diff --git a/.gitignore b/.gitignore index 9b188c6da..ae438ab55 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,8 @@ node_modules .phpunit.result.cache yarn-error.log modules/ppcp-button/assets/* -modules/ppcp-wc-gateway/assets/* +modules/ppcp-wc-gateway/assets/js +modules/ppcp-wc-gateway/assets/css *.zip .env auth.json diff --git a/changelog.txt b/changelog.txt index d6448106d..ed6ee457e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,20 @@ *** Changelog *** += 1.7.0 - TBD = +* Fix - DCC orders randomly failing #503 +* Fix - Multi-currency broke #481 +* Fix - Address information from PayPal shortcut flow not loaded #451 +* Enhancement - Improve onboarding flow, allow no card processing #443 +* Enhancement - Add Germany to supported ACDC countries #459 +* Enhancement - Add filters to allow ACDC for countries #437 +* Enhancement - Update 3D Secure #464 +* Enhancement - Extend event, error logging & order notes #456 +* Enhancement - Display API response errors in checkout page with user-friendly error message #457 +* Enhancement - Pass address details to credit card fields #479 +* Enhancement - Improve onboarding notice #465 +* Enhancement - Add transaction ID to WC order and order note when refund is received #473 +* Enhancement - Asset caching may cause bugs on upgrades #501 + = 1.6.5 - 2022-01-31 = * Fix - Allow guest users to purchase subscription products from checkout page #422 * Fix - Transaction ID missing for renewal order #424 diff --git a/composer.json b/composer.json index f92d4dbff..ed3c2d4a3 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,10 @@ "dhii/containers": "^0.1.0-alpha1", "psr/log": "^1.1", "ralouphie/getallheaders": "^3.0", - "wikimedia/composer-merge-plugin": "^1.4" + "wikimedia/composer-merge-plugin": "^1.4", + "wp-oop/wordpress-interface": "^0.1.0-alpha1", + "dhii/versions": "^0.1.0-alpha1", + "symfony/polyfill-php80": "^1.19" }, "require-dev": { "woocommerce/woocommerce-sniffs": "^0.1.0", diff --git a/composer.lock b/composer.lock index 1c8ca84eb..1ff2571e2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5ec79a51fc5a2f5576f38dd6e4e87b2d", + "content-hash": "b3ddb500dfb804b3800901e2ac30108a", "packages": [ { "name": "container-interop/service-provider", @@ -35,10 +35,6 @@ ], "description": "Promoting container interoperability through standard service providers", "homepage": "https://github.com/container-interop/service-provider", - "support": { - "issues": "https://github.com/container-interop/service-provider/issues", - "source": "https://github.com/container-interop/service-provider/tree/master" - }, "time": "2017-09-20T14:13:36+00:00" }, { @@ -148,6 +144,57 @@ ], "time": "2021-10-06T11:13:51+00:00" }, + { + "name": "dhii/human-readable-interface", + "version": "v0.2.0-alpha1", + "source": { + "type": "git", + "url": "https://github.com/Dhii/human-readable-interface.git", + "reference": "2b49d664f117faf72fb7af402ad21c0c27c62b6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dhii/human-readable-interface/zipball/2b49d664f117faf72fb7af402ad21c0c27c62b6b", + "reference": "2b49d664f117faf72fb7af402ad21c0c27c62b6b", + "shasum": "" + }, + "require": { + "php": "^7.1 | ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0 | ^7.0 | ^8.0 | ^9.0", + "slevomat/coding-standard": "^6.0", + "symfony/polyfill-php80": "^1.19", + "vimeo/psalm": "^3.11.7 | ^4.0" + }, + "suggest": { + "dhii/i18n-interface": "For internationalizing and translating human readable strings.", + "symfony/polyfill-php80": "To add Stringable interface" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "0.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dhii\\Util\\String\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dhii Team", + "email": "development@dhii.co" + } + ], + "description": "Interfaces for human readable string interoperation.", + "time": "2021-03-05T00:36:01+00:00" + }, { "name": "dhii/module-interface", "version": "v0.3.0-alpha2", @@ -194,12 +241,142 @@ } ], "description": "Interfaces for modules", - "support": { - "issues": "https://github.com/Dhii/module-interface/issues", - "source": "https://github.com/Dhii/module-interface/tree/v0.3.0-alpha2" - }, "time": "2021-08-23T08:23:01+00:00" }, + { + "name": "dhii/package-interface", + "version": "v0.1.0-alpha4", + "source": { + "type": "git", + "url": "https://github.com/Dhii/package-interface.git", + "reference": "bcc73f4285eead9b482dbb89662b723abf49298b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dhii/package-interface/zipball/bcc73f4285eead9b482dbb89662b723abf49298b", + "reference": "bcc73f4285eead9b482dbb89662b723abf49298b", + "shasum": "" + }, + "require": { + "dhii/validation-interface": "^0.3-alpha1", + "php": "^7.1 | ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0", + "slevomat/coding-standard": "^6.0", + "symfony/polyfill-php80": "^1.19", + "vimeo/psalm": "^4.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Dhii\\Package\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anton Ukhanev", + "email": "xedin.unknown@gmail.com" + } + ], + "description": "Interfaces for package-related interop", + "time": "2021-12-08T15:57:36+00:00" + }, + { + "name": "dhii/validation-interface", + "version": "v0.3.0-alpha3", + "source": { + "type": "git", + "url": "https://github.com/Dhii/validation-interface.git", + "reference": "0e73c7bf3d2421ceb79331c60a9bc1b1d5eb65a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dhii/validation-interface/zipball/0e73c7bf3d2421ceb79331c60a9bc1b1d5eb65a6", + "reference": "0e73c7bf3d2421ceb79331c60a9bc1b1d5eb65a6", + "shasum": "" + }, + "require": { + "php": "^7.1 | ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0", + "slevomat/coding-standard": "^6.0", + "symfony/polyfill-mbstring": "1.20", + "symfony/polyfill-php80": "^1.19", + "vimeo/psalm": "^3.11.7 | ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "0.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dhii\\Validation\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anton Ukhanev", + "email": "xedin.unknown@gmail.com" + } + ], + "description": "A base interface for validators", + "time": "2021-01-14T16:19:20+00:00" + }, + { + "name": "dhii/versions", + "version": "v0.1.0-alpha3", + "source": { + "type": "git", + "url": "https://github.com/Dhii/versions.git", + "reference": "120b22b248d0b46e41bac93bf3394516c9d55730" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dhii/versions/zipball/120b22b248d0b46e41bac93bf3394516c9d55730", + "reference": "120b22b248d0b46e41bac93bf3394516c9d55730", + "shasum": "" + }, + "require": { + "dhii/package-interface": "^0.1.0-alpha3", + "php": "^7.1 | ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0", + "slevomat/coding-standard": "^6.0", + "symfony/polyfill-php80": "^1.19", + "vimeo/psalm": "^4.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Dhii\\Versions\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anton Ukhanev", + "email": "xedin.unknown@gmail.com" + } + ], + "description": "Implementation for dealing with SemVer-compliant versions", + "time": "2021-12-08T16:54:50+00:00" + }, { "name": "psr/container", "version": "1.0.0", @@ -247,10 +424,6 @@ "container-interop", "psr" ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/master" - }, "time": "2017-02-14T16:28:37+00:00" }, { @@ -298,9 +471,6 @@ "psr", "psr-3" ], - "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" - }, "time": "2021-05-03T11:20:27+00:00" }, { @@ -341,12 +511,88 @@ } ], "description": "A polyfill for getallheaders.", - "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" - }, "time": "2019-03-08T08:55:37+00:00" }, + { + "name": "symfony/polyfill-php80", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-09-13T13:58:33+00:00" + }, { "name": "wikimedia/composer-merge-plugin", "version": "v1.4.1", @@ -395,21 +641,69 @@ ], "description": "Composer plugin to merge multiple composer.json files", "time": "2017-04-25T02:31:25+00:00" + }, + { + "name": "wp-oop/wordpress-interface", + "version": "v0.1.0-alpha2", + "source": { + "type": "git", + "url": "https://github.com/wp-oop/wordpress-interface.git", + "reference": "5e40acb49b76702f409bb5bcd2ea5459c9b946f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-oop/wordpress-interface/zipball/5e40acb49b76702f409bb5bcd2ea5459c9b946f5", + "reference": "5e40acb49b76702f409bb5bcd2ea5459c9b946f5", + "shasum": "" + }, + "require": { + "dhii/human-readable-interface": "^0.2.0-alpha1", + "dhii/package-interface": "^0.1-alpha3", + "php": "^7.1 | ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0", + "slevomat/coding-standard": "^6.0", + "vimeo/psalm": "^4.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-task/initial-interfaces": "0.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "WpOop\\WordPress\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anton Ukhanev", + "email": "xedin.unknown@gmail.com" + } + ], + "description": "Interfaces for interop within WordPress", + "time": "2021-04-30T09:37:37+00:00" } ], "packages-dev": [ { "name": "amphp/amp", - "version": "v2.6.1", + "version": "v2.6.2", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", - "reference": "c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae" + "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae", - "reference": "c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae", + "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", + "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", "shasum": "" }, "require": { @@ -431,13 +725,13 @@ } }, "autoload": { - "psr-4": { - "Amp\\": "lib" - }, "files": [ "lib/functions.php", "lib/Internal/functions.php" - ] + ], + "psr-4": { + "Amp\\": "lib" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -462,7 +756,7 @@ } ], "description": "A non-blocking concurrency framework for PHP applications.", - "homepage": "http://amphp.org/amp", + "homepage": "https://amphp.org/amp", "keywords": [ "async", "asynchronous", @@ -480,7 +774,7 @@ "type": "github" } ], - "time": "2021-09-23T18:43:08+00:00" + "time": "2022-02-20T17:52:18+00:00" }, { "name": "amphp/byte-stream", @@ -556,16 +850,16 @@ }, { "name": "antecedent/patchwork", - "version": "2.1.17", + "version": "2.1.21", "source": { "type": "git", "url": "https://github.com/antecedent/patchwork.git", - "reference": "df5aba175a44c2996ced4edf8ec9f9081b5348c0" + "reference": "25c1fa0cd9a6e6d0d13863d8df8f050b6733f16d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/antecedent/patchwork/zipball/df5aba175a44c2996ced4edf8ec9f9081b5348c0", - "reference": "df5aba175a44c2996ced4edf8ec9f9081b5348c0", + "url": "https://api.github.com/repos/antecedent/patchwork/zipball/25c1fa0cd9a6e6d0d13863d8df8f050b6733f16d", + "reference": "25c1fa0cd9a6e6d0d13863d8df8f050b6733f16d", "shasum": "" }, "require": { @@ -596,31 +890,31 @@ "runkit", "testing" ], - "time": "2021-10-21T14:22:43+00:00" + "time": "2022-02-07T07:28:34+00:00" }, { "name": "brain/monkey", - "version": "2.6.0", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/Brain-WP/BrainMonkey.git", - "reference": "7042140000b4b18034c0c0010d86274a00f25442" + "reference": "a31c84515bb0d49be9310f52ef1733980ea8ffbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Brain-WP/BrainMonkey/zipball/7042140000b4b18034c0c0010d86274a00f25442", - "reference": "7042140000b4b18034c0c0010d86274a00f25442", + "url": "https://api.github.com/repos/Brain-WP/BrainMonkey/zipball/a31c84515bb0d49be9310f52ef1733980ea8ffbb", + "reference": "a31c84515bb0d49be9310f52ef1733980ea8ffbb", "shasum": "" }, "require": { - "antecedent/patchwork": "^2.0", - "mockery/mockery": ">=0.9 <2", + "antecedent/patchwork": "^2.1.17", + "mockery/mockery": "^1.3.5 || ^1.4.4", "php": ">=5.6.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6 || ^0.7", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.1", "phpcompatibility/php-compatibility": "^9.3.0", - "phpunit/phpunit": "^5.7.9 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^5.7.26 || ^6.0 || ^7.0 || >=8.0 <8.5.12 || ^8.5.14 || ^9.0" }, "type": "library", "extra": { @@ -630,12 +924,12 @@ } }, "autoload": { - "psr-4": { - "Brain\\Monkey\\": "src/" - }, "files": [ "inc/api.php" - ] + ], + "psr-4": { + "Brain\\Monkey\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -662,20 +956,20 @@ "test", "testing" ], - "time": "2020-10-13T17:56:14+00:00" + "time": "2021-11-11T15:53:55+00:00" }, { "name": "composer/package-versions-deprecated", - "version": "1.11.99.4", + "version": "1.11.99.5", "source": { "type": "git", "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b174585d1fe49ceed21928a945138948cb394600" + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600", - "reference": "b174585d1fe49ceed21928a945138948cb394600", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", "shasum": "" }, "require": { @@ -731,27 +1025,94 @@ "type": "tidelift" } ], - "time": "2021-09-13T08:41:34+00:00" + "time": "2022-01-17T14:14:24+00:00" }, { - "name": "composer/semver", - "version": "3.2.6", + "name": "composer/pcre", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "83e511e247de329283478496f7a1e114c9517506" + "url": "https://github.com/composer/pcre.git", + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/83e511e247de329283478496f7a1e114c9517506", - "reference": "83e511e247de329283478496f7a1e114c9517506", + "url": "https://api.github.com/repos/composer/pcre/zipball/67a32d7d6f9f560b726ab25a061b38ff3a80c560", + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.54", + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-01-21T20:24:37+00:00" + }, + { + "name": "composer/semver", + "version": "3.2.9", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/a951f614bd64dcd26137bc9b7b2637ddcfc57649", + "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", @@ -807,29 +1168,31 @@ "type": "tidelift" } ], - "time": "2021-10-25T11:34:17+00:00" + "time": "2022-02-04T13:58:43+00:00" }, { "name": "composer/xdebug-handler", - "version": "2.0.2", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339" + "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/84674dd3a7575ba617f5a76d7e9e29a7d3891339", - "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", + "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", "shasum": "" }, "require": { + "composer/pcre": "^1", "php": "^5.3.2 || ^7.0 || ^8.0", "psr/log": "^1 || ^2 || ^3" }, "require-dev": { - "phpstan/phpstan": "^0.12.55", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" }, "type": "library", "autoload": { @@ -866,31 +1229,31 @@ "type": "tidelift" } ], - "time": "2021-07-31T17:03:58+00:00" + "time": "2022-01-04T17:06:45+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.1", + "version": "v0.7.2", "source": { "type": "git", "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "fe390591e0241955f22eb9ba327d137e501c771c" + "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/fe390591e0241955f22eb9ba327d137e501c771c", - "reference": "fe390591e0241955f22eb9ba327d137e501c771c", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", "shasum": "" }, "require": { "composer-plugin-api": "^1.0 || ^2.0", "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0" + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" }, "require-dev": { "composer/composer": "*", - "phpcompatibility/php-compatibility": "^9.0", - "sensiolabs/security-checker": "^4.1.0" + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.0" }, "type": "composer-plugin", "extra": { @@ -911,6 +1274,10 @@ "email": "franck.nijhof@dealerdirect.com", "homepage": "http://www.frenck.nl", "role": "Developer / IT Manager" + }, + { + "name": "Contributors", + "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", @@ -922,6 +1289,7 @@ "codesniffer", "composer", "installer", + "phpcbf", "phpcs", "plugin", "qa", @@ -932,7 +1300,7 @@ "stylecheck", "tests" ], - "time": "2020-12-07T18:04:37+00:00" + "time": "2022-02-04T12:51:07+00:00" }, { "name": "dnoegel/php-xdg-base-dir", @@ -1016,20 +1384,6 @@ "constructor", "instantiate" ], - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], "time": "2020-11-10T18:47:58+00:00" }, { @@ -1283,12 +1637,6 @@ "object", "object graph" ], - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], "time": "2020-11-13T09:40:50+00:00" }, { @@ -1339,16 +1687,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.0", + "version": "v4.13.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "50953a2691a922aa1769461637869a0a2faa3f53" + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", - "reference": "50953a2691a922aa1769461637869a0a2faa3f53", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", "shasum": "" }, "require": { @@ -1387,7 +1735,7 @@ "parser", "php" ], - "time": "2021-09-20T12:20:58+00:00" + "time": "2021-11-30T19:35:32+00:00" }, { "name": "openlss/lib-array2xml", @@ -1542,16 +1890,16 @@ }, { "name": "php-stubs/woocommerce-stubs", - "version": "v5.8.0", + "version": "v5.9.0", "source": { "type": "git", "url": "https://github.com/php-stubs/woocommerce-stubs.git", - "reference": "e3978c519fb1e51585e8c86b489b802aa0c64cee" + "reference": "a7204cfbb5fa90720773122cb68530087de5bc78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/woocommerce-stubs/zipball/e3978c519fb1e51585e8c86b489b802aa0c64cee", - "reference": "e3978c519fb1e51585e8c86b489b802aa0c64cee", + "url": "https://api.github.com/repos/php-stubs/woocommerce-stubs/zipball/a7204cfbb5fa90720773122cb68530087de5bc78", + "reference": "a7204cfbb5fa90720773122cb68530087de5bc78", "shasum": "" }, "require": { @@ -1578,28 +1926,31 @@ "woocommerce", "wordpress" ], - "time": "2021-10-15T14:13:09+00:00" + "time": "2021-11-05T10:02:27+00:00" }, { "name": "php-stubs/wordpress-stubs", - "version": "v5.8.1", + "version": "v5.9.0", "source": { "type": "git", "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "8b333464d3183bccde2fdbb814e3cae592434943" + "reference": "0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/8b333464d3183bccde2fdbb814e3cae592434943", - "reference": "8b333464d3183bccde2fdbb814e3cae592434943", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b", + "reference": "0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b", "shasum": "" }, "replace": { "giacocorsiglia/wordpress-stubs": "*" }, "require-dev": { - "giacocorsiglia/stubs-generator": "^0.5.0", - "php": "~7.1" + "nikic/php-parser": "< 4.12.0", + "php": "~7.3 || ~8.0", + "php-stubs/generator": "^0.8.0", + "phpdocumentor/reflection-docblock": "^5.3", + "phpstan/phpstan": "^1.2" }, "suggest": { "paragonie/sodium_compat": "Pure PHP implementation of libsodium", @@ -1618,7 +1969,7 @@ "static analysis", "wordpress" ], - "time": "2021-09-09T22:10:19+00:00" + "time": "2022-01-26T00:27:45+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -1732,16 +2083,16 @@ }, { "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.1.2", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "a792ab623069f0ce971b2417edef8d9632e32f75" + "reference": "d55de55f88697b9cdb94bccf04f14eb3b11cf308" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/a792ab623069f0ce971b2417edef8d9632e32f75", - "reference": "a792ab623069f0ce971b2417edef8d9632e32f75", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/d55de55f88697b9cdb94bccf04f14eb3b11cf308", + "reference": "d55de55f88697b9cdb94bccf04f14eb3b11cf308", "shasum": "" }, "require": { @@ -1778,7 +2129,7 @@ "standards", "wordpress" ], - "time": "2021-07-21T11:09:57+00:00" + "time": "2021-12-30T16:37:40+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -2056,16 +2407,16 @@ }, { "name": "phpunit/php-file-iterator", - "version": "2.0.4", + "version": "2.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "28af674ff175d0768a5a978e6de83f697d4a7f05" + "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/28af674ff175d0768a5a978e6de83f697d4a7f05", - "reference": "28af674ff175d0768a5a978e6de83f697d4a7f05", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", + "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", "shasum": "" }, "require": { @@ -2108,7 +2459,7 @@ "type": "github" } ], - "time": "2021-07-19T06:46:01+00:00" + "time": "2021-12-02T12:42:26+00:00" }, { "name": "phpunit/php-text-template", @@ -2198,12 +2549,6 @@ "keywords": [ "timer" ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "time": "2020-11-30T08:20:02+00:00" }, { @@ -2253,12 +2598,6 @@ "keywords": [ "tokenizer" ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "abandoned": true, "time": "2021-07-26T12:15:06+00:00" }, @@ -2389,12 +2728,6 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "time": "2020-11-30T08:15:22+00:00" }, { @@ -2459,12 +2792,6 @@ "compare", "equality" ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "time": "2020-11-30T08:04:30+00:00" }, { @@ -2521,12 +2848,6 @@ "unidiff", "unified diff" ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "time": "2020-11-30T07:59:04+00:00" }, { @@ -2580,26 +2901,20 @@ "environment", "hhvm" ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "time": "2020-11-30T07:53:42+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.3", + "version": "3.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" + "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", - "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", + "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", "shasum": "" }, "require": { @@ -2608,7 +2923,7 @@ }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -2659,7 +2974,7 @@ "type": "github" } ], - "time": "2020-11-30T07:47:53+00:00" + "time": "2021-11-11T13:51:24+00:00" }, { "name": "sebastian/global-state", @@ -2757,12 +3072,6 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "time": "2020-11-30T07:40:27+00:00" }, { @@ -2808,12 +3117,6 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "time": "2020-11-30T07:37:18+00:00" }, { @@ -2867,12 +3170,6 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "time": "2020-11-30T07:34:24+00:00" }, { @@ -2915,12 +3212,6 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "time": "2020-11-30T07:30:19+00:00" }, { @@ -2968,16 +3259,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.6.1", + "version": "3.6.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e" + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f268ca40d54617c6e06757f83f699775c9b3ff2e", - "reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", "shasum": "" }, "require": { @@ -3015,20 +3306,20 @@ "phpcs", "standards" ], - "time": "2021-10-11T04:00:11+00:00" + "time": "2021-12-12T21:44:58+00:00" }, { "name": "symfony/console", - "version": "v4.4.30", + "version": "v4.4.37", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a3f7189a0665ee33b50e9e228c46f50f5acbed22" + "reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a3f7189a0665ee33b50e9e228c46f50f5acbed22", - "reference": "a3f7189a0665ee33b50e9e228c46f50f5acbed22", + "url": "https://api.github.com/repos/symfony/console/zipball/0259f01dbf9d77badddbbf4c2abb681f24c9cac6", + "reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6", "shasum": "" }, "require": { @@ -3102,25 +3393,28 @@ "type": "tidelift" } ], - "time": "2021-08-25T19:27:26+00:00" + "time": "2022-01-26T16:15:26+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.23.0", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + "reference": "30885182c981ab175d4d034db0f6f469898070ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-ctype": "*" + }, "suggest": { "ext-ctype": "For best performance" }, @@ -3178,25 +3472,28 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2021-10-20T20:35:02+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.23.1", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-mbstring": "*" + }, "suggest": { "ext-mbstring": "For best performance" }, @@ -3211,12 +3508,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3255,20 +3552,20 @@ "type": "tidelift" } ], - "time": "2021-05-27T12:26:48+00:00" + "time": "2021-11-30T18:21:41+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.23.0", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010" + "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010", - "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", + "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", "shasum": "" }, "require": { @@ -3285,12 +3582,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -3331,100 +3628,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.23.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-07-28T13:41:28+00:00" + "time": "2021-06-05T21:20:04+00:00" }, { "name": "symfony/service-contracts", - "version": "v1.1.9", + "version": "v1.1.11", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26" + "reference": "633df678bec3452e04a7b0337c9bcfe7354124b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b776d18b303a39f56c63747bcb977ad4b27aca26", - "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/633df678bec3452e04a7b0337c9bcfe7354124b3", + "reference": "633df678bec3452e04a7b0337c9bcfe7354124b3", "shasum": "" }, "require": { @@ -3437,7 +3654,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-main": "1.1-dev" }, "thanks": { "name": "symfony/contracts", @@ -3487,7 +3704,7 @@ "type": "tidelift" } ], - "time": "2020-07-06T13:19:58+00:00" + "time": "2021-11-04T13:32:43+00:00" }, { "name": "theseer/tokenizer", @@ -3531,16 +3748,16 @@ }, { "name": "vimeo/psalm", - "version": "4.11.2", + "version": "4.21.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "6fba5eb554f9507b72932f9c75533d8af593688d" + "reference": "d8bec4c7aaee111a532daec32fb09de5687053d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/6fba5eb554f9507b72932f9c75533d8af593688d", - "reference": "6fba5eb554f9507b72932f9c75533d8af593688d", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/d8bec4c7aaee111a532daec32fb09de5687053d1", + "reference": "d8bec4c7aaee111a532daec32fb09de5687053d1", "shasum": "" }, "require": { @@ -3548,7 +3765,7 @@ "amphp/byte-stream": "^1.5", "composer/package-versions-deprecated": "^1.8.0", "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^1.1 || ^2.0", + "composer/xdebug-handler": "^1.1 || ^2.0 || ^3.0", "dnoegel/php-xdg-base-dir": "^0.1.1", "ext-ctype": "*", "ext-dom": "*", @@ -3564,7 +3781,7 @@ "openlss/lib-array2xml": "^1.0", "php": "^7.1|^8", "sebastian/diff": "^3.0 || ^4.0", - "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0", + "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0 || ^6.0", "webmozart/path-util": "^2.3" }, "provide": { @@ -3582,11 +3799,12 @@ "psalm/plugin-phpunit": "^0.16", "slevomat/coding-standard": "^7.0", "squizlabs/php_codesniffer": "^3.5", - "symfony/process": "^4.3 || ^5.0", + "symfony/process": "^4.3 || ^5.0 || ^6.0", "weirdan/prophecy-shim": "^1.0 || ^2.0" }, "suggest": { - "ext-igbinary": "^2.0.5" + "ext-curl": "In order to send data to shepherd", + "ext-igbinary": "^2.0.5 is required, used to serialize caching data" }, "bin": [ "psalm", @@ -3605,13 +3823,13 @@ } }, "autoload": { - "psr-4": { - "Psalm\\": "src/Psalm/" - }, "files": [ "src/functions.php", "src/spl_object_id.php" - ] + ], + "psr-4": { + "Psalm\\": "src/Psalm/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3628,7 +3846,7 @@ "inspection", "php" ], - "time": "2021-10-26T17:28:17+00:00" + "time": "2022-02-18T04:34:15+00:00" }, { "name": "webmozart/assert", @@ -3723,20 +3941,21 @@ } ], "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "abandoned": "symfony/filesystem", "time": "2015-12-17T08:42:14+00:00" }, { "name": "woocommerce/woocommerce-sniffs", - "version": "0.1.1", + "version": "0.1.2", "source": { "type": "git", "url": "https://github.com/woocommerce/woocommerce-sniffs.git", - "reference": "eb604d751b61c42f31ff1aa24113c7c0de438553" + "reference": "5566270d280a300bc24bd0cb055a8b9325afdd6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/eb604d751b61c42f31ff1aa24113c7c0de438553", - "reference": "eb604d751b61c42f31ff1aa24113c7c0de438553", + "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/5566270d280a300bc24bd0cb055a8b9325afdd6b", + "reference": "5566270d280a300bc24bd0cb055a8b9325afdd6b", "shasum": "" }, "require": { @@ -3763,7 +3982,7 @@ "woocommerce", "wordpress" ], - "time": "2021-07-29T17:25:16+00:00" + "time": "2022-01-21T20:13:23+00:00" }, { "name": "wp-coding-standards/wpcs", diff --git a/modules/ppcp-admin-notices/src/Repository/Repository.php b/modules/ppcp-admin-notices/src/Repository/Repository.php index 066ed0ea8..e13a5dd6c 100644 --- a/modules/ppcp-admin-notices/src/Repository/Repository.php +++ b/modules/ppcp-admin-notices/src/Repository/Repository.php @@ -25,6 +25,9 @@ class Repository implements RepositoryInterface { */ public function current_message(): array { return array_filter( + /** + * Returns the list of admin messages. + */ (array) apply_filters( self::NOTICES_FILTER, array() diff --git a/modules/ppcp-api-client/services.php b/modules/ppcp-api-client/services.php index 32184c6a3..e4ce7ebb3 100644 --- a/modules/ppcp-api-client/services.php +++ b/modules/ppcp-api-client/services.php @@ -127,7 +127,6 @@ return array( return new PartnerReferrals( $container->get( 'api.host' ), $container->get( 'api.bearer' ), - $container->get( 'api.repository.partner-referrals-data' ), $container->get( 'woocommerce.logger.woocommerce' ) ); }, @@ -209,9 +208,8 @@ return array( }, 'api.repository.partner-referrals-data' => static function ( ContainerInterface $container ) : PartnerReferralsData { - $merchant_email = $container->get( 'api.merchant_email' ); $dcc_applies = $container->get( 'api.helpers.dccapplies' ); - return new PartnerReferralsData( $merchant_email, $dcc_applies ); + return new PartnerReferralsData( $dcc_applies ); }, 'api.repository.cart' => static function ( ContainerInterface $container ): CartRepository { $factory = $container->get( 'api.factory.purchase-unit' ); @@ -327,12 +325,16 @@ return array( }, 'api.shop.currency' => static function ( ContainerInterface $container ) : string { - // We use option instead of get_woocommerce_currency - // because it will not be overridden by currency switching plugins. + $currency = get_woocommerce_currency(); + if ( $currency ) { + return $currency; + } + $currency = get_option( 'woocommerce_currency' ); if ( ! $currency ) { return 'NO_CURRENCY'; // Unlikely to happen. } + return $currency; }, 'api.shop.country' => static function ( ContainerInterface $container ) : string { @@ -393,141 +395,147 @@ return array( * The matrix which countries and currency combinations can be used for DCC. */ 'api.dcc-supported-country-currency-matrix' => static function ( ContainerInterface $container ) : array { - return array( - 'AU' => array( - 'AUD', - 'CAD', - 'CHF', - 'CZK', - 'DKK', - 'EUR', - 'GBP', - 'HKD', - 'HUF', - 'JPY', - 'NOK', - 'NZD', - 'PLN', - 'SEK', - 'SGD', - 'USD', - ), - 'DE' => array( - 'AUD', - 'CAD', - 'CHF', - 'CZK', - 'DKK', - 'EUR', - 'GBP', - 'HKD', - 'HUF', - 'JPY', - 'NOK', - 'NZD', - 'PLN', - 'SEK', - 'SGD', - 'USD', - ), - 'ES' => array( - 'AUD', - 'CAD', - 'CHF', - 'CZK', - 'DKK', - 'EUR', - 'GBP', - 'HKD', - 'HUF', - 'JPY', - 'NOK', - 'NZD', - 'PLN', - 'SEK', - 'SGD', - 'USD', - ), - 'FR' => array( - 'AUD', - 'CAD', - 'CHF', - 'CZK', - 'DKK', - 'EUR', - 'GBP', - 'HKD', - 'HUF', - 'JPY', - 'NOK', - 'NZD', - 'PLN', - 'SEK', - 'SGD', - 'USD', - ), - 'GB' => array( - 'AUD', - 'CAD', - 'CHF', - 'CZK', - 'DKK', - 'EUR', - 'GBP', - 'HKD', - 'HUF', - 'JPY', - 'NOK', - 'NZD', - 'PLN', - 'SEK', - 'SGD', - 'USD', - ), - 'IT' => array( - 'AUD', - 'CAD', - 'CHF', - 'CZK', - 'DKK', - 'EUR', - 'GBP', - 'HKD', - 'HUF', - 'JPY', - 'NOK', - 'NZD', - 'PLN', - 'SEK', - 'SGD', - 'USD', - ), - 'US' => array( - 'AUD', - 'CAD', - 'EUR', - 'GBP', - 'JPY', - 'USD', - ), - 'CA' => array( - 'AUD', - 'CAD', - 'CHF', - 'CZK', - 'DKK', - 'EUR', - 'GBP', - 'HKD', - 'HUF', - 'JPY', - 'NOK', - 'NZD', - 'PLN', - 'SEK', - 'SGD', - 'USD', - ), + /** + * Returns which countries and currency combinations can be used for DCC. + */ + return apply_filters( + 'woocommerce_paypal_payments_supported_country_currency_matrix', + array( + 'AU' => array( + 'AUD', + 'CAD', + 'CHF', + 'CZK', + 'DKK', + 'EUR', + 'GBP', + 'HKD', + 'HUF', + 'JPY', + 'NOK', + 'NZD', + 'PLN', + 'SEK', + 'SGD', + 'USD', + ), + 'DE' => array( + 'AUD', + 'CAD', + 'CHF', + 'CZK', + 'DKK', + 'EUR', + 'GBP', + 'HKD', + 'HUF', + 'JPY', + 'NOK', + 'NZD', + 'PLN', + 'SEK', + 'SGD', + 'USD', + ), + 'ES' => array( + 'AUD', + 'CAD', + 'CHF', + 'CZK', + 'DKK', + 'EUR', + 'GBP', + 'HKD', + 'HUF', + 'JPY', + 'NOK', + 'NZD', + 'PLN', + 'SEK', + 'SGD', + 'USD', + ), + 'FR' => array( + 'AUD', + 'CAD', + 'CHF', + 'CZK', + 'DKK', + 'EUR', + 'GBP', + 'HKD', + 'HUF', + 'JPY', + 'NOK', + 'NZD', + 'PLN', + 'SEK', + 'SGD', + 'USD', + ), + 'GB' => array( + 'AUD', + 'CAD', + 'CHF', + 'CZK', + 'DKK', + 'EUR', + 'GBP', + 'HKD', + 'HUF', + 'JPY', + 'NOK', + 'NZD', + 'PLN', + 'SEK', + 'SGD', + 'USD', + ), + 'IT' => array( + 'AUD', + 'CAD', + 'CHF', + 'CZK', + 'DKK', + 'EUR', + 'GBP', + 'HKD', + 'HUF', + 'JPY', + 'NOK', + 'NZD', + 'PLN', + 'SEK', + 'SGD', + 'USD', + ), + 'US' => array( + 'AUD', + 'CAD', + 'EUR', + 'GBP', + 'JPY', + 'USD', + ), + 'CA' => array( + 'AUD', + 'CAD', + 'CHF', + 'CZK', + 'DKK', + 'EUR', + 'GBP', + 'HKD', + 'HUF', + 'JPY', + 'NOK', + 'NZD', + 'PLN', + 'SEK', + 'SGD', + 'USD', + ), + ) ); }, @@ -535,49 +543,55 @@ return array( * Which countries support which credit cards. Empty credit card arrays mean no restriction on currency. */ 'api.dcc-supported-country-card-matrix' => static function ( ContainerInterface $container ) : array { - return array( - 'AU' => array( - 'mastercard' => array(), - 'visa' => array(), - 'amex' => array( 'AUD' ), - ), - 'DE' => array( - 'mastercard' => array(), - 'visa' => array(), - 'amex' => array( 'EUR' ), - ), - 'ES' => array( - 'mastercard' => array(), - 'visa' => array(), - 'amex' => array( 'EUR' ), - ), - 'FR' => array( - 'mastercard' => array(), - 'visa' => array(), - 'amex' => array( 'EUR' ), - ), - 'GB' => array( - 'mastercard' => array(), - 'visa' => array(), - 'amex' => array( 'GBP', 'USD' ), - ), - 'IT' => array( - 'mastercard' => array(), - 'visa' => array(), - 'amex' => array( 'EUR' ), - ), - 'US' => array( - 'mastercard' => array(), - 'visa' => array(), - 'amex' => array( 'USD' ), - 'discover' => array( 'USD' ), - ), - 'CA' => array( - 'mastercard' => array(), - 'visa' => array(), - 'amex' => array( 'CAD' ), - 'jcb' => array( 'CAD' ), - ), + /** + * Returns which countries support which credit cards. Empty credit card arrays mean no restriction on currency. + */ + return apply_filters( + 'woocommerce_paypal_payments_supported_country_card_matrix', + array( + 'AU' => array( + 'mastercard' => array(), + 'visa' => array(), + 'amex' => array( 'AUD' ), + ), + 'DE' => array( + 'mastercard' => array(), + 'visa' => array(), + 'amex' => array( 'EUR' ), + ), + 'ES' => array( + 'mastercard' => array(), + 'visa' => array(), + 'amex' => array( 'EUR' ), + ), + 'FR' => array( + 'mastercard' => array(), + 'visa' => array(), + 'amex' => array( 'EUR' ), + ), + 'GB' => array( + 'mastercard' => array(), + 'visa' => array(), + 'amex' => array( 'GBP', 'USD' ), + ), + 'IT' => array( + 'mastercard' => array(), + 'visa' => array(), + 'amex' => array( 'EUR' ), + ), + 'US' => array( + 'mastercard' => array(), + 'visa' => array(), + 'amex' => array( 'USD' ), + 'discover' => array( 'USD' ), + ), + 'CA' => array( + 'mastercard' => array(), + 'visa' => array(), + 'amex' => array( 'CAD' ), + 'jcb' => array( 'CAD' ), + ), + ) ); }, diff --git a/modules/ppcp-api-client/src/Endpoint/PartnerReferrals.php b/modules/ppcp-api-client/src/Endpoint/PartnerReferrals.php index 38526927f..0f188f025 100644 --- a/modules/ppcp-api-client/src/Endpoint/PartnerReferrals.php +++ b/modules/ppcp-api-client/src/Endpoint/PartnerReferrals.php @@ -12,7 +12,6 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; -use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData; use Psr\Log\LoggerInterface; /** @@ -36,13 +35,6 @@ class PartnerReferrals { */ private $bearer; - /** - * The PartnerReferralsData. - * - * @var PartnerReferralsData - */ - private $data; - /** * The logger. * @@ -53,32 +45,29 @@ class PartnerReferrals { /** * PartnerReferrals constructor. * - * @param string $host The host. - * @param Bearer $bearer The bearer. - * @param PartnerReferralsData $data The partner referrals data. - * @param LoggerInterface $logger The logger. + * @param string $host The host. + * @param Bearer $bearer The bearer. + * @param LoggerInterface $logger The logger. */ public function __construct( string $host, Bearer $bearer, - PartnerReferralsData $data, LoggerInterface $logger ) { $this->host = $host; $this->bearer = $bearer; - $this->data = $data; $this->logger = $logger; } /** * Fetch the signup link. * + * @param array $data The partner referrals data. * @return string * @throws RuntimeException If the request fails. */ - public function signup_link(): string { - $data = $this->data->data(); + public function signup_link( array $data ): string { $bearer = $this->bearer->bearer(); $args = array( 'method' => 'POST', diff --git a/modules/ppcp-api-client/src/Entity/PaymentToken.php b/modules/ppcp-api-client/src/Entity/PaymentToken.php index ca919dc2f..686813817 100644 --- a/modules/ppcp-api-client/src/Entity/PaymentToken.php +++ b/modules/ppcp-api-client/src/Entity/PaymentToken.php @@ -105,6 +105,9 @@ class PaymentToken { * @return array */ public static function get_valid_types() { + /** + * Returns a list of valid payment token types. + */ return apply_filters( 'woocommerce_paypal_payments_valid_payment_token_types', array( diff --git a/modules/ppcp-api-client/src/Factory/PayerFactory.php b/modules/ppcp-api-client/src/Factory/PayerFactory.php index 70d33dee3..6bec8fe80 100644 --- a/modules/ppcp-api-client/src/Factory/PayerFactory.php +++ b/modules/ppcp-api-client/src/Factory/PayerFactory.php @@ -55,10 +55,12 @@ class PayerFactory { $national_number = preg_replace( '/[^0-9]/', '', $national_number ); $national_number = substr( $national_number, 0, 14 ); - $phone = new PhoneWithType( - 'HOME', - new Phone( $national_number ) - ); + if ( $national_number ) { + $phone = new PhoneWithType( + 'HOME', + new Phone( $national_number ) + ); + } } return new Payer( new PayerName( @@ -91,10 +93,12 @@ class PayerFactory { $national_number = preg_replace( '/[^0-9]/', '', $national_number ); $national_number = substr( $national_number, 0, 14 ); - $phone = new PhoneWithType( - 'HOME', - new Phone( $national_number ) - ); + if ( $national_number ) { + $phone = new PhoneWithType( + 'HOME', + new Phone( $national_number ) + ); + } } return new Payer( new PayerName( @@ -176,10 +180,12 @@ class PayerFactory { if ( null !== $national_number ) { $national_number = substr( $national_number, 0, 14 ); - $phone = new PhoneWithType( - 'HOME', - new Phone( $national_number ) - ); + if ( $national_number ) { + $phone = new PhoneWithType( + 'HOME', + new Phone( $national_number ) + ); + } } } diff --git a/modules/ppcp-api-client/src/Factory/PurchaseUnitFactory.php b/modules/ppcp-api-client/src/Factory/PurchaseUnitFactory.php index c018d9917..37c371fb0 100644 --- a/modules/ppcp-api-client/src/Factory/PurchaseUnitFactory.php +++ b/modules/ppcp-api-client/src/Factory/PurchaseUnitFactory.php @@ -134,6 +134,9 @@ class PurchaseUnitFactory { $invoice_id, $soft_descriptor ); + /** + * Returns PurchaseUnit for the WC order. + */ return apply_filters( 'woocommerce_paypal_payments_purchase_unit_from_wc_order', $purchase_unit, diff --git a/modules/ppcp-api-client/src/Repository/ApplicationContextRepository.php b/modules/ppcp-api-client/src/Repository/ApplicationContextRepository.php index bfc28b25a..f6c87c804 100644 --- a/modules/ppcp-api-client/src/Repository/ApplicationContextRepository.php +++ b/modules/ppcp-api-client/src/Repository/ApplicationContextRepository.php @@ -74,7 +74,10 @@ class ApplicationContextRepository { $parts = explode( '-', $locale ); if ( count( $parts ) === 3 ) { - return substr( $locale, 0, strrpos( $locale, '-' ) ); + $ret = substr( $locale, 0, strrpos( $locale, '-' ) ); + if ( false !== $ret ) { + return $ret; + } } return 'en'; diff --git a/modules/ppcp-api-client/src/Repository/CustomerRepository.php b/modules/ppcp-api-client/src/Repository/CustomerRepository.php index 93134624e..99063b7e3 100644 --- a/modules/ppcp-api-client/src/Repository/CustomerRepository.php +++ b/modules/ppcp-api-client/src/Repository/CustomerRepository.php @@ -45,6 +45,8 @@ class CustomerRepository { } $unique_id = substr( $this->prefix . strrev( uniqid() ), 0, self::CLIENT_ID_MAX_LENGTH ); + assert( is_string( $unique_id ) ); + WC()->session->set( 'ppcp_guest_customer_id', $unique_id ); return $unique_id; diff --git a/modules/ppcp-api-client/src/Repository/PartnerReferralsData.php b/modules/ppcp-api-client/src/Repository/PartnerReferralsData.php index d893e9c91..e2a13c949 100644 --- a/modules/ppcp-api-client/src/Repository/PartnerReferralsData.php +++ b/modules/ppcp-api-client/src/Repository/PartnerReferralsData.php @@ -15,14 +15,6 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies; * Class PartnerReferralsData */ class PartnerReferralsData { - - /** - * The merchant email. - * - * @var string - */ - private $merchant_email; - /** * The DCC Applies Helper object. * @@ -30,19 +22,39 @@ class PartnerReferralsData { */ private $dcc_applies; + /** + * The list of products ('PPCP', 'EXPRESS_CHECKOUT'). + * + * @var string[] + */ + private $products; + /** * PartnerReferralsData constructor. * - * @param string $merchant_email The email of the merchant. * @param DccApplies $dcc_applies The DCC Applies helper. */ public function __construct( - string $merchant_email, DccApplies $dcc_applies ) { + $this->dcc_applies = $dcc_applies; + $this->products = array( + $this->dcc_applies->for_country_currency() ? 'PPCP' : 'EXPRESS_CHECKOUT', + ); + } - $this->merchant_email = $merchant_email; - $this->dcc_applies = $dcc_applies; + /** + * Returns a new copy of this object with the given value set. + * + * @param string[] $products The list of products ('PPCP', 'EXPRESS_CHECKOUT'). + * @return static + */ + public function with_products( array $products ): self { + $obj = clone $this; + + $obj->products = $products; + + return $obj; } /** @@ -60,33 +72,26 @@ class PartnerReferralsData { * @return array */ public function data(): array { - $data = $this->default_data(); - return $data; - } - - /** - * Returns the default data. - * - * @return array - */ - private function default_data(): array { - return array( 'partner_config_override' => array( 'partner_logo_url' => 'https://connect.woocommerce.com/images/woocommerce_logo.png', + /** + * Returns the URL which will be opened at the end of onboarding. + */ 'return_url' => apply_filters( 'woocommerce_paypal_payments_partner_config_override_return_url', admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' ) ), + /** + * Returns the description of the URL which will be opened at the end of onboarding. + */ 'return_url_description' => apply_filters( 'woocommerce_paypal_payments_partner_config_override_return_url_description', __( 'Return to your shop.', 'woocommerce-paypal-payments' ) ), 'show_add_credit_card' => true, ), - 'products' => array( - $this->dcc_applies->for_country_currency() ? 'PPCP' : 'EXPRESS_CHECKOUT', - ), + 'products' => $this->products, 'legal_consents' => array( array( 'type' => 'SHARE_DATA_CONSENT', diff --git a/modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js b/modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js index 559803b3c..a4eb8f146 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js @@ -9,7 +9,6 @@ class CreditCardRenderer { this.cardValid = false; this.formValid = false; this.currentHostedFieldsInstance = null; - this.formSubmissionSubscribed = false; } render(wrapper, contextConfig) { @@ -122,7 +121,7 @@ class CreditCardRenderer { }); - if (!this.formSubmissionSubscribed) { + if (document.querySelector(wrapper).getAttribute('data-ppcp-subscribed') !== true) { document.querySelector(wrapper + ' button').addEventListener( 'click', event => { @@ -130,7 +129,8 @@ class CreditCardRenderer { this._submit(contextConfig); } ); - this.formSubmissionSubscribed = true; + + document.querySelector(wrapper).setAttribute('data-ppcp-subscribed', true); } }); @@ -143,7 +143,7 @@ class CreditCardRenderer { } disableFields() { - if( this.currentHostedFieldsInstance) { + if (this.currentHostedFieldsInstance) { this.currentHostedFieldsInstance.setAttribute({ field: 'number', attribute: 'disabled' @@ -160,7 +160,7 @@ class CreditCardRenderer { } enableFields() { - if( this.currentHostedFieldsInstance) { + if (this.currentHostedFieldsInstance) { this.currentHostedFieldsInstance.removeAttribute({ field: 'number', attribute: 'disabled' diff --git a/modules/ppcp-button/services.php b/modules/ppcp-button/services.php index fba90a1c8..9cec5b302 100644 --- a/modules/ppcp-button/services.php +++ b/modules/ppcp-button/services.php @@ -52,7 +52,7 @@ return array( * * @var State $state */ - if ( $state->current_state() <= State::STATE_PROGRESSIVE ) { + if ( $state->current_state() !== State::STATE_ONBOARDED ) { return new DisabledSmartButton(); } $settings = $container->get( 'wcgateway.settings' ); @@ -73,6 +73,7 @@ return array( $currency = $container->get( 'api.shop.currency' ); return new SmartButton( $container->get( 'button.url' ), + $container->get( 'ppcp.asset-version' ), $container->get( 'session.handler' ), $settings, $payer_factory, diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index 667560dbc..08e22815b 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -44,6 +44,13 @@ class SmartButton implements SmartButtonInterface { */ private $module_url; + /** + * The assets version. + * + * @var string + */ + private $version; + /** * The Session Handler. * @@ -125,6 +132,7 @@ class SmartButton implements SmartButtonInterface { * SmartButton constructor. * * @param string $module_url The URL to the module. + * @param string $version The assets version. * @param SessionHandler $session_handler The Session Handler. * @param Settings $settings The Settings. * @param PayerFactory $payer_factory The Payer factory. @@ -140,6 +148,7 @@ class SmartButton implements SmartButtonInterface { */ public function __construct( string $module_url, + string $version, SessionHandler $session_handler, Settings $settings, PayerFactory $payer_factory, @@ -155,6 +164,7 @@ class SmartButton implements SmartButtonInterface { ) { $this->module_url = $module_url; + $this->version = $version; $this->session_handler = $session_handler; $this->settings = $settings; $this->payer_factory = $payer_factory; @@ -406,7 +416,7 @@ class SmartButton implements SmartButtonInterface { 'ppcp-hosted-fields', untrailingslashit( $this->module_url ) . '/assets/css/hosted-fields.css', array(), - 1 + $this->version ); } if ( $load_script ) { @@ -414,7 +424,7 @@ class SmartButton implements SmartButtonInterface { 'ppcp-smart-button', untrailingslashit( $this->module_url ) . '/assets/js/button.js', array( 'jquery' ), - '1.3.2', + $this->version, true ); @@ -1012,38 +1022,50 @@ class SmartButton implements SmartButtonInterface { } /** - * Return action name PayPal buttons will be rendered at on checkout page. + * Returns the action name that PayPal button will use for rendering on the checkout page. * * @return string Action name. */ private function checkout_button_renderer_hook(): string { + /** + * The filter returning the action name that PayPal button will use for rendering on the checkout page. + */ return (string) apply_filters( 'woocommerce_paypal_payments_checkout_button_renderer_hook', 'woocommerce_review_order_after_payment' ); } /** - * Return action name PayPal DCC button will be rendered at on checkout page. + * Returns the action name that PayPal DCC button will use for rendering on the checkout page. * * @return string */ private function checkout_dcc_button_renderer_hook(): string { + /** + * The filter returning the action name that PayPal DCC button will use for rendering on the checkout page. + */ return (string) apply_filters( 'woocommerce_paypal_payments_checkout_dcc_renderer_hook', 'woocommerce_review_order_after_submit' ); } /** - * Return action name PayPal button and Pay Later message will be rendered at on pay-order page. + * Returns the action name that PayPal button and Pay Later message will use for rendering on the pay-order page. * * @return string */ private function pay_order_renderer_hook(): string { + /** + * The filter returning the action name that PayPal button and Pay Later message will use for rendering on the pay-order page. + */ return (string) apply_filters( 'woocommerce_paypal_payments_pay_order_dcc_renderer_hook', 'woocommerce_pay_order_after_submit' ); } /** - * Return action name PayPal button will be rendered next to Proceed to checkout button (normally displayed in cart). + * Returns action name that PayPal button will use for rendering next to Proceed to checkout button (normally displayed in cart). * * @return string */ private function proceed_to_checkout_button_renderer_hook(): string { + /** + * The filter returning the action name that PayPal button will use for rendering next to Proceed to checkout button (normally displayed in cart). + */ return (string) apply_filters( 'woocommerce_paypal_payments_proceed_to_checkout_button_renderer_hook', 'woocommerce_proceed_to_checkout' @@ -1051,11 +1073,14 @@ class SmartButton implements SmartButtonInterface { } /** - * Return action name PayPal button will be rendered in the WC mini cart. + * Returns the action name that PayPal button will use for rendering in the WC mini cart. * * @return string */ private function mini_cart_button_renderer_hook(): string { + /** + * The filter returning the action name that PayPal button will use for rendering in the WC mini cart. + */ return (string) apply_filters( 'woocommerce_paypal_payments_mini_cart_button_renderer_hook', 'woocommerce_widget_shopping_cart_after_buttons' @@ -1063,11 +1088,14 @@ class SmartButton implements SmartButtonInterface { } /** - * Return action name PayPal button and Pay Later message will be rendered at on the single product page. + * Returns the action name that PayPal button and Pay Later message will use for rendering on the single product page. * * @return string */ private function single_product_renderer_hook(): string { + /** + * The filter returning the action name that PayPal button and Pay Later message will use for rendering on the single product page. + */ return (string) apply_filters( 'woocommerce_paypal_payments_single_product_renderer_hook', 'woocommerce_single_product_summary' ); } } diff --git a/modules/ppcp-compat/src/PPEC/PPECHelper.php b/modules/ppcp-compat/src/PPEC/PPECHelper.php index 09fca3c19..71e16e544 100644 --- a/modules/ppcp-compat/src/PPEC/PPECHelper.php +++ b/modules/ppcp-compat/src/PPEC/PPECHelper.php @@ -89,6 +89,9 @@ class PPECHelper { * @return bool */ public static function use_ppec_compat_layer_for_subscriptions() { + /** + * The filter returning whether the compatibility layer for PPEC Subscriptions should be initialized. + */ return ( ! self::is_gateway_available() ) && self::site_has_ppec_subscriptions() && apply_filters( 'woocommerce_paypal_payments_process_legacy_subscriptions', true ); } diff --git a/modules/ppcp-onboarding/assets/css/onboarding.css b/modules/ppcp-onboarding/assets/css/onboarding.css index affc68415..084b96a22 100644 --- a/modules/ppcp-onboarding/assets/css/onboarding.css +++ b/modules/ppcp-onboarding/assets/css/onboarding.css @@ -2,41 +2,28 @@ display: none; } -#field-merchant_email_production, -#field-ppcp_disconnect_sandbox, -#field-ppcp_disconnect_production, -#field-merchant_id_production, -#field-client_id_production, -#field-client_secret_production, -#field-merchant_email_sandbox, -#field-merchant_id_sandbox, -#field-client_id_sandbox, -#field-client_secret_sandbox{ +.ppcp-onboarded .ppcp-onboarding-element:not(.ppcp-always-shown-element) { display: none; } -#field-merchant_email_production.show, -#field-ppcp_disconnect_sandbox.show, -#field-ppcp_disconnect_production.show, -#field-merchant_id_production.show, -#field-client_id_production.show, -#field-client_secret_production.show, -#field-merchant_email_sandbox.show, -#field-merchant_id_sandbox.show, -#field-client_id_sandbox.show, -#field-client_secret_sandbox.show { + +.ppcp-onboarding .ppcp-settings-field:not(.ppcp-onboarding-element):not(.ppcp-always-shown-element) { + display: none; +} + +.ppcp-settings-field.hide { + display: none; +} + +.ppcp-settings-field.show { display: table-row; } -#field-toggle_manual_input span.hide, -#field-toggle_manual_input.show span.show{ - display: none; -} -#field-toggle_manual_input.show span.hide { - display: unset; +label.error { + color: red; + font-weight: bold; } -#field-production_toggle_manual_input button, -#field-sandbox_toggle_manual_input button { +#field-toggle_manual_input button { color: #0073aa; transition-property: border, background, color; transition-duration: .05s; @@ -49,39 +36,8 @@ padding: 0; } -#field-sandbox_toggle_manual_input.onboarded, -#field-production_toggle_manual_input.onboarded { - display: none; -} - - -#field-ppcp_disconnect_sandbox.onboarded, -#field-ppcp_disconnect_production.onboarded, -#field-merchant_email_sandbox.onboarded, -#field-merchant_id_sandbox.onboarded, -#field-client_id_sandbox.onboarded, -#field-client_secret_sandbox.onboarded, -#field-merchant_email_production.onboarded, -#field-merchant_id_production.onboarded, -#field-client_id_production.onboarded, -#field-client_secret_production.onboarded { - display:table-row; -} -#field-ppcp_disconnect_sandbox.onboarded.hide, -#field-ppcp_disconnect_production.onboarded.hide, -#field-merchant_email_sandbox.onboarded.hide, -#field-merchant_id_sandbox.onboarded.hide, -#field-client_id_sandbox.onboarded.hide, -#field-client_secret_sandbox.onboarded.hide, -#field-merchant_email_production.onboarded.hide, -#field-merchant_id_production.onboarded.hide, -#field-client_id_production.onboarded.hide, -#field-client_secret_production.onboarded.hide { - display:none; -} - /* Probably not the best location for this but will do until there's a general purpose settings CSS file. */ -.ppcp-settings-field-heading td, .ppcp-settings-field-heading th { +.ppcp-settings-field-heading td, .ppcp-settings-field-heading th, .ppcp-settings-no-title-col td { padding-left: 0; } @@ -92,3 +48,83 @@ .input-text[pattern]:invalid { border: red solid 2px; } + +ul.ppcp-onboarding-options, ul.ppcp-onboarding-options-sublist { + list-style: none; +} + +ul.ppcp-onboarding-options-sublist { + margin-left: 15px; +} + +.ppcp-muted-text { + opacity: 0.6; + font-size: 85%; +} + +#field-ppcp_onboarading_header > td, #field-ppcp_onboarading_options > td { + padding: 0; +} + +.ppcp-onboarding-header, .ppcp-onboarding-cards-options { + display: flex; + width: 1200px; +} + +.ppcp-onboarding-header-left, .ppcp-onboarding-header-right { + flex: 50%; +} + +.ppcp-onboarding-header-right { + text-align: right; +} + +.ppcp-onboarding-header h2 { + margin-top: 0; +} + +.ppcp-onboarding-header-left img { + height: 60px; +} + +.ppcp-onboarding-header-cards img, .ppcp-onboarding-header-paypal-logos img { + margin: 5px; +} + +.ppcp-onboarding-header-cards img { + height: 37px; +} + +.ppcp-onboarding-header-paypal-logos img { + height: 32px; +} + +.ppcp-onboarding-cards-options table { + margin-left: 35px; + margin-right: 15px; +} + +.ppcp-onboarding-cards-options table td { + padding-top: 2px; +} + +.ppcp-onboarding-cards-options table td:first-child { + vertical-align: top; +} + +.ppcp-onboarding-cards-options table tr:not(:last-child) td { + padding-bottom: 0; +} + +.ppcp-onboarding-cards-options table tr td:first-child { + width: 350px; +} + +.ppcp-onboarding-cards-screen { + flex: 1; + align-self: center; +} + +.ppcp-onboarding-cards-screen img { + width: 100%; +} diff --git a/modules/ppcp-onboarding/assets/images/cards-screen-acdc.png b/modules/ppcp-onboarding/assets/images/cards-screen-acdc.png new file mode 100644 index 000000000..028012bb1 Binary files /dev/null and b/modules/ppcp-onboarding/assets/images/cards-screen-acdc.png differ diff --git a/modules/ppcp-onboarding/assets/images/cards-screen-basic.png b/modules/ppcp-onboarding/assets/images/cards-screen-basic.png new file mode 100644 index 000000000..106902102 Binary files /dev/null and b/modules/ppcp-onboarding/assets/images/cards-screen-basic.png differ diff --git a/modules/ppcp-onboarding/assets/js/onboarding.js b/modules/ppcp-onboarding/assets/js/onboarding.js index fd63915ff..0753ad943 100644 --- a/modules/ppcp-onboarding/assets/js/onboarding.js +++ b/modules/ppcp-onboarding/assets/js/onboarding.js @@ -1,9 +1,11 @@ -// Onboarding. const ppcp_onboarding = { BUTTON_SELECTOR: '[data-paypal-onboard-button]', PAYPAL_JS_ID: 'ppcp-onboarding-paypal-js', _timeout: false, + STATE_START: 'start', + STATE_ONBOARDED: 'onboarded', + init: function() { document.addEventListener('DOMContentLoaded', this.reload); }, @@ -15,7 +17,7 @@ const ppcp_onboarding = { return; } - // Add event listeners to buttons. + // Add event listeners to buttons preventing link clicking if PayPal init failed. buttons.forEach( (element) => { if (element.hasAttribute('data-ppcp-button-initialized')) { @@ -83,14 +85,13 @@ const ppcp_onboarding = { authCode: authCode, sharedId: sharedId, nonce: PayPalCommerceGatewayOnboarding.nonce, - env: env + env: env, + acceptCards: document.querySelector('#ppcp-onboarding-accept-cards').checked, } ) } ); }, - - }; function ppcp_onboarding_sandboxCallback(...args) { @@ -101,150 +102,151 @@ function ppcp_onboarding_productionCallback(...args) { return ppcp_onboarding.loginSeller('production', ...args); } -/** - * Since the PayPal modal will redirect the user a dirty form - * provokes an alert if the user wants to leave the page. Since the user - * needs to toggle the sandbox switch, we disable this dirty state with the - * following workaround for checkboxes. - * - * @param event - */ -const checkBoxOnClick = (event) => { - const value = event.target.checked; - if (event.target.getAttribute('id') === 'ppcp-sandbox_on') { - toggleSandboxProduction(! value); - } - event.preventDefault(); - event.stopPropagation(); - setTimeout( () => { - event.target.checked = value; - },1 - ); -}; - -/** - * Toggles the credential input fields. - * - * @param forProduction - */ -const credentialToggle = (forProduction) => { - - const sandboxClassSelectors = [ - '#field-ppcp_disconnect_sandbox', - '#field-merchant_email_sandbox', - '#field-merchant_id_sandbox', - '#field-client_id_sandbox', - '#field-client_secret_sandbox', - ]; - const productionClassSelectors = [ - '#field-ppcp_disconnect_production', - '#field-merchant_email_production', - '#field-merchant_id_production', - '#field-client_id_production', - '#field-client_secret_production', - ]; - - const selectors = forProduction ? productionClassSelectors : sandboxClassSelectors; - document.querySelectorAll(selectors.join()).forEach( - (element) => {element.classList.toggle('show')} - ) -}; - -/** - * Toggles the visibility of the sandbox/production input fields. - * - * @param showProduction - */ -const toggleSandboxProduction = (showProduction) => { - const productionDisplaySelectors = [ - '#field-credentials_production_heading', - '#field-production_toggle_manual_input', - '#field-ppcp_onboarding_production', - ]; - const productionClassSelectors = [ - - '#field-ppcp_disconnect_production', - '#field-merchant_email_production', - '#field-merchant_id_production', - '#field-client_id_production', - '#field-client_secret_production', - ]; - const sandboxDisplaySelectors = [ - '#field-credentials_sandbox_heading', - '#field-sandbox_toggle_manual_input', - '#field-ppcp_onboarding_sandbox', - ]; - const sandboxClassSelectors = [ - '#field-ppcp_disconnect_sandbox', - '#field-merchant_email_sandbox', - '#field-merchant_id_sandbox', - '#field-client_id_sandbox', - '#field-client_secret_sandbox', - ]; - - if (showProduction) { - document.querySelectorAll(productionDisplaySelectors.join()).forEach( - (element) => {element.style.display = ''} - ); - document.querySelectorAll(sandboxDisplaySelectors.join()).forEach( - (element) => {element.style.display = 'none'} - ); - document.querySelectorAll(productionClassSelectors.join()).forEach( - (element) => {element.classList.remove('hide')} - ); - document.querySelectorAll(sandboxClassSelectors.join()).forEach( - (element) => { - element.classList.remove('show'); - element.classList.add('hide'); - } - ); - return; - } - document.querySelectorAll(productionDisplaySelectors.join()).forEach( - (element) => {element.style.display = 'none'} - ); - document.querySelectorAll(sandboxDisplaySelectors.join()).forEach( - (element) => {element.style.display = ''} - ); - - document.querySelectorAll(sandboxClassSelectors.join()).forEach( - (element) => {element.classList.remove('hide')} - ); - document.querySelectorAll(productionClassSelectors.join()).forEach( - (element) => { - element.classList.remove('show'); - element.classList.add('hide'); - } - ) -}; - -const disconnect = (event) => { - event.preventDefault(); - const fields = event.target.classList.contains('production') ? [ - '#field-merchant_email_production input', - '#field-merchant_id_production input', - '#field-client_id_production input', - '#field-client_secret_production input', - ] : [ - '#field-merchant_email_sandbox input', - '#field-merchant_id_sandbox input', - '#field-client_id_sandbox input', - '#field-client_secret_sandbox input', - ]; - - document.querySelectorAll(fields.join()).forEach( - (element) => { - element.value = ''; - } - ); - document.querySelector('.woocommerce-save-button').click(); -}; - (() => { - const sandboxSwitchElement = document.querySelector('#ppcp-sandbox_on'); - if (sandboxSwitchElement) { - toggleSandboxProduction(! sandboxSwitchElement.checked); - } + const productionCredentialElementsSelectors = [ + '#field-merchant_email_production', + '#field-merchant_id_production', + '#field-client_id_production', + '#field-client_secret_production', + ]; + const sandboxCredentialElementsSelectors = [ + '#field-merchant_email_sandbox', + '#field-merchant_id_sandbox', + '#field-client_id_sandbox', + '#field-client_secret_sandbox', + ]; + + const updateOptionsState = () => { + const cardsChk = document.querySelector('#ppcp-onboarding-accept-cards'); + if (!cardsChk) { + return; + } + + document.querySelectorAll('#ppcp-onboarding-dcc-options input').forEach(input => { + input.disabled = !cardsChk.checked; + }); + + const basicRb = document.querySelector('#ppcp-onboarding-dcc-basic'); + + const isExpress = !cardsChk.checked || basicRb.checked; + + const expressButtonSelectors = [ + '#field-ppcp_onboarding_production_express', + '#field-ppcp_onboarding_sandbox_express', + ]; + const ppcpButtonSelectors = [ + '#field-ppcp_onboarding_production_ppcp', + '#field-ppcp_onboarding_sandbox_ppcp', + ]; + + document.querySelectorAll(expressButtonSelectors.join()).forEach( + element => element.style.display = isExpress ? '' : 'none' + ); + document.querySelectorAll(ppcpButtonSelectors.join()).forEach( + element => element.style.display = !isExpress ? '' : 'none' + ); + + const screemImg = document.querySelector('#ppcp-onboarding-cards-screen-img'); + if (screemImg) { + const currentRb = Array.from(document.querySelectorAll('#ppcp-onboarding-dcc-options input[type="radio"]')) + .filter(rb => rb.checked)[0] ?? null; + + const imgUrl = currentRb.getAttribute('data-screen-url'); + screemImg.src = imgUrl; + } + }; + + const updateManualInputControls = (shown, isSandbox, isAnyEnvOnboarded) => { + const productionElementsSelectors = productionCredentialElementsSelectors; + const sandboxElementsSelectors = sandboxCredentialElementsSelectors; + const otherElementsSelectors = [ + '.woocommerce-save-button', + ]; + if (!isAnyEnvOnboarded) { + otherElementsSelectors.push('#field-sandbox_on'); + } + + document.querySelectorAll(productionElementsSelectors.join()).forEach( + element => { + element.classList.remove('hide', 'show'); + element.classList.add((shown && !isSandbox) ? 'show' : 'hide'); + } + ); + document.querySelectorAll(sandboxElementsSelectors.join()).forEach( + element => { + element.classList.remove('hide', 'show'); + element.classList.add((shown && isSandbox) ? 'show' : 'hide'); + } + ); + document.querySelectorAll(otherElementsSelectors.join()).forEach( + element => element.style.display = shown ? '' : 'none' + ); + }; + + const updateEnvironmentControls = (isSandbox) => { + const productionElementsSelectors = [ + '#field-ppcp_disconnect_production', + '#field-credentials_production_heading', + ]; + const sandboxElementsSelectors = [ + '#field-ppcp_disconnect_sandbox', + '#field-credentials_sandbox_heading', + ]; + + document.querySelectorAll(productionElementsSelectors.join()).forEach( + element => element.style.display = !isSandbox ? '' : 'none' + ); + document.querySelectorAll(sandboxElementsSelectors.join()).forEach( + element => element.style.display = isSandbox ? '' : 'none' + ); + }; + + let isDisconnecting = false; + + const disconnect = (event) => { + event.preventDefault(); + const fields = event.target.classList.contains('production') ? productionCredentialElementsSelectors : sandboxCredentialElementsSelectors; + + document.querySelectorAll(fields.map(f => f + ' input').join()).forEach( + (element) => { + element.value = ''; + } + ); + + isDisconnecting = true; + + document.querySelector('.woocommerce-save-button').click(); + }; + + // Prevent the message about unsaved checkbox/radiobutton when reloading the page. + // (WC listens for changes on all inputs and sets dirty flag until form submission) + const preventDirtyCheckboxPropagation = event => { + event.preventDefault(); + event.stopPropagation(); + + const value = event.target.checked; + setTimeout( () => { + event.target.checked = value; + }, 1 + ); + }; + + const sandboxSwitchElement = document.querySelector('#ppcp-sandbox_on'); + + const validate = () => { + const selectors = sandboxSwitchElement.checked ? sandboxCredentialElementsSelectors : productionCredentialElementsSelectors; + const values = selectors.map(s => document.querySelector(s + ' input')).map(el => el.value); + + const errors = []; + if (values.some(v => !v)) { + errors.push(PayPalCommerceGatewayOnboarding.error_messages.no_credentials); + } + + return errors; + }; + + const isAnyEnvOnboarded = PayPalCommerceGatewayOnboarding.sandbox_state === ppcp_onboarding.STATE_ONBOARDED || + PayPalCommerceGatewayOnboarding.production_state === ppcp_onboarding.STATE_ONBOARDED; document.querySelectorAll('.ppcp-disconnect').forEach( (button) => { @@ -255,43 +257,89 @@ const disconnect = (event) => { } ); - // Prevent a possibly dirty form arising from this particular checkbox. - if (sandboxSwitchElement) { - sandboxSwitchElement.addEventListener( - 'click', - (event) => { - const value = event.target.checked; + document.querySelectorAll('.ppcp-onboarding-options input').forEach( + (element) => { + element.addEventListener('click', event => { + updateOptionsState(); - toggleSandboxProduction( ! value ); + preventDirtyCheckboxPropagation(event); + }); + } + ); - event.preventDefault(); - event.stopPropagation(); - setTimeout( () => { - event.target.checked = value; - }, 1 - ); - } - ); - } + const isSandboxInBackend = PayPalCommerceGatewayOnboarding.current_env === 'sandbox'; + if (sandboxSwitchElement.checked !== isSandboxInBackend) { + sandboxSwitchElement.checked = isSandboxInBackend; + } - // document.querySelectorAll('#mainform input[type="checkbox"]').forEach( - // (checkbox) => { - // checkbox.addEventListener('click', checkBoxOnClick); - // } - // ); + updateOptionsState(); - document.querySelectorAll('#field-sandbox_toggle_manual_input button, #field-production_toggle_manual_input button').forEach( - (button) => { - button.addEventListener( - 'click', - (event) => { - event.preventDefault(); - const isProduction = event.target.classList.contains('production-toggle'); - credentialToggle(isProduction); - } - ) - } - ); + const settingsContainer = document.querySelector('#mainform .form-table'); + + const markCurrentOnboardingState = (isOnboarded) => { + settingsContainer.classList.remove('ppcp-onboarded', 'ppcp-onboarding'); + settingsContainer.classList.add(isOnboarded ? 'ppcp-onboarded' : 'ppcp-onboarding'); + } + + markCurrentOnboardingState(PayPalCommerceGatewayOnboarding.current_state === ppcp_onboarding.STATE_ONBOARDED); + + const manualInputToggleButton = document.querySelector('#field-toggle_manual_input button'); + let isManualInputShown = PayPalCommerceGatewayOnboarding.current_state === ppcp_onboarding.STATE_ONBOARDED; + + manualInputToggleButton.addEventListener( + 'click', + (event) => { + event.preventDefault(); + + isManualInputShown = !isManualInputShown; + + updateManualInputControls(isManualInputShown, sandboxSwitchElement.checked, isAnyEnvOnboarded); + } + ); + + sandboxSwitchElement.addEventListener( + 'click', + (event) => { + const isSandbox = sandboxSwitchElement.checked; + + if (isAnyEnvOnboarded) { + const onboardingState = isSandbox ? PayPalCommerceGatewayOnboarding.sandbox_state : PayPalCommerceGatewayOnboarding.production_state; + const isOnboarded = onboardingState === ppcp_onboarding.STATE_ONBOARDED; + + markCurrentOnboardingState(isOnboarded); + isManualInputShown = isOnboarded; + } + + updateManualInputControls(isManualInputShown, isSandbox, isAnyEnvOnboarded); + + updateEnvironmentControls(isSandbox); + + preventDirtyCheckboxPropagation(event); + } + ); + + updateManualInputControls(isManualInputShown, sandboxSwitchElement.checked, isAnyEnvOnboarded); + + updateEnvironmentControls(sandboxSwitchElement.checked); + + document.querySelector('#mainform').addEventListener('submit', e => { + if (isDisconnecting) { + return; + } + + const errors = validate(); + if (errors.length) { + e.preventDefault(); + + const errorLabel = document.querySelector('#ppcp-form-errors-label'); + errorLabel.parentElement.parentElement.classList.remove('hide'); + + errorLabel.innerHTML = errors.join('
'); + + errorLabel.scrollIntoView(); + window.scrollBy(0, -120); // WP + WC floating header + } + }); // Onboarding buttons. ppcp_onboarding.init(); diff --git a/modules/ppcp-onboarding/assets/js/settings.js b/modules/ppcp-onboarding/assets/js/settings.js index e30b45856..9af409f07 100644 --- a/modules/ppcp-onboarding/assets/js/settings.js +++ b/modules/ppcp-onboarding/assets/js/settings.js @@ -23,7 +23,7 @@ document.addEventListener( } group.forEach( (elementToShow) => { - document.querySelector(elementToShow).style.display = 'table-row'; + document.querySelector(elementToShow).style.display = ''; }) if('ppcp-message_enabled' === event.target.getAttribute('id')){ @@ -56,7 +56,7 @@ document.addEventListener( return; } if (value === elementToToggle.value && domElement.style.display !== 'none') { - domElement.style.display = 'table-row'; + domElement.style.display = ''; return; } domElement.style.display = 'none'; @@ -69,7 +69,7 @@ document.addEventListener( const value = event.target.value; group.forEach( (elementToToggle) => { if (value === elementToToggle.value) { - document.querySelector(elementToToggle.selector).style.display = 'table-row'; + document.querySelector(elementToToggle.selector).style.display = ''; return; } document.querySelector(elementToToggle.selector).style.display = 'none'; diff --git a/modules/ppcp-onboarding/services.php b/modules/ppcp-onboarding/services.php index cb0e17590..a3a2fec58 100644 --- a/modules/ppcp-onboarding/services.php +++ b/modules/ppcp-onboarding/services.php @@ -18,6 +18,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnerReferrals; use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache; use WooCommerce\PayPalCommerce\Onboarding\Assets\OnboardingAssets; use WooCommerce\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint; +use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer; use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer; use WooCommerce\PayPalCommerce\Onboarding\OnboardingRESTController; @@ -117,9 +118,8 @@ return array( ); }, 'onboarding.state' => function( ContainerInterface $container ) : State { - $environment = $container->get( 'onboarding.environment' ); $settings = $container->get( 'wcgateway.settings' ); - return new State( $environment, $settings ); + return new State( $settings ); }, 'onboarding.environment' => function( ContainerInterface $container ) : Environment { $settings = $container->get( 'wcgateway.settings' ); @@ -131,8 +131,11 @@ return array( $login_seller_endpoint = $container->get( 'onboarding.endpoint.login-seller' ); return new OnboardingAssets( $container->get( 'onboarding.url' ), + $container->get( 'ppcp.asset-version' ), $state, - $login_seller_endpoint + $container->get( 'onboarding.environment' ), + $login_seller_endpoint, + $container->get( 'wcgateway.current-ppcp-settings-page-id' ) ); }, @@ -188,7 +191,6 @@ return array( return new PartnerReferrals( CONNECT_WOO_SANDBOX_URL, new ConnectBearer(), - $container->get( 'api.repository.partner-referrals-data' ), $container->get( 'woocommerce.logger.woocommerce' ) ); }, @@ -197,7 +199,6 @@ return array( return new PartnerReferrals( CONNECT_WOO_URL, new ConnectBearer(), - $container->get( 'api.repository.partner-referrals-data' ), $container->get( 'woocommerce.logger.woocommerce' ) ); }, @@ -205,11 +206,18 @@ return array( $partner_referrals = $container->get( 'api.endpoint.partner-referrals-production' ); $partner_referrals_sandbox = $container->get( 'api.endpoint.partner-referrals-sandbox' ); + $partner_referrals_data = $container->get( 'api.repository.partner-referrals-data' ); $settings = $container->get( 'wcgateway.settings' ); return new OnboardingRenderer( $settings, $partner_referrals, - $partner_referrals_sandbox + $partner_referrals_sandbox, + $partner_referrals_data + ); + }, + 'onboarding.render-options' => static function ( ContainerInterface $container ) : OnboardingOptionsRenderer { + return new OnboardingOptionsRenderer( + $container->get( 'onboarding.url' ) ); }, 'onboarding.rest' => static function( $container ) : OnboardingRESTController { diff --git a/modules/ppcp-onboarding/src/Assets/OnboardingAssets.php b/modules/ppcp-onboarding/src/Assets/OnboardingAssets.php index 57a632860..55e99c0d1 100644 --- a/modules/ppcp-onboarding/src/Assets/OnboardingAssets.php +++ b/modules/ppcp-onboarding/src/Assets/OnboardingAssets.php @@ -10,7 +10,9 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\Onboarding\Assets; use WooCommerce\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint; +use WooCommerce\PayPalCommerce\Onboarding\Environment; use WooCommerce\PayPalCommerce\Onboarding\State; +use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; /** * Class OnboardingAssets @@ -24,6 +26,13 @@ class OnboardingAssets { */ private $module_url; + /** + * The assets version. + * + * @var string + */ + private $version; + /** * The State. * @@ -31,6 +40,13 @@ class OnboardingAssets { */ private $state; + /** + * The Environment. + * + * @var Environment + */ + private $environment; + /** * The LoginSeller Endpoint. * @@ -38,22 +54,38 @@ class OnboardingAssets { */ private $login_seller_endpoint; + /** + * ID of the current PPCP gateway settings page, or empty if it is not such page. + * + * @var string + */ + protected $page_id; + /** * OnboardingAssets constructor. * * @param string $module_url The URL to the module. + * @param string $version The assets version. * @param State $state The State object. + * @param Environment $environment The Environment. * @param LoginSellerEndpoint $login_seller_endpoint The LoginSeller endpoint. + * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page. */ public function __construct( string $module_url, + string $version, State $state, - LoginSellerEndpoint $login_seller_endpoint + Environment $environment, + LoginSellerEndpoint $login_seller_endpoint, + string $page_id ) { $this->module_url = untrailingslashit( $module_url ); + $this->version = $version; $this->state = $state; + $this->environment = $environment; $this->login_seller_endpoint = $login_seller_endpoint; + $this->page_id = $page_id; } /** @@ -68,14 +100,14 @@ class OnboardingAssets { 'ppcp-onboarding', $url, array(), - 1 + $this->version ); $url = untrailingslashit( $this->module_url ) . '/assets/js/settings.js'; wp_register_script( 'ppcp-settings', $url, array(), - 1, + $this->version, true ); @@ -84,7 +116,7 @@ class OnboardingAssets { 'ppcp-onboarding', $url, array( 'jquery' ), - 1, + $this->version, true ); wp_localize_script( @@ -103,9 +135,16 @@ class OnboardingAssets { */ public function get_script_data() { return array( - 'endpoint' => home_url( \WC_AJAX::get_endpoint( LoginSellerEndpoint::ENDPOINT ) ), - 'nonce' => wp_create_nonce( $this->login_seller_endpoint::nonce() ), - 'paypal_js_url' => 'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js', + 'endpoint' => home_url( \WC_AJAX::get_endpoint( LoginSellerEndpoint::ENDPOINT ) ), + 'nonce' => wp_create_nonce( $this->login_seller_endpoint::nonce() ), + 'paypal_js_url' => 'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js', + 'sandbox_state' => State::get_state_name( $this->state->sandbox_state() ), + 'production_state' => State::get_state_name( $this->state->production_state() ), + 'current_state' => State::get_state_name( $this->state->current_state() ), + 'current_env' => $this->environment->current_environment(), + 'error_messages' => array( + 'no_credentials' => __( 'API credentials must be entered to save the settings.', 'woocommerce-paypal-payments' ), + ), ); } @@ -131,7 +170,6 @@ class OnboardingAssets { * @return bool */ private function should_render_onboarding_script(): bool { - global $current_section; - return 'ppcp-gateway' === $current_section; + return PayPalGateway::ID === $this->page_id; } } diff --git a/modules/ppcp-onboarding/src/Endpoint/LoginSellerEndpoint.php b/modules/ppcp-onboarding/src/Endpoint/LoginSellerEndpoint.php index 38b54331b..b8a458609 100644 --- a/modules/ppcp-onboarding/src/Endpoint/LoginSellerEndpoint.php +++ b/modules/ppcp-onboarding/src/Endpoint/LoginSellerEndpoint.php @@ -128,6 +128,7 @@ class LoginSellerEndpoint implements EndpointInterface { $this->settings->set( 'sandbox_on', $is_sandbox ); $this->settings->set( 'products_dcc_enabled', null ); $this->settings->persist(); + $endpoint = $is_sandbox ? $this->login_seller_sandbox : $this->login_seller_production; $credentials = $endpoint->credentials_for( $data['sharedId'], @@ -143,10 +144,30 @@ class LoginSellerEndpoint implements EndpointInterface { } $this->settings->set( 'client_secret', $credentials->client_secret ); $this->settings->set( 'client_id', $credentials->client_id ); + + $accept_cards = (bool) ( $data['acceptCards'] ?? true ); + $funding_sources = array(); + if ( $this->settings->get( 'disable_funding' ) ) { + $funding_sources = $this->settings->get( 'disable_funding' ); + if ( ! is_array( $funding_sources ) ) { + $funding_sources = array(); + } + } + if ( $accept_cards ) { + $funding_sources = array_diff( $funding_sources, array( 'card' ) ); + } else { + if ( ! in_array( 'card', $funding_sources, true ) ) { + $funding_sources[] = 'card'; + } + } + $this->settings->set( 'disable_funding', $funding_sources ); + $this->settings->persist(); + if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) { $this->cache->delete( PayPalBearer::CACHE_KEY ); } + wp_schedule_single_event( time() + 5, WebhookRegistrar::EVENT_HOOK diff --git a/modules/ppcp-onboarding/src/OnboardingModule.php b/modules/ppcp-onboarding/src/OnboardingModule.php index d05b9509f..0960c7b6c 100644 --- a/modules/ppcp-onboarding/src/OnboardingModule.php +++ b/modules/ppcp-onboarding/src/OnboardingModule.php @@ -65,16 +65,15 @@ class OnboardingModule implements ModuleInterface { if ( 'ppcp_onboarding' !== $config['type'] ) { return $field; } - $renderer = $c->get( 'onboarding.render' ); - $is_production = 'production' === $config['env']; - /** - * The OnboardingRenderer. - * - * @var OnboardingRenderer $renderer - */ + $renderer = $c->get( 'onboarding.render' ); + assert( $renderer instanceof OnboardingRenderer ); + + $is_production = 'production' === $config['env']; + $products = $config['products']; + ob_start(); - $renderer->render( $is_production ); + $renderer->render( $is_production, $products ); $content = ob_get_contents(); ob_end_clean(); return $content; diff --git a/modules/ppcp-onboarding/src/OnboardingRESTController.php b/modules/ppcp-onboarding/src/OnboardingRESTController.php index 9a5fae43a..209534564 100644 --- a/modules/ppcp-onboarding/src/OnboardingRESTController.php +++ b/modules/ppcp-onboarding/src/OnboardingRESTController.php @@ -10,7 +10,6 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\Onboarding; use Psr\Container\ContainerInterface; -use WooCommerce\PayPalCommerce\Onboarding\State; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; /** @@ -138,13 +137,13 @@ class OnboardingRESTController { return array( 'environment' => $environment->current_environment(), 'onboarded' => ( $state->current_state() >= State::STATE_ONBOARDED ), - 'state' => $this->get_onboarding_state_name( $state->current_state() ), + 'state' => State::get_state_name( $state->current_state() ), 'sandbox' => array( - 'state' => $this->get_onboarding_state_name( $state->sandbox_state() ), + 'state' => State::get_state_name( $state->sandbox_state() ), 'onboarded' => ( $state->sandbox_state() >= State::STATE_ONBOARDED ), ), 'production' => array( - 'state' => $this->get_onboarding_state_name( $state->production_state() ), + 'state' => State::get_state_name( $state->production_state() ), 'onboarded' => ( $state->production_state() >= State::STATE_ONBOARDED ), ), ); @@ -265,34 +264,6 @@ class OnboardingRESTController { return add_query_arg( $this->return_url_args, $url ); } - /** - * Translates an onboarding state to a string. - * - * @param int $state An onboarding state to translate as returned by {@link State} methods. - * @return string A string representing the state: "start", "progressive" or "onboarded". - * @see State::current_state(), State::sandbox_state(), State::production_state(). - */ - public function get_onboarding_state_name( $state ) { - $name = 'unknown'; - - switch ( absint( $state ) ) { - case State::STATE_START: - $name = 'start'; - break; - case State::STATE_PROGRESSIVE: - $name = 'progressive'; - break; - case State::STATE_ONBOARDED: - $name = 'onboarded'; - break; - default: - break; - - } - - return $name; - } - /** * Generates a signup link for onboarding for a given environment and optionally adding certain URL arguments * to the URL users are redirected after completing the onboarding flow. diff --git a/modules/ppcp-onboarding/src/Render/OnboardingOptionsRenderer.php b/modules/ppcp-onboarding/src/Render/OnboardingOptionsRenderer.php new file mode 100644 index 000000000..be69cf4ce --- /dev/null +++ b/modules/ppcp-onboarding/src/Render/OnboardingOptionsRenderer.php @@ -0,0 +1,199 @@ +module_url = $module_url; + } + + /** + * Renders the onboarding options. + * + * @param bool $is_shop_supports_dcc Whether the shop can use DCC (country, currency). + */ + public function render( bool $is_shop_supports_dcc ): string { + return ' +'; + } + + /** + * Renders the onboarding DCC options. + * + * @param bool $is_shop_supports_dcc Whether the shop can use DCC (country, currency). + */ + private function render_dcc( bool $is_shop_supports_dcc ): string { + $items = array(); + + if ( $is_shop_supports_dcc ) { + $dcc_table_rows = array( + $this->render_table_row( + __( 'Credit & Debit Card form fields', 'woocommerce-paypal-payments' ), + __( 'Customizable user experience', 'woocommerce-paypal-payments' ) + ), + $this->render_table_row( + __( 'Credit & Debit Card pricing', 'woocommerce-paypal-payments' ), + __( '2.59% + $0.49', 'woocommerce-paypal-payments' ) + ), + $this->render_table_row( + __( 'Seller Protection', 'woocommerce-paypal-payments' ), + __( 'Yes', 'woocommerce-paypal-payments' ), + __( 'No matter what you sell, Seller Protection can help you avoid chargebacks, reversals, and fees on eligible PayPal payment transactions — even when a customer has filed a dispute.', 'woocommerce-paypal-payments' ), + __( 'On eligible PayPal transactions', 'woocommerce-paypal-payments' ) + ), + $this->render_table_row( + __( 'Advanced Fraud Protection', 'woocommerce-paypal-payments' ), + __( 'Yes', 'woocommerce-paypal-payments' ), + __( 'Included with Advanced Checkout at no extra cost, Fraud Protection gives you the insight and control you need to better balance chargebacks and declines.', 'woocommerce-paypal-payments' ) + ), + $this->render_table_row( + __( 'Chargeback Protection', 'woocommerce-paypal-payments' ), + __( 'Yes', 'woocommerce-paypal-payments' ), + __( 'If you choose this optional, fee-based alternative to Fraud Protection, PayPal will manage chargebacks for eligible credit and debit card transactions — so you won’t have to worry about unexpected costs.', 'woocommerce-paypal-payments' ), + __( 'Extra 0.4% per transaction', 'woocommerce-paypal-payments' ) + ), + $this->render_table_row( + __( 'Additional Vetting and Underwriting Required', 'woocommerce-paypal-payments' ), + __( 'Yes', 'woocommerce-paypal-payments' ), + __( 'Business Ownership and other business information will be required during the application for Advanced Card Processing.', 'woocommerce-paypal-payments' ) + ), + $this->render_table_row( + __( 'Seller Account Type', 'woocommerce-paypal-payments' ), + __( 'Business', 'woocommerce-paypal-payments' ) + ), + ); + $items[] = ' +
  • + + ' . + __( 'Advanced Card Processing', 'woocommerce-paypal-payments' ) . ' + + + ' . implode( '', $dcc_table_rows ) . ' +
    +
  • '; + } + + $basic_table_rows = array( + $this->render_table_row( + __( 'Credit & Debit Card form fields', 'woocommerce-paypal-payments' ), + __( 'Prebuilt user experience', 'woocommerce-paypal-payments' ) + ), + $this->render_table_row( + __( 'Credit & Debit Card pricing', 'woocommerce-paypal-payments' ), + __( '3.49% + $0.49', 'woocommerce-paypal-payments' ) + ), + $this->render_table_row( + __( 'Seller Protection', 'woocommerce-paypal-payments' ), + __( 'Yes', 'woocommerce-paypal-payments' ), + __( 'No matter what you sell, Seller Protection can help you avoid chargebacks, reversals, and fees on eligible PayPal payment transactions — even when a customer has filed a dispute.', 'woocommerce-paypal-payments' ), + __( 'On eligible PayPal transactions', 'woocommerce-paypal-payments' ) + ), + $this->render_table_row( + __( 'Seller Account Type', 'woocommerce-paypal-payments' ), + __( 'Business or Personal', 'woocommerce-paypal-payments' ), + __( 'For Standard payments, Casual sellers may connect their Personal PayPal account in eligible countries to sell on WooCommerce. For Advanced payments, a Business PayPal account is required.', 'woocommerce-paypal-payments' ) + ), + ); + $items[] = ' +
  • + + + ' . implode( $basic_table_rows ) . ' +
    +
  • '; + + return ' +
    + +
    ' . + ( $is_shop_supports_dcc ? '' : '' ) . ' +
    +
    '; + } + + /** + * Returns HTML of a row for the cards options tables. + * + * @param string $header The text in the first cell. + * @param string $value The text in the second cell. + * @param string $tooltip The text shown on hover. + * @param string $note The additional description text, such as about conditions. + * @return string + */ + private function render_table_row( string $header, string $value, string $tooltip = '', string $note = '' ): string { + $value_html = $value; + if ( $note ) { + $value_html .= '
    ' . $note . ''; + } + + $row_attributes_html = ''; + if ( $tooltip ) { + $row_attributes_html .= 'title="' . $tooltip . '"'; + } + + return " + + $header + $value_html +"; + } + + /** + * Returns the screen image URL. + * + * @param string $key The image suffix, 'acdc' or 'basic'. + * @return string + */ + private function get_screen_url( string $key ): string { + return untrailingslashit( $this->module_url ) . "/assets/images/cards-screen-$key.png"; + } +} diff --git a/modules/ppcp-onboarding/src/Render/OnboardingRenderer.php b/modules/ppcp-onboarding/src/Render/OnboardingRenderer.php index cc2fa38f1..9d2f6957b 100644 --- a/modules/ppcp-onboarding/src/Render/OnboardingRenderer.php +++ b/modules/ppcp-onboarding/src/Render/OnboardingRenderer.php @@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Onboarding\Render; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnerReferrals; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; +use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; /** @@ -39,31 +40,50 @@ class OnboardingRenderer { */ private $sandbox_partner_referrals; + /** + * The default partner referrals data. + * + * @var PartnerReferralsData + */ + private $partner_referrals_data; + /** * OnboardingRenderer constructor. * - * @param Settings $settings The settings. - * @param PartnerReferrals $production_partner_referrals The PartnerReferrals for production. - * @param PartnerReferrals $sandbox_partner_referrals The PartnerReferrals for sandbox. + * @param Settings $settings The settings. + * @param PartnerReferrals $production_partner_referrals The PartnerReferrals for production. + * @param PartnerReferrals $sandbox_partner_referrals The PartnerReferrals for sandbox. + * @param PartnerReferralsData $partner_referrals_data The default partner referrals data. */ - public function __construct( Settings $settings, PartnerReferrals $production_partner_referrals, PartnerReferrals $sandbox_partner_referrals ) { + public function __construct( + Settings $settings, + PartnerReferrals $production_partner_referrals, + PartnerReferrals $sandbox_partner_referrals, + PartnerReferralsData $partner_referrals_data + ) { $this->settings = $settings; $this->production_partner_referrals = $production_partner_referrals; $this->sandbox_partner_referrals = $sandbox_partner_referrals; + $this->partner_referrals_data = $partner_referrals_data; } /** * Returns the action URL for the onboarding button/link. * - * @param boolean $is_production Whether the production or sandbox button should be rendered. + * @param boolean $is_production Whether the production or sandbox button should be rendered. + * @param string[] $products The list of products ('PPCP', 'EXPRESS_CHECKOUT'). * @return string URL. */ - public function get_signup_link( bool $is_production ) { + public function get_signup_link( bool $is_production, array $products ) { $args = array( 'displayMode' => 'minibrowser', ); - $url = $is_production ? $this->production_partner_referrals->signup_link() : $this->sandbox_partner_referrals->signup_link(); + $data = $this->partner_referrals_data + ->with_products( $products ) + ->data(); + + $url = $is_production ? $this->production_partner_referrals->signup_link( $data ) : $this->sandbox_partner_referrals->signup_link( $data ); $url = add_query_arg( $args, $url ); return $url; @@ -72,14 +92,18 @@ class OnboardingRenderer { /** * Renders the "Connect to PayPal" button. * - * @param bool $is_production Whether the production or sandbox button should be rendered. + * @param bool $is_production Whether the production or sandbox button should be rendered. + * @param string[] $products The list of products ('PPCP', 'EXPRESS_CHECKOUT'). */ - public function render( bool $is_production ) { + public function render( bool $is_production, array $products ) { try { + $id = 'connect-to' . ( $is_production ? 'production' : 'sandbox' ) . strtolower( implode( '-', $products ) ); + $this->render_button( - $this->get_signup_link( $is_production ), - $is_production ? 'connect-to-production' : 'connect-to-sandbox', - $is_production ? __( 'Connect to PayPal', 'woocommerce-paypal-payments' ) : __( 'Connect to PayPal Sandbox', 'woocommerce-paypal-payments' ), + $this->get_signup_link( $is_production, $products ), + $id, + $is_production ? __( 'Activate PayPal', 'woocommerce-paypal-payments' ) : __( 'Test payments with PayPal sandbox', 'woocommerce-paypal-payments' ), + $is_production ? 'primary' : 'secondary', $is_production ? 'production' : 'sandbox' ); } catch ( RuntimeException $exception ) { @@ -96,13 +120,14 @@ class OnboardingRenderer { * @param string $url The url of the button. * @param string $id The ID of the button. * @param string $label The button text. + * @param string $class The CSS class for button ('primary', 'secondary'). * @param string $env The environment ('production' or 'sandbox'). */ - private function render_button( string $url, string $id, string $label, string $env ) { + private function render_button( string $url, string $id, string $label, string $class, string $env ) { ?> environment = $environment; - $this->settings = $settings; + $this->settings = $settings; + } + + /** + * Returns the state of the specified environment (or the active environment if null). + * + * @param string|null $environment 'sandbox', 'production'. + * @return int + */ + public function environment_state( ?string $environment = null ): int { + switch ( $environment ) { + case Environment::PRODUCTION: + return $this->production_state(); + case Environment::SANDBOX: + return $this->sandbox_state(); + } + return $this->current_state(); } /** @@ -57,9 +62,6 @@ class State { public function current_state(): int { return $this->state_by_keys( - array( - 'merchant_email', - ), array( 'merchant_email', 'merchant_id', @@ -77,9 +79,6 @@ class State { public function sandbox_state() : int { return $this->state_by_keys( - array( - 'merchant_email_sandbox', - ), array( 'merchant_email_sandbox', 'merchant_id_sandbox', @@ -97,9 +96,6 @@ class State { public function production_state() : int { return $this->state_by_keys( - array( - 'merchant_email_production', - ), array( 'merchant_email_production', 'merchant_id_production', @@ -110,36 +106,36 @@ class State { } /** - * Returns the state based on progressive and onboarded values being looked up in the settings. + * Translates an onboarding state to a string. + * + * @param int $state An onboarding state to translate. + * @return string A string representing the state: "start" or "onboarded". + */ + public static function get_state_name( int $state ) : string { + switch ( $state ) { + case self::STATE_START: + return 'start'; + case self::STATE_ONBOARDED: + return 'onboarded'; + default: + return 'unknown'; + } + } + + /** + * Returns the state based on onboarding settings values. * - * @param array $progressive_keys The keys which need to be present to be at least in progressive state. * @param array $onboarded_keys The keys which need to be present to be in onboarded state. * * @return int */ - private function state_by_keys( array $progressive_keys, array $onboarded_keys ) : int { - $state = self::STATE_START; - $is_progressive = true; - foreach ( $progressive_keys as $key ) { - if ( ! $this->settings->has( $key ) || ! $this->settings->get( $key ) ) { - $is_progressive = false; - } - } - if ( $is_progressive ) { - $state = self::STATE_PROGRESSIVE; - } - - $is_onboarded = true; + private function state_by_keys( array $onboarded_keys ) : int { foreach ( $onboarded_keys as $key ) { if ( ! $this->settings->has( $key ) || ! $this->settings->get( $key ) ) { - $is_onboarded = false; + return self::STATE_START; } } - if ( $is_onboarded ) { - $state = self::STATE_ONBOARDED; - } - - return $state; + return self::STATE_ONBOARDED; } } diff --git a/modules/ppcp-subscription/src/RenewalHandler.php b/modules/ppcp-subscription/src/RenewalHandler.php index e2815baf6..2103e443d 100644 --- a/modules/ppcp-subscription/src/RenewalHandler.php +++ b/modules/ppcp-subscription/src/RenewalHandler.php @@ -174,6 +174,9 @@ class RenewalHandler { * @return PaymentToken|null */ private function get_token_for_customer( \WC_Customer $customer, \WC_Order $wc_order ) { + /** + * Returns a payment token for a customer, or null. + */ $token = apply_filters( 'woocommerce_paypal_payments_subscriptions_get_token_for_customer', null, $customer, $wc_order ); if ( null !== $token ) { return $token; diff --git a/modules/ppcp-vaulting/services.php b/modules/ppcp-vaulting/services.php index 0e3e2d7d1..c7b5bac1e 100644 --- a/modules/ppcp-vaulting/services.php +++ b/modules/ppcp-vaulting/services.php @@ -22,7 +22,8 @@ return array( }, 'vaulting.assets.myaccount-payments' => function( ContainerInterface $container ) : MyAccountPaymentsAssets { return new MyAccountPaymentsAssets( - $container->get( 'vaulting.module-url' ) + $container->get( 'vaulting.module-url' ), + $container->get( 'ppcp.asset-version' ) ); }, 'vaulting.payment-tokens-renderer' => static function (): PaymentTokensRenderer { diff --git a/modules/ppcp-vaulting/src/Assets/MyAccountPaymentsAssets.php b/modules/ppcp-vaulting/src/Assets/MyAccountPaymentsAssets.php index 80e9bc3db..36c3a4da3 100644 --- a/modules/ppcp-vaulting/src/Assets/MyAccountPaymentsAssets.php +++ b/modules/ppcp-vaulting/src/Assets/MyAccountPaymentsAssets.php @@ -23,15 +23,25 @@ class MyAccountPaymentsAssets { */ private $module_url; + /** + * The assets version. + * + * @var string + */ + private $version; + /** * MyAccountPaymentsAssets constructor. * * @param string $module_url The URL to the module. + * @param string $version The assets version. */ public function __construct( - string $module_url + string $module_url, + string $version ) { $this->module_url = untrailingslashit( $module_url ); + $this->version = $version; } /** @@ -44,7 +54,7 @@ class MyAccountPaymentsAssets { 'ppcp-vaulting-myaccount-payments', untrailingslashit( $this->module_url ) . '/assets/js/myaccount-payments.js', array( 'jquery' ), - '1', + $this->version, true ); } diff --git a/modules/ppcp-wc-gateway/assets/images/amex.svg b/modules/ppcp-wc-gateway/assets/images/amex.svg index d9c69a5e5..5aa37e085 100644 --- a/modules/ppcp-wc-gateway/assets/images/amex.svg +++ b/modules/ppcp-wc-gateway/assets/images/amex.svg @@ -1,10 +1,19 @@ - - Amex_acceptancemark_50x50 - - - - + + AmEx Card Icon + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/ppcp-wc-gateway/assets/images/ideal-dark.svg b/modules/ppcp-wc-gateway/assets/images/ideal-dark.svg new file mode 100644 index 000000000..d2426a5b2 --- /dev/null +++ b/modules/ppcp-wc-gateway/assets/images/ideal-dark.svg @@ -0,0 +1,22 @@ + + + iDEAL_acceptancemark_80x50 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/ppcp-wc-gateway/assets/images/mastercard-dark.svg b/modules/ppcp-wc-gateway/assets/images/mastercard-dark.svg new file mode 100644 index 000000000..8eb40d9ba --- /dev/null +++ b/modules/ppcp-wc-gateway/assets/images/mastercard-dark.svg @@ -0,0 +1,17 @@ + + + Mastercard_acceptancemark_80x50 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/ppcp-wc-gateway/assets/images/paylater.svg b/modules/ppcp-wc-gateway/assets/images/paylater.svg new file mode 100644 index 000000000..c281f4d63 --- /dev/null +++ b/modules/ppcp-wc-gateway/assets/images/paylater.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/ppcp-wc-gateway/assets/images/paypal-button.svg b/modules/ppcp-wc-gateway/assets/images/paypal-button.svg new file mode 100644 index 000000000..e4050f2a4 --- /dev/null +++ b/modules/ppcp-wc-gateway/assets/images/paypal-button.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/ppcp-wc-gateway/assets/images/paypal.png b/modules/ppcp-wc-gateway/assets/images/paypal.png new file mode 100755 index 000000000..180620eee Binary files /dev/null and b/modules/ppcp-wc-gateway/assets/images/paypal.png differ diff --git a/modules/ppcp-wc-gateway/assets/images/sofort.svg b/modules/ppcp-wc-gateway/assets/images/sofort.svg index 26c9c95e3..1d693e376 100644 --- a/modules/ppcp-wc-gateway/assets/images/sofort.svg +++ b/modules/ppcp-wc-gateway/assets/images/sofort.svg @@ -1,12 +1,16 @@ - - Sofort_acceptancemark_80x50 - - - - - - + + Sofort + + + + + + + + + + diff --git a/modules/ppcp-wc-gateway/assets/images/venmo.svg b/modules/ppcp-wc-gateway/assets/images/venmo.svg new file mode 100644 index 000000000..6395fba8d --- /dev/null +++ b/modules/ppcp-wc-gateway/assets/images/venmo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/ppcp-wc-gateway/assets/images/visa-dark.svg b/modules/ppcp-wc-gateway/assets/images/visa-dark.svg new file mode 100644 index 000000000..6d2766cee --- /dev/null +++ b/modules/ppcp-wc-gateway/assets/images/visa-dark.svg @@ -0,0 +1,14 @@ + + + Visa_acceptancemark_80x50 + + + + + + + + + + + \ No newline at end of file diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index 1442531a2..cfcbb18c1 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -17,6 +17,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache; use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies; use WooCommerce\PayPalCommerce\Button\Helper\MessagesDisclaimers; use WooCommerce\PayPalCommerce\Onboarding\Environment; +use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer; use WooCommerce\PayPalCommerce\Onboarding\State; use WooCommerce\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn; use WooCommerce\PayPalCommerce\WcGateway\Admin\PaymentStatusOrderDetail; @@ -254,78 +255,207 @@ return array( 'wcgateway.settings.fields' => static function ( ContainerInterface $container ): array { $state = $container->get( 'onboarding.state' ); + assert( $state instanceof State ); + $messages_disclaimers = $container->get( 'button.helper.messages-disclaimers' ); + $dcc_applies = $container->get( 'api.helpers.dccapplies' ); + assert( $dcc_applies instanceof DccApplies ); + + $is_shop_supports_dcc = $dcc_applies->for_country_currency(); + + $onboarding_options_renderer = $container->get( 'onboarding.render-options' ); + assert( $onboarding_options_renderer instanceof OnboardingOptionsRenderer ); + + $module_url = $container->get( 'wcgateway.url' ); + $fields = array( - 'sandbox_on' => array( + 'ppcp_onboarading_header' => array( + 'type' => 'ppcp-text', + 'classes' => array( 'ppcp-onboarding-element' ), + 'text' => ' +
    +
    + PayPal +

    The all-in-one checkout solution

    +
    +
    +
    + PayPal + Venmo + Pay Later +
    +
    + Visa + Mastercard + American Express + Discover + iDEAL + Sofort +
    +
    +
    ', + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + + 'credentials_production_heading' => array( + 'heading' => __( 'API Credentials', 'woocommerce-paypal-payments' ), + 'type' => 'ppcp-heading', + 'screens' => array( + State::STATE_ONBOARDED, + ), + 'state_from' => Environment::PRODUCTION, + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'credentials_sandbox_heading' => array( + 'heading' => __( 'Sandbox API Credentials', 'woocommerce-paypal-payments' ), + 'type' => 'ppcp-heading', + 'screens' => array( + State::STATE_ONBOARDED, + ), + 'state_from' => Environment::SANDBOX, + 'requirements' => array(), + 'gateway' => 'paypal', + 'description' => __( 'Your account is connected to sandbox, no real charging takes place. To accept live payments, turn off sandbox mode and connect your live PayPal account.', 'woocommerce-paypal-payments' ), + ), + + 'ppcp_onboarading_options' => array( + 'type' => 'ppcp-text', + 'classes' => array( 'ppcp-onboarding-element' ), + 'text' => $onboarding_options_renderer->render( $is_shop_supports_dcc ), + 'raw' => true, + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + + // We need to have a button for each option (ppcp, express) + // because currently the only documented way to use the PayPal onboarding JS library + // is to have the buttons before loading the script. + 'ppcp_onboarding_production_ppcp' => array( + 'type' => 'ppcp_onboarding', + 'classes' => array( 'ppcp-onboarding-element' ), + 'screens' => array( + State::STATE_START, + ), + 'state_from' => Environment::PRODUCTION, + 'env' => Environment::PRODUCTION, + 'products' => array( 'PPCP' ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'ppcp_onboarding_production_express' => array( + 'type' => 'ppcp_onboarding', + 'classes' => array( 'ppcp-onboarding-element' ), + 'screens' => array( + State::STATE_START, + ), + 'state_from' => Environment::PRODUCTION, + 'env' => Environment::PRODUCTION, + 'products' => array( 'EXPRESS_CHECKOUT' ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'ppcp_onboarding_sandbox_ppcp' => array( + 'type' => 'ppcp_onboarding', + 'classes' => array( 'ppcp-onboarding-element' ), + 'screens' => array( + State::STATE_START, + ), + 'state_from' => Environment::SANDBOX, + 'env' => Environment::SANDBOX, + 'products' => array( 'PPCP' ), + 'requirements' => array(), + 'gateway' => 'paypal', + 'description' => __( 'Prior to accepting live payments, you can test payments on your WooCommerce platform in a safe PayPal sandbox environment.', 'woocommerce-paypal-payments' ), + ), + 'ppcp_onboarding_sandbox_express' => array( + 'type' => 'ppcp_onboarding', + 'classes' => array( 'ppcp-onboarding-element' ), + 'screens' => array( + State::STATE_START, + ), + 'state_from' => Environment::SANDBOX, + 'env' => Environment::SANDBOX, + 'products' => array( 'EXPRESS_CHECKOUT' ), + 'requirements' => array(), + 'gateway' => 'paypal', + 'description' => __( 'Prior to accepting live payments, you can test payments on your WooCommerce platform in a safe PayPal sandbox environment.', 'woocommerce-paypal-payments' ), + ), + + 'ppcp_disconnect_production' => array( + 'title' => __( 'Disconnect from PayPal', 'woocommerce-paypal-payments' ), + 'type' => 'ppcp-text', + 'text' => '', + 'screens' => array( + State::STATE_ONBOARDED, + ), + 'state_from' => Environment::PRODUCTION, + 'env' => Environment::PRODUCTION, + 'requirements' => array(), + 'gateway' => 'paypal', + 'description' => __( 'Click to reset current credentials and use another account.', 'woocommerce-paypal-payments' ), + ), + 'ppcp_disconnect_sandbox' => array( + 'title' => __( 'Disconnect from PayPal Sandbox', 'woocommerce-paypal-payments' ), + 'type' => 'ppcp-text', + 'text' => '', + 'screens' => array( + State::STATE_ONBOARDED, + ), + 'state_from' => Environment::SANDBOX, + 'env' => Environment::SANDBOX, + 'requirements' => array(), + 'gateway' => 'paypal', + 'description' => __( 'Click to reset current credentials and use another account.', 'woocommerce-paypal-payments' ), + ), + 'toggle_manual_input' => array( + 'type' => 'ppcp-text', + 'text' => '', + 'classes' => array( 'ppcp-onboarding-element' ), + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'error_label' => array( + 'type' => 'ppcp-text', + 'text' => '', + 'classes' => array( 'hide', 'ppcp-always-shown-element' ), + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'sandbox_on' => array( 'title' => __( 'Sandbox', 'woocommerce-paypal-payments' ), + 'classes' => array( 'ppcp-onboarding-element', 'ppcp-always-shown-element' ), 'type' => 'checkbox', 'label' => __( 'To test your WooCommerce installation, you can use the sandbox mode.', 'woocommerce-paypal-payments' ), 'default' => 0, 'screens' => array( State::STATE_START, - State::STATE_PROGRESSIVE, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - - // Production credentials. - 'credentials_production_heading' => array( - 'heading' => __( 'API Credentials', 'woocommerce-paypal-payments' ), - 'type' => 'ppcp-heading', - 'screens' => array( - State::STATE_PROGRESSIVE, - State::STATE_ONBOARDED, - ), - 'requirements' => array(), - 'gateway' => 'paypal', - ), - 'ppcp_onboarding_production' => array( - 'title' => __( 'Connect to PayPal', 'woocommerce-paypal-payments' ), - 'type' => 'ppcp_onboarding', - 'screens' => array( - State::STATE_START, - State::STATE_PROGRESSIVE, - State::STATE_ONBOARDED, - ), - 'env' => 'production', - 'requirements' => array(), - 'gateway' => 'paypal', - 'description' => __( 'Setup or link an existing PayPal account.', 'woocommerce-paypal-payments' ), - ), - 'ppcp_disconnect_production' => array( - 'title' => __( 'Disconnect from PayPal', 'woocommerce-paypal-payments' ), - 'type' => 'ppcp-text', - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ), - 'text' => '', - 'screens' => array( - State::STATE_START, - State::STATE_PROGRESSIVE, - State::STATE_ONBOARDED, - ), - 'env' => 'production', - 'requirements' => array(), - 'gateway' => 'paypal', - 'description' => __( 'Click to reset current credentials and use another account.', 'woocommerce-paypal-payments' ), - ), - 'production_toggle_manual_input' => array( - 'type' => 'ppcp-text', - 'title' => __( 'Manual mode', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ), - 'text' => '', - 'screens' => array( - State::STATE_START, - State::STATE_PROGRESSIVE, - State::STATE_ONBOARDED, - ), - 'requirements' => array(), - 'gateway' => 'paypal', - ), - 'merchant_email_production' => array( + 'merchant_email_production' => array( 'title' => __( 'Live Email address', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'text', 'required' => true, 'desc_tip' => true, @@ -333,115 +463,57 @@ return array( 'default' => '', 'screens' => array( State::STATE_START, - State::STATE_PROGRESSIVE, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'merchant_id_production' => array( + 'merchant_id_production' => array( 'title' => __( 'Live Merchant Id', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-text-input', 'desc_tip' => true, 'description' => __( 'The merchant id of your account ', 'woocommerce-paypal-payments' ), 'default' => false, 'screens' => array( State::STATE_START, - State::STATE_PROGRESSIVE, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'client_id_production' => array( + 'client_id_production' => array( 'title' => __( 'Live Client Id', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-text-input', 'desc_tip' => true, 'description' => __( 'The client id of your api ', 'woocommerce-paypal-payments' ), 'default' => false, 'screens' => array( State::STATE_START, - State::STATE_PROGRESSIVE, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'client_secret_production' => array( + 'client_secret_production' => array( 'title' => __( 'Live Secret Key', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-password', 'desc_tip' => true, 'description' => __( 'The secret key of your api', 'woocommerce-paypal-payments' ), 'default' => false, 'screens' => array( State::STATE_START, - State::STATE_PROGRESSIVE, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - // Sandbox credentials. - 'credentials_sandbox_heading' => array( - 'heading' => __( 'Sandbox API Credentials', 'woocommerce-paypal-payments' ), - 'type' => 'ppcp-heading', - 'screens' => array( - State::STATE_PROGRESSIVE, - State::STATE_ONBOARDED, - ), - 'requirements' => array(), - 'gateway' => 'paypal', - 'description' => __( 'Your account setting is set to sandbox, no real charging takes place. To accept live payments, switch your environment to live and connect your PayPal account.', 'woocommerce-paypal-payments' ), - ), - - 'ppcp_onboarding_sandbox' => array( - 'title' => __( 'Connect to PayPal', 'woocommerce-paypal-payments' ), - 'type' => 'ppcp_onboarding', - 'screens' => array( - State::STATE_START, - State::STATE_PROGRESSIVE, - State::STATE_ONBOARDED, - ), - 'env' => 'sandbox', - 'requirements' => array(), - 'gateway' => 'paypal', - 'description' => __( 'Setup or link an existing PayPal Sandbox account.', 'woocommerce-paypal-payments' ), - ), - 'ppcp_disconnect_sandbox' => array( - 'title' => __( 'Disconnect from PayPal Sandbox', 'woocommerce-paypal-payments' ), - 'type' => 'ppcp-text', - 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), - 'text' => '', - 'screens' => array( - State::STATE_START, - State::STATE_PROGRESSIVE, - State::STATE_ONBOARDED, - ), - 'env' => 'production', - 'requirements' => array(), - 'gateway' => 'paypal', - 'description' => __( 'Click to reset current credentials and use another account.', 'woocommerce-paypal-payments' ), - ), - 'sandbox_toggle_manual_input' => array( - 'type' => 'ppcp-text', - 'title' => __( 'Manual mode', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), - 'text' => '', - 'screens' => array( - State::STATE_START, - State::STATE_PROGRESSIVE, - State::STATE_ONBOARDED, - ), - 'requirements' => array(), - 'gateway' => 'paypal', - ), - 'merchant_email_sandbox' => array( + 'merchant_email_sandbox' => array( 'title' => __( 'Sandbox Email address', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'text', 'required' => true, 'desc_tip' => true, @@ -449,69 +521,65 @@ return array( 'default' => '', 'screens' => array( State::STATE_START, - State::STATE_PROGRESSIVE, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'merchant_id_sandbox' => array( + 'merchant_id_sandbox' => array( 'title' => __( 'Sandbox Merchant Id', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-text-input', 'desc_tip' => true, 'description' => __( 'The merchant id of your account ', 'woocommerce-paypal-payments' ), 'default' => false, 'screens' => array( State::STATE_START, - State::STATE_PROGRESSIVE, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'client_id_sandbox' => array( + 'client_id_sandbox' => array( 'title' => __( 'Sandbox Client Id', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-text-input', 'desc_tip' => true, 'description' => __( 'The client id of your api ', 'woocommerce-paypal-payments' ), 'default' => false, 'screens' => array( State::STATE_START, - State::STATE_PROGRESSIVE, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'client_secret_sandbox' => array( + 'client_secret_sandbox' => array( 'title' => __( 'Sandbox Secret Key', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-password', 'desc_tip' => true, 'description' => __( 'The secret key of your api', 'woocommerce-paypal-payments' ), 'default' => false, 'screens' => array( State::STATE_START, - State::STATE_PROGRESSIVE, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'checkout_settings_heading' => array( + 'checkout_settings_heading' => array( 'heading' => __( 'PayPal Checkout Settings', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'title' => array( + 'title' => array( 'title' => __( 'Title', 'woocommerce-paypal-payments' ), 'type' => 'text', 'description' => __( @@ -521,13 +589,13 @@ return array( 'default' => __( 'PayPal', 'woocommerce-paypal-payments' ), 'desc_tip' => true, 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'dcc_enabled' => array( + 'dcc_enabled' => array( 'title' => __( 'Enable/Disable', 'woocommerce-paypal-payments' ), 'desc_tip' => true, 'description' => __( 'Once enabled, the Credit Card option will show up in the checkout.', 'woocommerce-paypal-payments' ), @@ -542,7 +610,7 @@ return array( State::STATE_ONBOARDED, ), ), - 'dcc_gateway_title' => array( + 'dcc_gateway_title' => array( 'title' => __( 'Title', 'woocommerce-paypal-payments' ), 'type' => 'text', 'description' => __( @@ -559,7 +627,7 @@ return array( ), 'gateway' => 'dcc', ), - 'description' => array( + 'description' => array( 'title' => __( 'Description', 'woocommerce-paypal-payments' ), 'type' => 'text', 'desc_tip' => true, @@ -572,13 +640,13 @@ return array( 'woocommerce-paypal-payments' ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'intent' => array( + 'intent' => array( 'title' => __( 'Intent', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -594,12 +662,13 @@ return array( 'authorize' => __( 'Authorize', 'woocommerce-paypal-payments' ), ), 'screens' => array( + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'capture_for_virtual_only' => array( + 'capture_for_virtual_only' => array( 'title' => __( 'Capture Virtual-Only Orders ', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'default' => false, @@ -610,12 +679,13 @@ return array( ), 'label' => __( 'Capture Virtual-Only Orders', 'woocommerce-paypal-payments' ), 'screens' => array( + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'payee_preferred' => array( + 'payee_preferred' => array( 'title' => __( 'Instant Payments ', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'default' => false, @@ -626,13 +696,13 @@ return array( ), 'label' => __( 'Require Instant Payment', 'woocommerce-paypal-payments' ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'brand_name' => array( + 'brand_name' => array( 'title' => __( 'Brand Name', 'woocommerce-paypal-payments' ), 'type' => 'text', 'default' => get_bloginfo( 'name' ), @@ -642,13 +712,13 @@ return array( 'woocommerce-paypal-payments' ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'landing_page' => array( + 'landing_page' => array( 'title' => __( 'Landing Page', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -664,13 +734,13 @@ return array( ApplicationContext::LANDING_PAGE_BILLING => __( 'Billing (Non-PayPal account)', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'disable_funding' => array( + 'disable_funding' => array( 'title' => __( 'Hide Funding Source(s)', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-multiselect', 'class' => array(), @@ -678,7 +748,7 @@ return array( 'default' => array(), 'desc_tip' => false, 'description' => sprintf( - // translators: %1$s and %2$s are the opening and closing of HTML
    tag. + // translators: %1$s and %2$s are the opening and closing of HTML tag. __( 'By default, all possible funding sources will be shown. This setting can disable funding sources such as Credit Cards, Pay Later, Venmo, or other %1$sAlternative Payment Methods%2$s.', 'woocommerce-paypal-payments' ), ' _x( 'Venmo', 'Name of payment method', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'vault_enabled' => array( + 'vault_enabled' => array( 'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'desc_tip' => true, @@ -729,7 +799,7 @@ return array( 'requirements' => array(), 'gateway' => array( 'paypal', 'dcc' ), ), - 'logging_enabled' => array( + 'logging_enabled' => array( 'title' => __( 'Logging', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'desc_tip' => true, @@ -738,13 +808,13 @@ return array( 'description' => __( 'Enable logging of unexpected behavior. This can also log private data and should only be enabled in a development or stage environment.', 'woocommerce-paypal-payments' ), 'default' => false, 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'prefix' => array( + 'prefix' => array( 'title' => __( 'Invoice prefix', 'woocommerce-paypal-payments' ), 'type' => 'text', 'desc_tip' => true, @@ -760,7 +830,7 @@ return array( return substr( $letters, 0, 6 ) . '-'; } )(), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), @@ -768,30 +838,30 @@ return array( ), // General button styles. - 'button_style_heading' => array( + 'button_style_heading' => array( 'heading' => __( 'Checkout', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', 'description' => __( 'Customize the appearance of PayPal Checkout on the checkout page.', 'woocommerce-paypal-payments' ), ), - 'button_enabled' => array( + 'button_enabled' => array( 'title' => __( 'Enable buttons on Checkout', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'label' => __( 'Enable on Checkout', 'woocommerce-paypal-payments' ), 'default' => true, 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_layout' => array( + 'button_layout' => array( 'title' => __( 'Button Layout', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -807,13 +877,13 @@ return array( 'horizontal' => __( 'Horizontal', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_tagline' => array( + 'button_tagline' => array( 'title' => __( 'Tagline', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'default' => true, @@ -824,17 +894,20 @@ return array( 'woocommerce-paypal-payments' ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_label' => array( + 'button_label' => array( 'title' => __( 'Button Label', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), 'input_class' => array( 'wc-enhanced-select' ), + /** + * Returns default label ID of the PayPal button. + */ 'default' => apply_filters( 'woocommerce_paypal_payments_button_label_default', 'paypal' ), 'desc_tip' => true, 'description' => __( @@ -848,13 +921,13 @@ return array( 'pay' => __( 'Pay with PayPal', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_color' => array( + 'button_color' => array( 'title' => __( 'Color', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -872,13 +945,13 @@ return array( 'black' => __( 'Black', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_shape' => array( + 'button_shape' => array( 'title' => __( 'Shape', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -894,17 +967,17 @@ return array( 'rect' => __( 'Rectangle', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'message_heading' => array( + 'message_heading' => array( 'heading' => __( 'Pay Later on Checkout', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), @@ -912,19 +985,19 @@ return array( 'description' => str_replace( '', '', __( 'Displays Pay Later messaging for available offers. Restrictions apply. Click here to learn more. Pay Later button will show for eligible buyers and PayPal determines eligibility.', 'woocommerce-paypal-payments' ) ), 'class' => array( 'ppcp-subheading' ), ), - 'message_enabled' => array( + 'message_enabled' => array( 'title' => __( 'Enable message on Checkout', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'label' => __( 'Enable on Checkout', 'woocommerce-paypal-payments' ), 'default' => true, 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_layout' => array( + 'message_layout' => array( 'title' => __( 'Pay Later Messaging layout', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -940,13 +1013,13 @@ return array( 'flex' => __( 'Flex', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_logo' => array( + 'message_logo' => array( 'title' => __( 'Pay Later Messaging logo', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -964,13 +1037,13 @@ return array( 'none' => __( 'None', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_position' => array( + 'message_position' => array( 'title' => __( 'Pay Later Messaging logo position', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -987,13 +1060,13 @@ return array( 'top' => __( 'Top', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_color' => array( + 'message_color' => array( 'title' => __( 'Pay Later Messaging text color', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1011,13 +1084,13 @@ return array( 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_flex_color' => array( + 'message_flex_color' => array( 'title' => __( 'Pay Later Messaging color', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1038,13 +1111,13 @@ return array( 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_flex_ratio' => array( + 'message_flex_ratio' => array( 'title' => __( 'Pay Later Messaging ratio', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1062,7 +1135,7 @@ return array( '20x1' => __( '20x1', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), @@ -1070,30 +1143,30 @@ return array( ), // Single product page. - 'button_product_heading' => array( + 'button_product_heading' => array( 'heading' => __( 'Single Product Page', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', 'description' => __( 'Customize the appearance of PayPal Checkout on the single product page.', 'woocommerce-paypal-payments' ), ), - 'button_product_enabled' => array( + 'button_product_enabled' => array( 'title' => __( 'Enable buttons on Single Product', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'label' => __( 'Enable on Single Product', 'woocommerce-paypal-payments' ), 'default' => true, 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_product_layout' => array( + 'button_product_layout' => array( 'title' => __( 'Button Layout', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1109,13 +1182,13 @@ return array( 'horizontal' => __( 'Horizontal', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_product_tagline' => array( + 'button_product_tagline' => array( 'title' => __( 'Tagline', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'label' => __( 'Enable tagline', 'woocommerce-paypal-payments' ), @@ -1126,17 +1199,20 @@ return array( 'woocommerce-paypal-payments' ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_product_label' => array( + 'button_product_label' => array( 'title' => __( 'Button Label', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), 'input_class' => array( 'wc-enhanced-select' ), + /** + * Returns default label ID of the PayPal button on product pages. + */ 'default' => apply_filters( 'woocommerce_paypal_payments_button_product_label_default', 'paypal' ), 'desc_tip' => true, 'description' => __( @@ -1150,13 +1226,13 @@ return array( 'pay' => __( 'Pay with PayPal', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_product_color' => array( + 'button_product_color' => array( 'title' => __( 'Color', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1174,13 +1250,13 @@ return array( 'black' => __( 'Black', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_product_shape' => array( + 'button_product_shape' => array( 'title' => __( 'Shape', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1196,18 +1272,18 @@ return array( 'rect' => __( 'Rectangle', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'message_product_heading' => array( + 'message_product_heading' => array( 'heading' => __( 'Pay Later on Single Product Page', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), @@ -1215,19 +1291,19 @@ return array( 'description' => str_replace( '', '', __( 'Displays Pay Later messaging for available offers. Restrictions apply. Click here to learn more. Pay Later button will show for eligible buyers and PayPal determines eligibility.', 'woocommerce-paypal-payments' ) ), 'class' => array( 'ppcp-subheading' ), ), - 'message_product_enabled' => array( + 'message_product_enabled' => array( 'title' => __( 'Enable message on Single Product', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'label' => __( 'Enable on Single Product', 'woocommerce-paypal-payments' ), 'default' => true, 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_product_layout' => array( + 'message_product_layout' => array( 'title' => __( 'Pay Later Messaging layout', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1243,13 +1319,13 @@ return array( 'flex' => __( 'Flex', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_product_logo' => array( + 'message_product_logo' => array( 'title' => __( 'Pay Later Messaging logo', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1267,13 +1343,13 @@ return array( 'none' => __( 'None', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_product_position' => array( + 'message_product_position' => array( 'title' => __( 'Pay Later Messaging logo position', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1290,13 +1366,13 @@ return array( 'top' => __( 'Top', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_product_color' => array( + 'message_product_color' => array( 'title' => __( 'Pay Later Messaging text color', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1314,13 +1390,13 @@ return array( 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_product_flex_color' => array( + 'message_product_flex_color' => array( 'title' => __( 'Pay Later Messaging color', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1341,13 +1417,13 @@ return array( 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_product_flex_ratio' => array( + 'message_product_flex_ratio' => array( 'title' => __( 'Pay Later Messaging ratio', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1365,7 +1441,7 @@ return array( '20x1' => __( '20x1', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), @@ -1373,30 +1449,30 @@ return array( ), // Cart settings. - 'button_cart_heading' => array( + 'button_cart_heading' => array( 'heading' => __( 'Cart', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', 'description' => __( 'Customize the appearance of PayPal Checkout on the cart page.', 'woocommerce-paypal-payments' ), ), - 'button_cart_enabled' => array( + 'button_cart_enabled' => array( 'title' => __( 'Buttons on Cart', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'label' => __( 'Enable on Cart', 'woocommerce-paypal-payments' ), 'default' => true, 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_cart_layout' => array( + 'button_cart_layout' => array( 'title' => __( 'Button Layout', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1412,13 +1488,13 @@ return array( 'horizontal' => __( 'Horizontal', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_cart_tagline' => array( + 'button_cart_tagline' => array( 'title' => __( 'Tagline', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'label' => __( 'Enable tagline', 'woocommerce-paypal-payments' ), @@ -1429,17 +1505,20 @@ return array( 'woocommerce-paypal-payments' ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_cart_label' => array( + 'button_cart_label' => array( 'title' => __( 'Button Label', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), 'input_class' => array( 'wc-enhanced-select' ), + /** + * Returns default label ID of the PayPal button in cart. + */ 'default' => apply_filters( 'woocommerce_paypal_payments_button_cart_label_default', 'paypal' ), 'desc_tip' => true, 'description' => __( @@ -1453,13 +1532,13 @@ return array( 'pay' => __( 'Pay with PayPal', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_cart_color' => array( + 'button_cart_color' => array( 'title' => __( 'Color', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1477,13 +1556,13 @@ return array( 'black' => __( 'Black', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_cart_shape' => array( + 'button_cart_shape' => array( 'title' => __( 'Shape', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1499,18 +1578,18 @@ return array( 'rect' => __( 'Rectangle', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'message_cart_heading' => array( + 'message_cart_heading' => array( 'heading' => __( 'Pay Later on Cart', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), @@ -1518,19 +1597,19 @@ return array( 'description' => str_replace( '', '', __( 'Displays Pay Later messaging for available offers. Restrictions apply. Click here to learn more. Pay Later button will show for eligible buyers and PayPal determines eligibility.', 'woocommerce-paypal-payments' ) ), 'class' => array( 'ppcp-subheading' ), ), - 'message_cart_enabled' => array( + 'message_cart_enabled' => array( 'title' => __( 'Enable message on Cart', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'label' => __( 'Enable on Cart', 'woocommerce-paypal-payments' ), 'default' => true, 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_cart_layout' => array( + 'message_cart_layout' => array( 'title' => __( 'Pay Later Messaging layout', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1546,13 +1625,13 @@ return array( 'flex' => __( 'Flex', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_cart_logo' => array( + 'message_cart_logo' => array( 'title' => __( 'Pay Later Messaging logo', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1570,13 +1649,13 @@ return array( 'none' => __( 'None', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_cart_position' => array( + 'message_cart_position' => array( 'title' => __( 'Pay Later Messaging logo position', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1593,13 +1672,13 @@ return array( 'top' => __( 'Top', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_cart_color' => array( + 'message_cart_color' => array( 'title' => __( 'Pay Later Messaging text color', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1617,13 +1696,13 @@ return array( 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_cart_flex_color' => array( + 'message_cart_flex_color' => array( 'title' => __( 'Pay Later Messaging color', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1644,13 +1723,13 @@ return array( 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), 'gateway' => 'paypal', ), - 'message_cart_flex_ratio' => array( + 'message_cart_flex_ratio' => array( 'title' => __( 'Pay Later Messaging ratio', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1668,7 +1747,7 @@ return array( '20x1' => __( '20x1', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array( 'messages' ), @@ -1676,30 +1755,30 @@ return array( ), // Mini cart settings. - 'button_mini-cart_heading' => array( + 'button_mini-cart_heading' => array( 'heading' => __( 'Mini Cart', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', 'description' => __( 'Customize the appearance of PayPal Checkout on the Mini Cart.', 'woocommerce-paypal-payments' ), ), - 'button_mini-cart_enabled' => array( + 'button_mini-cart_enabled' => array( 'title' => __( 'Buttons on Mini Cart', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'label' => __( 'Enable on Mini Cart', 'woocommerce-paypal-payments' ), 'default' => true, 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_mini-cart_layout' => array( + 'button_mini-cart_layout' => array( 'title' => __( 'Button Layout', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1715,13 +1794,13 @@ return array( 'horizontal' => __( 'Horizontal', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_mini-cart_tagline' => array( + 'button_mini-cart_tagline' => array( 'title' => __( 'Tagline', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'label' => __( 'Enable tagline', 'woocommerce-paypal-payments' ), @@ -1732,17 +1811,20 @@ return array( 'woocommerce-paypal-payments' ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_mini-cart_label' => array( + 'button_mini-cart_label' => array( 'title' => __( 'Button Label', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), 'input_class' => array( 'wc-enhanced-select' ), + /** + * Returns default label ID of the PayPal button in mini cart. + */ 'default' => apply_filters( 'woocommerce_paypal_payments_button_mini_cart_label_default', 'paypal' ), 'desc_tip' => true, 'description' => __( @@ -1756,13 +1838,13 @@ return array( 'pay' => __( 'Pay with PayPal', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_mini-cart_color' => array( + 'button_mini-cart_color' => array( 'title' => __( 'Color', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1780,13 +1862,13 @@ return array( 'black' => __( 'Black', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_mini-cart_shape' => array( + 'button_mini-cart_shape' => array( 'title' => __( 'Shape', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -1802,27 +1884,27 @@ return array( 'rect' => __( 'Rectangle', 'woocommerce-paypal-payments' ), ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'button_mini-cart_height' => array( + 'button_mini-cart_height' => array( 'title' => __( 'Button Height', 'woocommerce-paypal-payments' ), 'type' => 'number', 'default' => '35', 'desc_tip' => true, 'description' => __( 'Add a value from 25 to 55.', 'woocommerce-paypal-payments' ), 'screens' => array( - State::STATE_PROGRESSIVE, + State::STATE_START, State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), - 'disable_cards' => array( + 'disable_cards' => array( 'title' => __( 'Disable specific credit cards', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-multiselect', 'class' => array(), @@ -1850,7 +1932,7 @@ return array( ), 'gateway' => 'dcc', ), - 'card_icons' => array( + 'card_icons' => array( 'title' => __( 'Show logo of the following credit cards', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-multiselect', 'class' => array(), @@ -1878,7 +1960,7 @@ return array( ), 'gateway' => 'dcc', ), - '3d_secure_heading' => array( + '3d_secure_heading' => array( 'heading' => __( '3D Secure', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'description' => wp_kses_post( @@ -1906,7 +1988,7 @@ return array( ), 'gateway' => 'dcc', ), - '3d_secure_contingency' => array( + '3d_secure_contingency' => array( 'title' => __( 'Contingency for 3D Secure', 'woocommerce-paypal-payments' ), 'type' => 'select', 'description' => sprintf( @@ -1939,26 +2021,10 @@ return array( unset( $fields['vault_enabled'] ); } - if ( State::STATE_ONBOARDED === $state->production_state() ) { - unset( $fields['ppcp_onboarding_production'] ); - } else { - unset( $fields['ppcp_disconnect_production'] ); - } - if ( State::STATE_ONBOARDED === $state->sandbox_state() ) { - unset( $fields['ppcp_onboarding_sandbox'] ); - } else { - unset( $fields['ppcp_disconnect_sandbox'] ); - } - /** * Depending on your store location, some credit cards can't be used. * Here, we filter them out. - * - * The DCC Applies object. - * - * @var DccApplies $dcc_applies */ - $dcc_applies = $container->get( 'api.helpers.dccapplies' ); $card_options = $fields['disable_cards']['options']; foreach ( $card_options as $card => $label ) { if ( $dcc_applies->can_process_card( $card ) ) { diff --git a/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php b/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php index fd89636ad..d2c031622 100644 --- a/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php +++ b/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php @@ -25,11 +25,11 @@ class SettingsPageAssets { private $module_url; /** - * The filesystem path to the module dir. + * The assets version. * * @var string */ - private $module_path; + private $version; /** * The bearer. @@ -42,13 +42,13 @@ class SettingsPageAssets { * Assets constructor. * * @param string $module_url The url of this module. - * @param string $module_path The filesystem path to this module. + * @param string $version The assets version. * @param Bearer $bearer The bearer. */ - public function __construct( string $module_url, string $module_path, Bearer $bearer ) { - $this->module_url = $module_url; - $this->module_path = $module_path; - $this->bearer = $bearer; + public function __construct( string $module_url, string $version, Bearer $bearer ) { + $this->module_url = $module_url; + $this->version = $version; + $this->bearer = $bearer; } /** @@ -102,13 +102,11 @@ class SettingsPageAssets { * @param Bearer $bearer The bearer. */ private function register_admin_assets( Bearer $bearer ) { - $gateway_settings_script_path = trailingslashit( $this->module_path ) . 'assets/js/gateway-settings.js'; - wp_enqueue_script( 'ppcp-gateway-settings', trailingslashit( $this->module_url ) . 'assets/js/gateway-settings.js', array(), - file_exists( $gateway_settings_script_path ) ? (string) filemtime( $gateway_settings_script_path ) : null, + $this->version, true ); diff --git a/modules/ppcp-wc-gateway/src/Notice/ConnectAdminNotice.php b/modules/ppcp-wc-gateway/src/Notice/ConnectAdminNotice.php index 25b880d74..319f2c844 100644 --- a/modules/ppcp-wc-gateway/src/Notice/ConnectAdminNotice.php +++ b/modules/ppcp-wc-gateway/src/Notice/ConnectAdminNotice.php @@ -71,6 +71,6 @@ class ConnectAdminNotice { * @return bool */ protected function should_display(): bool { - return $this->state->current_state() < State::STATE_PROGRESSIVE; + return $this->state->current_state() !== State::STATE_ONBOARDED; } } diff --git a/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php b/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php index ba2f4b08c..6ddf945d4 100644 --- a/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php +++ b/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php @@ -146,8 +146,14 @@ class SettingsListener { } $this->settings->persist(); + /** + * The hook fired before performing the redirect at the end of onboarding after saving the merchant ID/email. + */ do_action( 'woocommerce_paypal_payments_onboarding_before_redirect' ); + /** + * The URL opened at the end of onboarding after saving the merchant ID/email. + */ $redirect_url = apply_filters( 'woocommerce_paypal_payments_onboarding_redirect_url', admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' ) ); if ( ! $this->settings->has( 'client_id' ) || ! $this->settings->get( 'client_id' ) ) { $redirect_url = add_query_arg( 'ppcp-onboarding-error', '1', $redirect_url ); diff --git a/modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php b/modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php index 39c6c8390..3deef7f48 100644 --- a/modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php +++ b/modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php @@ -377,8 +377,18 @@ $data_rows_html ?> + + + + + fields as $field => $config ) : - if ( ! in_array( $this->state->current_state(), $config['screens'], true ) ) { + if ( ! in_array( $this->state->environment_state( $config['state_from'] ?? null ), $config['screens'], true ) ) { continue; } if ( ! $this->field_matches_page( $config, $this->page_id ) ) { @@ -406,14 +416,18 @@ $data_rows_html $key = 'ppcp[' . $field . ']'; $id = 'ppcp-' . $field; $config['id'] = $id; - $colspan = 'ppcp-heading' !== $config['type'] ? 1 : 2; + $colspan = ( 'ppcp-heading' !== $config['type'] && isset( $config['title'] ) ) ? 1 : 2; $classes = isset( $config['classes'] ) ? $config['classes'] : array(); + $classes[] = 'ppcp-settings-field'; $classes[] = sprintf( 'ppcp-settings-field-%s', str_replace( 'ppcp-', '', $config['type'] ) ); - $description = isset( $config['description'] ) ? $config['description'] : ''; + if ( 1 !== $colspan ) { + $classes[] = 'ppcp-settings-no-title-col'; + } + $description = isset( $config['description'] ) ? $config['description'] : ''; unset( $config['description'] ); ?> - +