From a2821498ea4ba3c9c24a1db0b6dcee959d294bd9 Mon Sep 17 00:00:00 2001 From: carmenmaymo Date: Mon, 4 Nov 2024 14:16:38 +0100 Subject: [PATCH 1/7] Squash and merge PIWOO-289 This PR adds the new settings UI --- inc/settings/mollie_advanced_settings.php | 207 ----- inc/settings/mollie_applepay_settings.php | 122 --- inc/settings/mollie_components.php | 170 ---- phpcs.xml.dist | 2 +- public/images/logo/black.svg | 18 + resources/js/mollie-settings-2024.js | 11 + resources/js/settings.js | 11 - src/Activation/ActivationModule.php | 3 +- src/Assets/AssetsModule.php | 25 +- src/Gateway/GatewayModule.php | 1 + src/PaymentMethods/Alma.php | 1 + src/PaymentMethods/Applepay.php | 1 + src/PaymentMethods/Bancomatpay.php | 1 + src/PaymentMethods/Bancontact.php | 1 + src/PaymentMethods/Banktransfer.php | 1 + src/PaymentMethods/Belfius.php | 1 + src/PaymentMethods/Billie.php | 1 + src/PaymentMethods/Blik.php | 1 + src/PaymentMethods/Creditcard.php | 1 + src/PaymentMethods/Directdebit.php | 1 + src/PaymentMethods/Eps.php | 1 + src/PaymentMethods/Giftcard.php | 1 + src/PaymentMethods/Giropay.php | 1 + src/PaymentMethods/Ideal.php | 1 + src/PaymentMethods/In3.php | 1 + src/PaymentMethods/Kbc.php | 1 + src/PaymentMethods/Klarna.php | 1 + src/PaymentMethods/Klarnapaylater.php | 1 + src/PaymentMethods/Klarnapaynow.php | 1 + src/PaymentMethods/Klarnasliceit.php | 1 + src/PaymentMethods/Mybank.php | 1 + src/PaymentMethods/Payconiq.php | 1 + src/PaymentMethods/PaymentMethodsIconUrl.php | 2 +- src/PaymentMethods/Paypal.php | 1 + src/PaymentMethods/Paysafecard.php | 1 + src/PaymentMethods/Przelewy24.php | 1 + src/PaymentMethods/Riverty.php | 1 + src/PaymentMethods/Satispay.php | 1 + src/PaymentMethods/Sofort.php | 1 + src/PaymentMethods/Trustly.php | 1 + src/PaymentMethods/Twint.php | 1 + src/PaymentMethods/Voucher.php | 1 + src/Settings/MollieSettingsPage.php | 266 ++++++ src/Settings/Page/AbstractPage.php | 90 ++ src/Settings/Page/Components.php | 68 -- src/Settings/Page/MollieSettingsPage.php | 789 ------------------ src/Settings/Page/PageAdvancedSettings.php | 39 + src/Settings/Page/PageApiKeys.php | 41 + src/Settings/Page/PageNoApiKey.php | 33 + src/Settings/Page/PagePaymentMethods.php | 40 + src/Settings/Page/Section/AbstractSection.php | 56 ++ src/Settings/Page/Section/Advanced.php | 248 ++++++ .../Page/Section/ConnectionFields.php | 80 ++ .../Page/Section/ConnectionStatusFields.php | 46 + .../Page/Section/ConnectionStatusTrait.php | 36 + src/Settings/Page/Section/Header.php | 84 ++ .../Page/Section/InstructionsConnected.php | 52 ++ .../Page/Section/InstructionsNotConnected.php | 90 ++ src/Settings/Page/Section/Notices.php | 190 +++++ src/Settings/Page/Section/PaymentMethods.php | 261 ++++++ src/Settings/Page/Section/Tabs.php | 45 + src/Settings/Settings.php | 24 +- src/Settings/SettingsModule.php | 19 +- webpack.config.js | 3 +- 64 files changed, 1822 insertions(+), 1381 deletions(-) delete mode 100644 inc/settings/mollie_advanced_settings.php delete mode 100644 inc/settings/mollie_applepay_settings.php delete mode 100644 inc/settings/mollie_components.php create mode 100644 public/images/logo/black.svg create mode 100644 resources/js/mollie-settings-2024.js create mode 100644 src/Settings/MollieSettingsPage.php create mode 100644 src/Settings/Page/AbstractPage.php delete mode 100644 src/Settings/Page/Components.php delete mode 100644 src/Settings/Page/MollieSettingsPage.php create mode 100644 src/Settings/Page/PageAdvancedSettings.php create mode 100644 src/Settings/Page/PageApiKeys.php create mode 100644 src/Settings/Page/PageNoApiKey.php create mode 100644 src/Settings/Page/PagePaymentMethods.php create mode 100644 src/Settings/Page/Section/AbstractSection.php create mode 100644 src/Settings/Page/Section/Advanced.php create mode 100644 src/Settings/Page/Section/ConnectionFields.php create mode 100644 src/Settings/Page/Section/ConnectionStatusFields.php create mode 100644 src/Settings/Page/Section/ConnectionStatusTrait.php create mode 100644 src/Settings/Page/Section/Header.php create mode 100644 src/Settings/Page/Section/InstructionsConnected.php create mode 100644 src/Settings/Page/Section/InstructionsNotConnected.php create mode 100644 src/Settings/Page/Section/Notices.php create mode 100644 src/Settings/Page/Section/PaymentMethods.php create mode 100644 src/Settings/Page/Section/Tabs.php diff --git a/inc/settings/mollie_advanced_settings.php b/inc/settings/mollie_advanced_settings.php deleted file mode 100644 index e108e62d9..000000000 --- a/inc/settings/mollie_advanced_settings.php +++ /dev/null @@ -1,207 +0,0 @@ - 1, 'nonce_mollie_cleanDb' => $nonce_mollie_cleanDb] -); -$api_payment_description_labels = [ - '{orderNumber}' => _x('Order number', 'Label {orderNumber} description for payment description options', 'mollie-payments-for-woocommerce'), - '{storeName}' => _x('Site Title', 'Label {storeName} description for payment description options', 'mollie-payments-for-woocommerce'), - '{customer.firstname}' => _x('Customer\'s first name', 'Label {customer.firstname} description for payment description options', 'mollie-payments-for-woocommerce'), - '{customer.lastname}' => _x('Customer\'s last name', 'Label {customer.lastname} description for payment description options', 'mollie-payments-for-woocommerce'), - '{customer.company}' => _x('Customer\'s company name', 'Label {customer.company} description for payment description options', 'mollie-payments-for-woocommerce'), -]; - -$mollieAdvancedSettings = [ - [ - 'id' => $pluginName . '_title', - 'title' => __('Mollie advanced settings', 'mollie-payments-for-woocommerce'), - 'type' => 'title', - 'desc' => '

' . __('The following options are required to use the plugin and are used by all Mollie payment methods', 'mollie-payments-for-woocommerce') . '

', - ], - [ - 'id' => $pluginName . '_order_status_cancelled_payments', - 'title' => __('Order status after cancelled payment', 'mollie-payments-for-woocommerce'), - 'type' => 'select', - 'options' => [ - 'pending' => __('Pending', 'woocommerce'), - 'cancelled' => __('Cancelled', 'woocommerce'), - ], - 'desc' => __('Status for orders when a payment (not a Mollie order via the Orders API) is cancelled. Default: pending. Orders with status Pending can be paid with another payment method, customers can try again. Cancelled orders are final. Set this to Cancelled if you only have one payment method or don\'t want customers to re-try paying with a different payment method. This doesn\'t apply to payments for orders via the new Orders API and Klarna payments.', 'mollie-payments-for-woocommerce'), - 'default' => 'pending', - ], - [ - 'id' => $pluginName . '_' . SharedDataDictionary::SETTING_NAME_PAYMENT_LOCALE, - 'title' => __('Payment screen language', 'mollie-payments-for-woocommerce'), - 'type' => 'select', - 'options' => [ - SharedDataDictionary::SETTING_LOCALE_WP_LANGUAGE => __( - 'Automatically send WordPress language', - 'mollie-payments-for-woocommerce' - ) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', - SharedDataDictionary::SETTING_LOCALE_DETECT_BY_BROWSER => __( - 'Detect using browser language', - 'mollie-payments-for-woocommerce' - ), - 'en_US' => __('English', 'mollie-payments-for-woocommerce'), - 'nl_NL' => __('Dutch', 'mollie-payments-for-woocommerce'), - 'nl_BE' => __('Flemish (Belgium)', 'mollie-payments-for-woocommerce'), - 'fr_FR' => __('French', 'mollie-payments-for-woocommerce'), - 'fr_BE' => __('French (Belgium)', 'mollie-payments-for-woocommerce'), - 'de_DE' => __('German', 'mollie-payments-for-woocommerce'), - 'de_AT' => __('Austrian German', 'mollie-payments-for-woocommerce'), - 'de_CH' => __('Swiss German', 'mollie-payments-for-woocommerce'), - 'es_ES' => __('Spanish', 'mollie-payments-for-woocommerce'), - 'ca_ES' => __('Catalan', 'mollie-payments-for-woocommerce'), - 'pt_PT' => __('Portuguese', 'mollie-payments-for-woocommerce'), - 'it_IT' => __('Italian', 'mollie-payments-for-woocommerce'), - 'nb_NO' => __('Norwegian', 'mollie-payments-for-woocommerce'), - 'sv_SE' => __('Swedish', 'mollie-payments-for-woocommerce'), - 'fi_FI' => __('Finnish', 'mollie-payments-for-woocommerce'), - 'da_DK' => __('Danish', 'mollie-payments-for-woocommerce'), - 'is_IS' => __('Icelandic', 'mollie-payments-for-woocommerce'), - 'hu_HU' => __('Hungarian', 'mollie-payments-for-woocommerce'), - 'pl_PL' => __('Polish', 'mollie-payments-for-woocommerce'), - 'lv_LV' => __('Latvian', 'mollie-payments-for-woocommerce'), - 'lt_LT' => __('Lithuanian', 'mollie-payments-for-woocommerce'), - ], - 'desc' => sprintf( - /* translators: Placeholder 1: link tag Placeholder 2: closing tag */ - __('Sending a language (or locale) is required. The option \'Automatically send WordPress language\' will try to get the customer\'s language in WordPress (and respects multilanguage plugins) and convert it to a format Mollie understands. If this fails, or if the language is not supported, it will fall back to American English. You can also select one of the locales currently supported by Mollie, that will then be used for all customers.', 'mollie-payments-for-woocommerce'), - '', - '' - ), - 'default' => SharedDataDictionary::SETTING_LOCALE_WP_LANGUAGE, - ], - [ - 'id' => $pluginName . '_customer_details', - 'title' => __('Store customer details at Mollie', 'mollie-payments-for-woocommerce'), - 'desc' => sprintf( - /* translators: Placeholder 1: enabled or disabled Placeholder 2: translated string */ - __( - 'Should Mollie store customers name and email address for Single Click Payments? Default %1$s. Required if WooCommerce Subscriptions is being used! Read more about %2$s and how it improves your conversion.', - 'mollie-payments-for-woocommerce' - ), - strtolower(__('Enabled', 'mollie-payments-for-woocommerce')), - __('Single Click Payments', 'mollie-payments-for-woocommerce') - ), - 'type' => 'checkbox', - 'default' => 'yes', - - ], - [ - 'id' => $pluginName . '_api_switch', - 'title' => __( - 'Select API Method', - 'mollie-payments-for-woocommerce' - ), - 'type' => 'select', - 'options' => [ - PaymentService::PAYMENT_METHOD_TYPE_ORDER => ucfirst( - PaymentService::PAYMENT_METHOD_TYPE_ORDER - ) . ' (' . __('default', 'mollie-payments-for-woocommerce') - . ')', - PaymentService::PAYMENT_METHOD_TYPE_PAYMENT => ucfirst( - PaymentService::PAYMENT_METHOD_TYPE_PAYMENT - ), - ], - 'default' => PaymentService::PAYMENT_METHOD_TYPE_ORDER, - 'desc' => sprintf( - /* translators: Placeholder 1: opening link tag, placeholder 2: closing link tag */ - __( - 'Click %1$shere%2$s to read more about the differences between the Payments and Orders API', - 'mollie-payments-for-woocommerce' - ), - '', - '' - ), - ], - [ - 'id' => $pluginName . '_api_payment_description', - 'title' => __( - 'API Payment Description', - 'mollie-payments-for-woocommerce' - ), - 'type' => 'text', - 'default' => '{orderNumber}', - 'desc' => sprintf( - '

-
-

%1$s:

- -
-
-

%3$s', - _x('Available variables', 'Payment description options', 'mollie-payments-for-woocommerce'), - implode('', array_map( - static function ($label, $label_description) { - return sprintf( - '

  • - -
  • ', - $label, - substr($label, 1, -1), - $label_description - ); - }, - array_keys($api_payment_description_labels), - $api_payment_description_labels - )), - sprintf( - /* translators: Placeholder 1: Opening paragraph tag, placeholder 2: Closing paragraph tag */ - __( - 'Select among the available variables the description to be used for this transaction.%1$s(Note: this only works when the method is set to Payments API)%2$s', - 'mollie-payments-for-woocommerce' - ), - '

    ', - '

    ' - ) - ), - ], - [ - 'id' => $pluginName . '_gatewayFeeLabel', - 'title' => __( - 'Surcharge gateway fee label', - 'mollie-payments-for-woocommerce' - ), - 'type' => 'text', - 'custom_attributes' => ['maxlength' => '30'], - 'default' => __('Gateway Fee', 'mollie-payments-for-woocommerce'), - 'desc' => __( - 'This is the label will appear in frontend when the surcharge applies', - 'mollie-payments-for-woocommerce' - ), - ], - [ - 'id' => $pluginName . '_removeOptionsAndTransients', - 'title' => __( - 'Remove Mollie data from Database on uninstall', - 'mollie-payments-for-woocommerce' - ), - 'type' => 'checkbox', - 'default' => 'no', - 'desc' => __("Remove options and scheduled actions from database when uninstalling the plugin.", "mollie-payments-for-woocommerce") . ' (' . strtolower( - __('Clear now', 'mollie-payments-for-woocommerce') - ) . ')', - ], - [ - 'id' => $pluginName . '_sectionend', - 'type' => 'sectionend', - ], -]; - -return apply_filters('inpsyde.mollie-advanced-settings', $mollieAdvancedSettings, $pluginName); diff --git a/inc/settings/mollie_applepay_settings.php b/inc/settings/mollie_applepay_settings.php deleted file mode 100644 index 2ef1c3fa0..000000000 --- a/inc/settings/mollie_applepay_settings.php +++ /dev/null @@ -1,122 +0,0 @@ - $title . '_' . 'title', - 'title' => __('Apple Pay', 'mollie-payments-for-woocommerce'), - 'type' => 'title', - 'desc' => '

    ' . __('The following options are required to use the Apple Pay gateway', 'mollie-payments-for-woocommerce') . '

    ', - ], - - [ - 'id' => 'enabled', - 'title' => __('Enable/Disable', 'mollie-payments-for-woocommerce'), - /* translators: Placeholder 1: Gateway title */ - 'desc' => sprintf(__('Enable %s', 'mollie-payments-for-woocommerce'), $title), - 'type' => 'checkbox', - 'default' => 'yes', - 'value' => isset($applePayOption['enabled']) ? $applePayOption['enabled'] : 'yes', - - ], - [ - 'id' => 'title', - 'title' => __('Title', 'mollie-payments-for-woocommerce'), - 'desc' => sprintf( - /* translators: Placeholder 1: Gateway title */ - __( - 'This controls the title which the user sees during checkout. Default %s', - 'mollie-payments-for-woocommerce' - ), - $title - ), - 'desc_tip' => true, - 'type' => 'text', - 'default' => $title, - 'value' => isset($applePayOption['title']) ? $applePayOption['title'] : $title, - - ], - [ - 'id' => 'display_logo', - 'title' => __('Display logo', 'mollie-payments-for-woocommerce'), - 'desc' => __( - 'Display logo', - 'mollie-payments-for-woocommerce' - ), - 'desc_tip' => true, - 'type' => 'checkbox', - 'default' => 'yes', - 'value' => isset($applePayOption['display_logo']) ? $applePayOption['display_logo'] : 'yes', - - ], - [ - 'id' => 'description', - 'title' => __('Description', 'mollie-payments-for-woocommerce'), - 'desc' => sprintf( - /* translators: Placeholder 1: Gateway description */ - __( - 'Payment method description that the customer will see on your checkout. Default %s', - 'mollie-payments-for-woocommerce' - ), - $description - ), - 'desc_tip' => true, - 'type' => 'text', - 'default' => $description, - 'value' => isset($applePayOption['description']) ? $applePayOption['description'] : $description, - ], - [ - 'id' => $pluginId . '_' . 'sectionend', - 'type' => 'sectionend', - ], - [ - 'id' => $title . '_' . 'title_button', - 'title' => __( - 'Apple Pay button settings', - 'mollie-payments-for-woocommerce' - ), - 'type' => 'title', - 'desc' => '

    ' . __('The following options are required to use the Apple Pay Direct Button', 'mollie-payments-for-woocommerce') . '

    ', - ], - [ - 'id' => 'mollie_apple_pay_button_enabled_cart', - 'title' => __('Enable Apple Pay Button on Cart page', 'mollie-payments-for-woocommerce'), - 'desc' => sprintf( - /* translators: Placeholder 1: enabled or disabled */ - __( - 'Enable the Apple Pay direct buy button on the Cart page', - 'mollie-payments-for-woocommerce' - ), - $description - ), - 'type' => 'checkbox', - 'default' => 'no', - 'value' => isset($applePayOption['mollie_apple_pay_button_enabled_cart']) ? $applePayOption['mollie_apple_pay_button_enabled_cart'] : 'no', - - ], - [ - 'id' => 'mollie_apple_pay_button_enabled_product', - 'title' => __('Enable Apple Pay Button on Product page', 'mollie-payments-for-woocommerce'), - 'desc' => sprintf( - /* translators: Placeholder 1: enabled or disabled */ - __( - 'Enable the Apple Pay direct buy button on the Product page', - 'mollie-payments-for-woocommerce' - ), - $description - ), - 'type' => 'checkbox', - 'default' => 'no', - 'value' => isset($applePayOption['mollie_apple_pay_button_enabled_product']) ? $applePayOption['mollie_apple_pay_button_enabled_product'] : 'no', - - ], - [ - 'id' => $pluginName . '_' . 'sectionend', - 'type' => 'sectionend', - ], -]; diff --git a/inc/settings/mollie_components.php b/inc/settings/mollie_components.php deleted file mode 100644 index ac81476d9..000000000 --- a/inc/settings/mollie_components.php +++ /dev/null @@ -1,170 +0,0 @@ - 'title', - 'id' => 'mollie_components_styles', - 'title' => _x( - 'Base Styles', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - ], - StylesPropertiesDictionary::BACKGROUND_COLOR => [ - 'type' => 'color', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::BACKGROUND_COLOR, - 'title' => _x('Background Color', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'default' => '#ffffff', - ], - StylesPropertiesDictionary::TEXT_COLOR => [ - 'type' => 'color', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::TEXT_COLOR, - 'title' => _x('Text Color', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'default' => '#000000', - ], - StylesPropertiesDictionary::INPUT_PLACEHOLDER => [ - 'type' => 'color', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::INPUT_PLACEHOLDER, - 'title' => _x('Placeholder Color', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'default' => '#cccccc', - ], - StylesPropertiesDictionary::FONT_SIZE => [ - 'type' => 'text', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::FONT_SIZE, - 'title' => _x('Font Size', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'desc_tip' => _x( - 'Defines the component font size. Allowed units: \'em\', \'px\', \'rem\'.', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - 'default' => '16px', - ], - StylesPropertiesDictionary::FONT_WEIGHT => [ - 'type' => 'select', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::FONT_WEIGHT, - 'title' => _x('Font Weight', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'default' => 'normal', - 'options' => [ - 'lighter' => _x('Lighter', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'normal' => _x('Regular', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'bolder' => _x('Bold', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - ], - ], - StylesPropertiesDictionary::LETTER_SPACING => [ - 'type' => 'number', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::LETTER_SPACING, - 'title' => _x('Letter Spacing', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'default' => '0', - ], - StylesPropertiesDictionary::LINE_HEIGHT => [ - 'type' => 'number', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::LINE_HEIGHT, - 'title' => _x('Line Height', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'default' => '1.2', - 'custom_attributes' => [ - 'step' => '.1', - ], - ], - StylesPropertiesDictionary::PADDING => [ - 'type' => 'text', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::PADDING, - 'title' => _x('Padding', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'desc_tip' => _x( - 'Add padding to the components. Allowed units include `16px 16px 16px 16px` and `em`, `px`, `rem`.', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - 'default' => '.63em', - ], - StylesPropertiesDictionary::TEXT_ALIGN => [ - 'type' => 'select', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::TEXT_ALIGN, - 'title' => _x('Align Text', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'default' => 'left', - 'options' => [ - 'left' => _x('Left', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'right' => _x('Right', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'center' => _x('Center', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'justify' => _x('Justify', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - ], - ], - StylesPropertiesDictionary::TEXT_TRANSFORM => [ - 'type' => 'select', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::TEXT_TRANSFORM, - 'title' => _x('Transform Text ', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'default' => 'none', - 'options' => [ - 'none' => _x( - 'None', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - 'capitalize' => _x( - 'Capitalize', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - 'uppercase' => _x( - 'Uppercase', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - 'lowercase' => _x( - 'Lowercase', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - 'full-width' => _x( - 'Full Width', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - 'full-size-kana' => _x( - 'Full Size Kana', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - ], - ], - [ - 'type' => 'sectionend', - 'id' => 'mollie_components_styles', - ], - [ - 'type' => 'title', - 'id' => 'mollie_components_invalid_styles', - 'title' => _x( - 'Invalid Status Styles', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - ], - StylesPropertiesDictionary::INVALID_TEXT_COLOR => [ - 'type' => 'color', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::INVALID_TEXT_COLOR, - 'title' => _x('Text Color', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'desc_tip' => _x( - 'Text Color for invalid input.', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - 'default' => '#000000', - ], - StylesPropertiesDictionary::INVALID_BACKGROUND_COLOR => [ - 'type' => 'color', - 'id' => 'mollie_components_' . StylesPropertiesDictionary::INVALID_BACKGROUND_COLOR, - 'title' => _x('Background Color', 'Mollie Components Settings', 'mollie-payments-for-woocommerce'), - 'desc_tip' => _x( - 'Background Color for invalid input.', - 'Mollie Components Settings', - 'mollie-payments-for-woocommerce' - ), - 'default' => '#FFF0F0', - ], - [ - 'type' => 'sectionend', - 'id' => 'mollie_components_invalid_styles', - ], -]; diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 3f6cd5194..33e29a680 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -7,7 +7,7 @@ ./src ./tests/ - + diff --git a/public/images/logo/black.svg b/public/images/logo/black.svg new file mode 100644 index 000000000..76e679294 --- /dev/null +++ b/public/images/logo/black.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/resources/js/mollie-settings-2024.js b/resources/js/mollie-settings-2024.js new file mode 100644 index 000000000..659f2f5d2 --- /dev/null +++ b/resources/js/mollie-settings-2024.js @@ -0,0 +1,11 @@ +document.addEventListener('DOMContentLoaded', function () { + const noticeCancelButtons = document.querySelectorAll('.mollie-notice button'); + if (noticeCancelButtons.length === 0) { + return; + } + noticeCancelButtons.forEach((button) => { + button.addEventListener('click', function(){ + button.parentNode.remove(); + }); + }) +}); diff --git a/resources/js/settings.js b/resources/js/settings.js index 0cd19c22a..54eb4515c 100644 --- a/resources/js/settings.js +++ b/resources/js/settings.js @@ -4,17 +4,6 @@ const {current_section = false} = mollieSettingsData jQuery(function($) { - $('#mollie-payments-for-woocommerce_test_mode_enabled').change(function() { - if ($(this).is(':checked')) - { - $('#mollie-payments-for-woocommerce_test_api_key').attr('required', true).closest('tr').show(); - } - else - { - $('#mollie-payments-for-woocommerce_test_api_key').removeAttr('required').closest('tr').hide(); - } - }).change(); - if(_.isEmpty(mollieSettingsData)){ return } diff --git a/src/Activation/ActivationModule.php b/src/Activation/ActivationModule.php index cfab7d182..5a92e7104 100644 --- a/src/Activation/ActivationModule.php +++ b/src/Activation/ActivationModule.php @@ -40,8 +40,9 @@ public function run(ContainerInterface $container): bool 'init', [$this, 'pluginInit'] ); + + add_action('admin_init', [$this, 'mollieWcNoticeApiKeyMissing']); $this->declareCompatibleWithHPOS(); - $this->mollieWcNoticeApiKeyMissing(); $this->appleValidationFileRewriteRules(); return true; } diff --git a/src/Assets/AssetsModule.php b/src/Assets/AssetsModule.php index eeb8cd882..b4312bad7 100644 --- a/src/Assets/AssetsModule.php +++ b/src/Assets/AssetsModule.php @@ -490,7 +490,7 @@ public function enqueueAdvancedSettingsJS($ar) if ( $current_screen->id !== 'woocommerce_page_wc-settings' || $current_tab !== 'mollie_settings' - || $current_section !== 'advanced' + || $current_section !== 'mollie_advanced' ) { return; } @@ -640,9 +640,32 @@ function () use ($container, $hasBlocksEnabled, $pluginVersion, $dataService, $p true ); + wp_register_script( + 'mollie_wc_settings_2024', + $this->getPluginUrl( + $pluginUrl, + '/public/js/mollie-settings-2024.min.js' + ), + ['underscore', 'jquery'], + $pluginVersion, + true + ); + $this->enqueueMollieSettings(); $this->enqueueIconSettings($current_section); } } ); } + + protected function enqueueMollieSettings() + { + + $uri = isset($_SERVER['REQUEST_URI']) ? wc_clean( + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + wp_unslash($_SERVER['REQUEST_URI']) + ) : ''; + if (is_string($uri) && strpos($uri, 'tab=mollie_settings')) { + wp_enqueue_script('mollie_wc_settings_2024'); + } + } } diff --git a/src/Gateway/GatewayModule.php b/src/Gateway/GatewayModule.php index 72cade0d9..b8987f101 100644 --- a/src/Gateway/GatewayModule.php +++ b/src/Gateway/GatewayModule.php @@ -707,6 +707,7 @@ public function buildPaymentMethod( Surcharge $surchargeService, array $apiMethod ) { + $transformedId = ucfirst($id); $paymentMethodClassName = 'Mollie\\WooCommerce\\PaymentMethods\\' . $transformedId; $paymentMethod = new $paymentMethodClassName( diff --git a/src/PaymentMethods/Alma.php b/src/PaymentMethods/Alma.php index 57ac08fa4..d127a9864 100644 --- a/src/PaymentMethods/Alma.php +++ b/src/PaymentMethods/Alma.php @@ -26,6 +26,7 @@ protected function getConfig(): array 'billingAddress', 'shippingAddress', ], + 'docs' => 'https://www.mollie.com/gb/payments/alma', ]; } diff --git a/src/PaymentMethods/Applepay.php b/src/PaymentMethods/Applepay.php index 63a32c9ab..b1ae1f9eb 100644 --- a/src/PaymentMethods/Applepay.php +++ b/src/PaymentMethods/Applepay.php @@ -24,6 +24,7 @@ protected function getConfig(): array 'confirmationDelayed' => false, 'SEPA' => false, 'Subscription' => true, + 'docs' => 'https://www.mollie.com/gb/payments/apple-pay', ]; } diff --git a/src/PaymentMethods/Bancomatpay.php b/src/PaymentMethods/Bancomatpay.php index 054ef951d..7f9600fa1 100644 --- a/src/PaymentMethods/Bancomatpay.php +++ b/src/PaymentMethods/Bancomatpay.php @@ -21,6 +21,7 @@ public function getConfig(): array ], 'filtersOnBuild' => false, 'confirmationDelayed' => false, + 'docs' => 'https://www.mollie.com/gb/payments/bancomat-pay', ]; } diff --git a/src/PaymentMethods/Bancontact.php b/src/PaymentMethods/Bancontact.php index 9d01c9d93..14ac3832d 100644 --- a/src/PaymentMethods/Bancontact.php +++ b/src/PaymentMethods/Bancontact.php @@ -22,6 +22,7 @@ protected function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => true, 'SEPA' => true, + 'docs' => 'https://www.mollie.com/gb/payments/bancontact', ]; } diff --git a/src/PaymentMethods/Banktransfer.php b/src/PaymentMethods/Banktransfer.php index 93a6f3f10..6abc75866 100644 --- a/src/PaymentMethods/Banktransfer.php +++ b/src/PaymentMethods/Banktransfer.php @@ -42,6 +42,7 @@ protected function getConfig(): array 'confirmationDelayed' => true, 'SEPA' => false, 'customRedirect' => true, + 'docs' => 'https://www.mollie.com/gb/payments/bank-transfer', ]; } diff --git a/src/PaymentMethods/Belfius.php b/src/PaymentMethods/Belfius.php index ea98768f9..c8876451b 100644 --- a/src/PaymentMethods/Belfius.php +++ b/src/PaymentMethods/Belfius.php @@ -22,6 +22,7 @@ protected function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => true, 'SEPA' => true, + 'docs' => 'https://www.mollie.com/gb/payments/belfius', ]; } diff --git a/src/PaymentMethods/Billie.php b/src/PaymentMethods/Billie.php index 369f49521..0269b9da0 100644 --- a/src/PaymentMethods/Billie.php +++ b/src/PaymentMethods/Billie.php @@ -31,6 +31,7 @@ protected function getConfig(): array 'mollie-payments-for-woocommerce' ), 'companyPlaceholder' => __('Please enter your company name here.', 'mollie-payments-for-woocommerce'), + 'docs' => 'https://www.mollie.com/gb/payments/billie', ]; } diff --git a/src/PaymentMethods/Blik.php b/src/PaymentMethods/Blik.php index 83e05ef2c..c0590dcd6 100644 --- a/src/PaymentMethods/Blik.php +++ b/src/PaymentMethods/Blik.php @@ -22,6 +22,7 @@ protected function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => false, 'SEPA' => false, + 'docs' => 'https://www.mollie.com/gb/payments/blik', ]; } diff --git a/src/PaymentMethods/Creditcard.php b/src/PaymentMethods/Creditcard.php index 237ad4ce7..85e26b432 100644 --- a/src/PaymentMethods/Creditcard.php +++ b/src/PaymentMethods/Creditcard.php @@ -27,6 +27,7 @@ protected function getConfig(): array 'confirmationDelayed' => false, 'SEPA' => false, 'Subscription' => true, + 'docs' => 'https://www.mollie.com/gb/payments/credit-card', ]; } diff --git a/src/PaymentMethods/Directdebit.php b/src/PaymentMethods/Directdebit.php index 5b4b91d34..0b7bf94fa 100644 --- a/src/PaymentMethods/Directdebit.php +++ b/src/PaymentMethods/Directdebit.php @@ -22,6 +22,7 @@ protected function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => true, 'SEPA' => false, + 'docs' => 'https://www.mollie.com/gb/payments/direct-debit', ]; } diff --git a/src/PaymentMethods/Eps.php b/src/PaymentMethods/Eps.php index 15bd8eb5d..327a53acd 100644 --- a/src/PaymentMethods/Eps.php +++ b/src/PaymentMethods/Eps.php @@ -22,6 +22,7 @@ protected function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => true, 'SEPA' => true, + 'docs' => 'https://www.mollie.com/gb/payments/eps', ]; } diff --git a/src/PaymentMethods/Giftcard.php b/src/PaymentMethods/Giftcard.php index 812e3cd7f..b5154541a 100644 --- a/src/PaymentMethods/Giftcard.php +++ b/src/PaymentMethods/Giftcard.php @@ -70,6 +70,7 @@ protected function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => false, 'SEPA' => false, + 'docs' => 'https://www.mollie.com/gb/payments/gift-cards', ]; } diff --git a/src/PaymentMethods/Giropay.php b/src/PaymentMethods/Giropay.php index 440b8f0b8..8939ce56c 100644 --- a/src/PaymentMethods/Giropay.php +++ b/src/PaymentMethods/Giropay.php @@ -22,6 +22,7 @@ protected function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => true, 'SEPA' => true, + 'docs' => 'https://help.mollie.com/hc/en-gb/articles/19745480480786-Giropay-Depreciation-FAQ', ]; } diff --git a/src/PaymentMethods/Ideal.php b/src/PaymentMethods/Ideal.php index bc2e67139..08b28c0b3 100644 --- a/src/PaymentMethods/Ideal.php +++ b/src/PaymentMethods/Ideal.php @@ -24,6 +24,7 @@ public function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => true, 'SEPA' => true, + 'docs' => 'https://www.mollie.com/gb/payments/ideal-2-0', ]; } diff --git a/src/PaymentMethods/In3.php b/src/PaymentMethods/In3.php index d86beb12d..f839c6e71 100644 --- a/src/PaymentMethods/In3.php +++ b/src/PaymentMethods/In3.php @@ -29,6 +29,7 @@ public function getConfig(): array ), 'phonePlaceholder' => __('Please enter your phone here. +316xxxxxxxx', 'mollie-payments-for-woocommerce'), 'birthdatePlaceholder' => __('Please enter your birthdate here.', 'mollie-payments-for-woocommerce'), + 'docs' => 'https://www.mollie.com/gb/payments/ideal-in3', ]; } diff --git a/src/PaymentMethods/Kbc.php b/src/PaymentMethods/Kbc.php index 4005b83fd..99de76e93 100644 --- a/src/PaymentMethods/Kbc.php +++ b/src/PaymentMethods/Kbc.php @@ -23,6 +23,7 @@ protected function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => true, 'SEPA' => true, + 'docs' => 'https://www.mollie.com/gb/payments/kbc-cbc', ]; } diff --git a/src/PaymentMethods/Klarna.php b/src/PaymentMethods/Klarna.php index bdad1b516..0c0b3ccc8 100644 --- a/src/PaymentMethods/Klarna.php +++ b/src/PaymentMethods/Klarna.php @@ -26,6 +26,7 @@ protected function getConfig(): array 'confirmationDelayed' => false, 'SEPA' => false, 'orderMandatory' => true, + 'docs' => 'https://www.mollie.com/gb/payments/klarna', ]; } diff --git a/src/PaymentMethods/Klarnapaylater.php b/src/PaymentMethods/Klarnapaylater.php index 99140ba4a..edd6f6c99 100644 --- a/src/PaymentMethods/Klarnapaylater.php +++ b/src/PaymentMethods/Klarnapaylater.php @@ -26,6 +26,7 @@ protected function getConfig(): array 'confirmationDelayed' => false, 'SEPA' => false, 'orderMandatory' => true, + 'docs' => 'https://www.mollie.com/gb/payments/klarna', ]; } diff --git a/src/PaymentMethods/Klarnapaynow.php b/src/PaymentMethods/Klarnapaynow.php index 32cd04a98..5cdddfeb3 100644 --- a/src/PaymentMethods/Klarnapaynow.php +++ b/src/PaymentMethods/Klarnapaynow.php @@ -26,6 +26,7 @@ protected function getConfig(): array 'confirmationDelayed' => false, 'SEPA' => false, 'orderMandatory' => true, + 'docs' => 'https://www.mollie.com/gb/payments/klarna', ]; } diff --git a/src/PaymentMethods/Klarnasliceit.php b/src/PaymentMethods/Klarnasliceit.php index 9b97b3db3..dd8e31c21 100644 --- a/src/PaymentMethods/Klarnasliceit.php +++ b/src/PaymentMethods/Klarnasliceit.php @@ -26,6 +26,7 @@ protected function getConfig(): array 'confirmationDelayed' => false, 'SEPA' => false, 'orderMandatory' => true, + 'docs' => 'https://www.mollie.com/gb/payments/klarna', ]; } diff --git a/src/PaymentMethods/Mybank.php b/src/PaymentMethods/Mybank.php index a2f38ba23..e656d23ee 100644 --- a/src/PaymentMethods/Mybank.php +++ b/src/PaymentMethods/Mybank.php @@ -22,6 +22,7 @@ protected function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => false, 'SEPA' => false, + 'docs' => '', ]; } diff --git a/src/PaymentMethods/Payconiq.php b/src/PaymentMethods/Payconiq.php index 59f9899af..b89696c97 100644 --- a/src/PaymentMethods/Payconiq.php +++ b/src/PaymentMethods/Payconiq.php @@ -19,6 +19,7 @@ protected function getConfig(): array 'filtersOnBuild' => false, 'confirmationDelayed' => false, 'SEPA' => false, + 'docs' => '', ]; } diff --git a/src/PaymentMethods/PaymentMethodsIconUrl.php b/src/PaymentMethods/PaymentMethodsIconUrl.php index a1189ff8d..ed4c09a73 100644 --- a/src/PaymentMethods/PaymentMethodsIconUrl.php +++ b/src/PaymentMethods/PaymentMethodsIconUrl.php @@ -87,7 +87,7 @@ public function svgUrlForPaymentMethod($paymentMethodName) return $this->generateIconHtml($svgUrl); } - public function generateIconHtml($svgUrl) + public function generateIconHtml(string $svgUrl): string { return ' + + + + + + + + + +

    + + + + id, + [$this, 'output_sections'] + ); + } + + protected function pages(): array + { + return [ + PageNoApiKey::class, + PageApiKeys::class, + PagePaymentMethods::class, + PageAdvancedSettings::class, + ]; + } + + public function get_settings($currentSection = '') + { + $defaultSection = $currentSection; + $connectionStatus = $this->settings->getConnectionStatus(); + + if (!$connectionStatus) { + $defaultSection = PageNoApiKey::slug(); + } + + if ($connectionStatus && $defaultSection === PageNoApiKey::slug()) { + $defaultSection = PageApiKeys::slug(); + } + + if ($defaultSection === '') { + $defaultSection = PageApiKeys::slug(); + } + + $mollieSettings = null; + foreach ($this->pages() as $pageClass) { + /** @var AbstractPage $page */ + $page = new $pageClass( + $this->settings, + $this->pluginUrl, + $this->pages(), + $defaultSection, + $connectionStatus, + $this->isTestModeEnabled, + $this->mollieGateways, + $this->paymentMethods, + $this->dataHelper + ); + if ($page::slug() === $defaultSection) { + $mollieSettings = $this->hideKeysIntoStars($page->settings()); + break; + } + } + + return apply_filters( + 'woocommerce_get_settings_' . $this->id, + $mollieSettings, + $currentSection + ); + } + + /** + * @param $settings + * + * @return array + */ + protected function hideKeysIntoStars($settings): array + { + $liveKeyName = 'mollie-payments-for-woocommerce_live_api_key'; + $testKeyName = 'mollie-payments-for-woocommerce_test_api_key'; + $liveValue = get_option($liveKeyName); + $testValue = get_option($testKeyName); + + foreach ($settings as $key => $setting) { + if ( + ($setting['id'] + === $liveKeyName + && $liveValue) + || ($setting['id'] + === $testKeyName + && $testValue) + ) { + $settings[$key]['value'] = '**********'; + } + } + return $settings; + } + + /** + * Save settings + * + * @since 1.0 + */ + public function save() + { + global $current_section; + + $settings = $this->get_settings($current_section); + $settings = $this->saveApiKeys($settings); + WC_Admin_Settings::save_fields($settings); + } + + /** + * @param $settings + * + * @return array + */ + protected function saveApiKeys($settings) + { + $nonce = filter_input(INPUT_POST, '_wpnonce', FILTER_SANITIZE_SPECIAL_CHARS); + $isNonceValid = wp_verify_nonce( + $nonce, + 'woocommerce-settings' + ); + if (!$isNonceValid) { + return $settings; + } + $liveKeyName = 'mollie-payments-for-woocommerce_live_api_key'; + $testKeyName = 'mollie-payments-for-woocommerce_test_api_key'; + $liveValueInDb = get_option($liveKeyName); + $testValueInDb = get_option($testKeyName); + $postedLiveValue = isset($_POST[$liveKeyName]) ? sanitize_text_field(wp_unslash($_POST[$liveKeyName])) : ''; + $postedTestValue = isset($_POST[$testKeyName]) ? sanitize_text_field(wp_unslash($_POST[$testKeyName])) : ''; + + foreach ($settings as $setting) { + if ( + $setting['id'] + === $liveKeyName + && $liveValueInDb + ) { + if ($postedLiveValue === '**********') { + $_POST[$liveKeyName] = $liveValueInDb; + } else { + $pattern = '/^live_\w{30,}$/'; + $this->validateApiKeyOrRemove( + $pattern, + $postedLiveValue, + $liveKeyName + ); + } + } elseif ( + $setting['id'] + === $testKeyName + && $testValueInDb + ) { + if ($postedTestValue === '**********') { + $_POST[$testKeyName] = $testValueInDb; + } else { + $pattern = '/^test_\w{30,}$/'; + $this->validateApiKeyOrRemove( + $pattern, + $postedTestValue, + $testKeyName + ); + } + } + } + return $settings; + } + + /** + * @param $pattern + * @param $value + * @param $keyName + * + */ + protected function validateApiKeyOrRemove($pattern, $value, $keyName) + { + $nonce = filter_input(INPUT_POST, '_wpnonce', FILTER_SANITIZE_SPECIAL_CHARS); + $isNonceValid = wp_verify_nonce( + $nonce, + 'woocommerce-settings' + ); + if (!$isNonceValid) { + return; + } + $hasApiFormat = preg_match($pattern, $value); + if (!$hasApiFormat) { + unset($_POST[$keyName]); + } + } +} diff --git a/src/Settings/Page/AbstractPage.php b/src/Settings/Page/AbstractPage.php new file mode 100644 index 000000000..86ce33627 --- /dev/null +++ b/src/Settings/Page/AbstractPage.php @@ -0,0 +1,90 @@ +settings = $settings; + $this->pluginUrl = $pluginUrl; + $this->currentSection = $currentSection; + $this->connectionStatus = $connectionStatus; + $this->testModeEnabled = $testModeEnabled; + $this->pages = $pages; + $this->mollieGateways = $mollieGateways; + $this->paymentMethods = $paymentMethods; + $this->dataHelper = $dataHelper; + } + + abstract public static function isTab(): bool; + + abstract public static function slug(): string; + + public static function tabName(): string + { + return 'tabName'; + } + + protected function sections(): array + { + return []; + } + + public function settings(): array + { + $settings = []; + $styles = []; + + foreach ($this->sections() as $sectionClass) { + /** @var AbstractSection $section */ + $section = new $sectionClass( + $this->settings, + $this->pluginUrl, + $this->pages, + $this->currentSection, + $this->connectionStatus, + $this->testModeEnabled, + $this->mollieGateways, + $this->paymentMethods, + $this->dataHelper + ); + foreach ($section->config() as $field) { + $settings[] = $field; + } + $styles[$sectionClass] = $section->styles(); + } + array_unshift($settings, [ + 'id' => $this->settings->getSettingId('styles'), + 'type' => 'mollie_content', + 'value' => implode($styles), + ]); + return $settings; + } +} diff --git a/src/Settings/Page/Components.php b/src/Settings/Page/Components.php deleted file mode 100644 index 59548e33f..000000000 --- a/src/Settings/Page/Components.php +++ /dev/null @@ -1,68 +0,0 @@ -id = 'mollie_components'; - $this->label = __('Mollie Components', 'mollie-payments-for-woocommerce'); - $this->pluginPath = $pluginPath; - - parent::__construct(); - } - - public function output() - { - $settings = $this->get_settings(); - WC_Admin_Settings::output_fields($settings); - } - - public function get_settings() - { - $componentsSettings = $this->componentsSettings(); - - /** - * Filter Component Settings - * - * @param array $componentSettings Default components settings for the Credit Card Gateway - */ - $componentsSettings = apply_filters(self::FILTER_COMPONENTS_SETTINGS, $componentsSettings); - - return $componentsSettings; - } - - protected function componentsSettings() - { - $componentSettingsFilePath = $this->componentsFilePath(); - - if (!file_exists($componentSettingsFilePath)) { - return []; - } - - $components = include $componentSettingsFilePath; - - if (!is_array($components)) { - $components = []; - } - - return $components; - } - - protected function componentsFilePath() - { - return $this->pluginPath . '/inc/settings/mollie_components.php'; - } -} diff --git a/src/Settings/Page/MollieSettingsPage.php b/src/Settings/Page/MollieSettingsPage.php deleted file mode 100644 index fd265b692..000000000 --- a/src/Settings/Page/MollieSettingsPage.php +++ /dev/null @@ -1,789 +0,0 @@ -id = 'mollie_settings'; - $this->label = __('Mollie Settings', 'mollie-payments-for-woocommerce'); - $this->settingsHelper = $settingsHelper; - $this->pluginPath = $pluginPath; - $this->registeredGateways = $gateways; - $this->isTestModeEnabled = $isTestModeEnabled; - $this->dataHelper = $dataHelper; - $this->paymentMethods = $paymentMethods; - add_action( - 'woocommerce_sections_' . $this->id, - [$this, 'output_sections'] - ); - parent::__construct(); - } - - public function output() - { - global $current_section; - $settings = $this->get_settings($current_section); - $settings = $this->hideKeysIntoStars($settings); - - WC_Admin_Settings::output_fields($settings); - } - - public function get_settings($currentSection = '') - { - $mollieSettings = $this->addGlobalSettingsFields([]); - - if ('mollie_components' === $currentSection) { - $mollieSettings = $this->sectionSettings( - $this->componentsFilePath() - ); - } - if ('applepay_button' === $currentSection) { - $mollieSettings = $this->sectionSettings($this->applePaySection()); - } - if ('advanced' === $currentSection) { - $mollieSettings = $this->sectionSettings($this->advancedSectionFilePath()); - } - - /** - * Filter Component Settings - * - * @param array $componentSettings Default components settings for the Credit Card Gateway - */ - $mollieSettings = apply_filters( - self::FILTER_COMPONENTS_SETTINGS, - $mollieSettings - ); - - return apply_filters( - 'woocommerce_get_settings_' . $this->id, - $mollieSettings, - $currentSection - ); - } - - /** - * @param array $settings - * @return array - */ - public function addGlobalSettingsFields(array $settings): array - { - $presentationText = __( - 'Quickly integrate all major payment methods in WooCommerce, wherever you need them.', - 'mollie-payments-for-woocommerce' - ); - $presentationText .= __( - ' Simply drop them ready-made into your WooCommerce webshop with this powerful plugin by Mollie.', - 'mollie-payments-for-woocommerce' - ); - $presentationText .= __( - ' Mollie is dedicated to making payments better for WooCommerce. ', - 'mollie-payments-for-woocommerce' - ); - $presentationText .= '

    ' . __( - 'Please go to', - 'mollie-payments-for-woocommerce' - ) . '' . __( - ' the signup page', - 'mollie-payments-for-woocommerce' - ) . ' '; - $presentationText .= __( - ' to create a new Mollie account and start receiving payments in a couple of minutes. ', - 'mollie-payments-for-woocommerce' - ); - $presentationText .= __( - 'Contact ', - 'mollie-payments-for-woocommerce' - ) . 'info@mollie.com'; - $presentationText .= __( - ' if you have any questions or comments about this plugin.', - 'mollie-payments-for-woocommerce' - ) . '

    '; - $presentationText .= '

    ' . __( - 'Our pricing is always per transaction. No startup fees, no monthly fees, and no gateway fees. No hidden fees, period.', - 'mollie-payments-for-woocommerce' - ) . '

    '; - - $presentation = '' - . '' - . '' - . '

    ' . $presentationText . '

    '; - - $content = '' - . $presentation - . $this->settingsHelper->getPluginStatus() - . $this->getMollieMethods(); - - $debugDesc = __('Log plugin events.', 'mollie-payments-for-woocommerce'); - - // Display location of log files - - - $debugDesc .= ' ' . sprintf( - /* translators: Placeholder 1: Location of the log files */ - __( - 'Log files are saved to %s', - 'mollie-payments-for-woocommerce' - ), - defined('WC_LOG_DIR') ? WC_LOG_DIR - : WC()->plugin_path() . '/logs/' - ); - - // Global Mollie settings - $mollieSettings = [ - [ - 'id' => $this->settingsHelper->getSettingId('title'), - 'title' => __('Mollie Settings', 'mollie-payments-for-woocommerce'), - 'type' => 'title', - 'desc' => '

    ' . $content . '

    ' - . '

    ' . __( - 'The following options are required to use the plugin and are used by all Mollie payment methods', - 'mollie-payments-for-woocommerce' - ) . '

    ', - ], - [ - 'id' => $this->settingsHelper->getSettingId('live_api_key'), - 'title' => __('Live API key', 'mollie-payments-for-woocommerce'), - 'default' => '', - 'type' => 'text', - 'desc' => sprintf( - /* translators: Placeholder 1: API key mode (live or test). The surrounding %s's Will be replaced by a link to the Mollie profile */ - __( - 'The API key is used to connect to Mollie. You can find your %1$s API key in your %2$sMollie account%3$s', - 'mollie-payments-for-woocommerce' - ), - 'live', - '', - '' - ), - 'css' => 'width: 350px', - 'placeholder' => __( - 'Live API key should start with live_', - 'mollie-payments-for-woocommerce' - ), - ], - [ - 'id' => $this->settingsHelper->getSettingId('test_mode_enabled'), - 'title' => __('Enable test mode', 'mollie-payments-for-woocommerce'), - 'default' => 'no', - 'type' => 'checkbox', - 'desc_tip' => __( - 'Enable test mode if you want to test the plugin without using real payments.', - 'mollie-payments-for-woocommerce' - ), - ], - [ - 'id' => $this->settingsHelper->getSettingId('test_api_key'), - 'title' => __('Test API key', 'mollie-payments-for-woocommerce'), - 'default' => '', - 'type' => 'text', - 'desc' => sprintf( - /* translators: Placeholder 1: API key mode (live or test). The surrounding %s's Will be replaced by a link to the Mollie profile */ - __( - 'The API key is used to connect to Mollie. You can find your %1$s API key in your %2$sMollie account%3$s', - 'mollie-payments-for-woocommerce' - ), - 'test', - '', - '' - ), - 'css' => 'width: 350px', - 'placeholder' => __( - 'Test API key should start with test_', - 'mollie-payments-for-woocommerce' - ), - ], - [ - 'id' => $this->settingsHelper->getSettingId('debug'), - 'title' => __('Debug Log', 'mollie-payments-for-woocommerce'), - 'type' => 'checkbox', - 'desc' => $debugDesc, - 'default' => 'yes', - ], - [ - 'id' => $this->settingsHelper->getSettingId('sectionend'), - 'type' => 'sectionend', - ], - ]; - - return $this->mergeSettings($settings, $mollieSettings); - } - /** - * @return string - */ - public function getMollieMethods(): string - { - $content = ''; - - $dataHelper = $this->dataHelper; - - // Is Test mode enabled? - $testMode = $this->isTestModeEnabled; - $apiKey = $this->settingsHelper->getApiKey(); - - if ( - isset($_GET['refresh-methods']) && - isset($_GET['nonce_mollie_refresh_methods']) && - wp_verify_nonce( - filter_input(INPUT_GET, 'nonce_mollie_refresh_methods', FILTER_SANITIZE_SPECIAL_CHARS), - 'nonce_mollie_refresh_methods' - ) - ) { - /* Reload active Mollie methods */ - $methods = $dataHelper->getAllPaymentMethods($apiKey, $testMode, false); - foreach ($methods as $key => $method) { - $methods['mollie_wc_gateway_' . $method['id']] = $method; - unset($methods[$key]); - } - $this->registeredGateways = $methods; - } - if ( - isset($_GET['cleanDB-mollie']) && wp_verify_nonce( - filter_input(INPUT_GET, 'nonce_mollie_cleanDb', FILTER_SANITIZE_SPECIAL_CHARS), - 'nonce_mollie_cleanDb' - ) - ) { - $cleaner = $this->settingsHelper->cleanDb(); - $cleaner->cleanAll(); - //set default settings - foreach ($this->paymentMethods as $paymentMethod) { - $paymentMethod->getSettings(); - } - } - - $iconAvailable = ' ' . strtolower(__('Enabled', 'mollie-payments-for-woocommerce')) . ''; - $iconNoAvailable = ' ' . strtolower(__('Disabled', 'mollie-payments-for-woocommerce')) . ''; - - $content .= '

    '; - $content .= '
    '; - - if ($testMode) { - $content .= '' . __('Test mode enabled.', 'mollie-payments-for-woocommerce') . ' '; - } - - $content .= sprintf( - /* translators: The surrounding %s's Will be replaced by a link to the Mollie profile */ - __( - 'The following payment methods are activated in your %1$sMollie profile%2$s:', - 'mollie-payments-for-woocommerce' - ), - '', - '' - ); - - // Set a "refresh" link so payment method status can be refreshed from Mollie API - $nonce_mollie_refresh_methods = wp_create_nonce('nonce_mollie_refresh_methods'); - $refresh_methods_url = add_query_arg( - ['refresh-methods' => 1, 'nonce_mollie_refresh_methods' => $nonce_mollie_refresh_methods] - ); - - $content .= ' (' . strtolower( - __('Refresh', 'mollie-payments-for-woocommerce') - ) . ')'; - - $content .= '
      '; - - $mollieGateways = $this->registeredGateways;//this are the gateways enabled - $paymentMethods = $this->paymentMethods; - if (empty($mollieGateways)) { - $content .= '
    • '; - $content .= __("No payment methods available", "mollie-payments-for-woocommerce"); - $content .= '
    '; - $content .= '
    '; - return $content; - } - foreach ($paymentMethods as $paymentMethod) { - $paymentMethodId = $paymentMethod->getProperty('id'); - $gatewayKey = 'mollie_wc_gateway_' . $paymentMethodId; - $paymentMethodEnabledAtMollie = array_key_exists($gatewayKey, $mollieGateways); - $content .= '
  • '; - $content .= $paymentMethod->getIconUrl(); - $content .= ' ' . esc_html($paymentMethod->title()); - if ($paymentMethodEnabledAtMollie) { - $content .= $iconAvailable; - $content .= ' ' . strtolower( - __('Edit', 'mollie-payments-for-woocommerce') - ) . ''; - - $content .= '
  • '; - continue; - } - $content .= $iconNoAvailable; - $content .= ' ' . strtolower( - __('Activate', 'mollie-payments-for-woocommerce') - ) . ''; - - $content .= ''; - } - - $content .= ''; - $content .= '
    '; - - // Make sure users also enable iDEAL when they enable SEPA Direct Debit - // iDEAL is needed for the first payment of subscriptions with SEPA Direct Debit - $content = $this->checkDirectDebitStatus($content); - - // Advice users to use bank transfer via Mollie, not - // WooCommerce default BACS method - $content = $this->checkMollieBankTransferNotBACS($content); - - // Warn users that all default WooCommerce checkout fields - // are required to accept Klarna as payment method - $content = $this->warnAboutRequiredCheckoutFieldForKlarna($content); - - // Warn users that all default WooCommerce checkout fields - // and billing company name - // are required to accept Billie as payment method - $content = $this->warnAboutRequiredCheckoutFieldForBillie($content); - - return $content; - } - - /** - * @param string $gateway_class_name - * @return string - */ - protected function getGatewaySettingsUrl(string $gateway_class_name): string - { - return admin_url( - 'admin.php?page=wc-settings&tab=checkout§ion=' . sanitize_title(strtolower($gateway_class_name)) - ); - } - - /** - * @param $content - * - * @return string - */ - protected function checkDirectDebitStatus($content): string - { - $hasCustomSepaSettings = $this->paymentMethods["directdebit"]->getProperty('enabled') !== false; - $isSepaEnabled = !$hasCustomSepaSettings || $this->paymentMethods["directdebit"]->getProperty('enabled') === 'yes'; - $sepaGatewayAllowed = !empty($this->registeredGateways["mollie_wc_gateway_directdebit"]); - if ($sepaGatewayAllowed && !$isSepaEnabled) { - $warning_message = __( - "You have WooCommerce Subscriptions activated, but not SEPA Direct Debit. Enable SEPA Direct Debit if you want to allow customers to pay subscriptions with iDEAL and/or other 'first' payment methods.", - 'mollie-payments-for-woocommerce' - ); - - $content .= '

    '; - $content .= $warning_message; - $content .= '

    '; - - return $content; - } - - return $content; - } - - /** - * @param $content - * - * @return string - */ - protected function checkMollieBankTransferNotBACS($content): string - { - $woocommerce_banktransfer_gateway = new WC_Gateway_BACS(); - - if ($woocommerce_banktransfer_gateway->is_available()) { - $content .= '

    '; - $content .= __( - 'You have the WooCommerce default Direct Bank Transfer (BACS) payment gateway enabled in WooCommerce. Mollie strongly advices only using Bank Transfer via Mollie and disabling the default WooCommerce BACS payment gateway to prevent possible conflicts.', - 'mollie-payments-for-woocommerce' - ); - $content .= '

    '; - - return $content; - } - - return $content; - } - - /** - * @param $content - * - * @return string - */ - protected function warnAboutRequiredCheckoutFieldForKlarna($content): string - { - $isKlarnaEnabled = $this->isKlarnaEnabled(); - if ($isKlarnaEnabled) { - $content .= '

    '; - $content .= sprintf( - /* translators: Placeholder 1: Opening link tag. Placeholder 2: Closing link tag. Placeholder 3: Opening link tag. Placeholder 4: Closing link tag. */ - __( - 'You have activated Klarna. To accept payments, please make sure all default WooCommerce checkout fields are enabled and required. For more information, go to %1$sKlarna Pay Later documentation%2$s or %3$sKlarna Slice it documentation%4$s', - 'mollie-payments-for-woocommerce' - ), - '', - '', - '', - '' - ); - $content .= '

    '; - - return $content; - } - - return $content; - } - - /** - * @param array $settings - * @param array $mollie_settings - * @return array - */ - protected function mergeSettings(array $settings, array $mollie_settings): array - { - $new_settings = []; - $mollie_settings_merged = false; - - // Find payment gateway options index - foreach ($settings as $index => $setting) { - if ( - isset($setting['id']) && $setting['id'] === 'payment_gateways_options' - && (!isset($setting['type']) || $setting['type'] !== 'sectionend') - ) { - $new_settings = array_merge($new_settings, $mollie_settings); - $mollie_settings_merged = true; - } - - $new_settings[] = $setting; - } - - // Mollie settings not merged yet, payment_gateways_options not found - if (!$mollie_settings_merged) { - // Append Mollie settings - $new_settings = array_merge($new_settings, $mollie_settings); - } - - return $new_settings; - } - - /** - * @param $filePath - * - * @return array|mixed - */ - protected function sectionSettings($filePath) - { - if (!file_exists($filePath)) { - return []; - } - - $section = include $filePath; - - if (!is_array($section)) { - $section = []; - } - - return $section; - } - - /** - * @return string - */ - protected function componentsFilePath(): string - { - return $this->pluginPath . '/inc/settings/mollie_components.php'; - } - - /** - * @return string - */ - protected function applePaySection(): string - { - return $this->pluginPath . '/inc/settings/mollie_applepay_settings.php'; - } - - /** - * @return string - */ - protected function advancedSectionFilePath(): string - { - return $this->pluginPath . '/inc/settings/mollie_advanced_settings.php'; - } - - /** - * @param $settings - * - * @return array - */ - protected function hideKeysIntoStars($settings): array - { - $liveKeyName = 'mollie-payments-for-woocommerce_live_api_key'; - $testKeyName = 'mollie-payments-for-woocommerce_test_api_key'; - $liveValue = get_option($liveKeyName); - $testValue = get_option($testKeyName); - - foreach ($settings as $key => $setting) { - if ( - ($setting['id'] - === $liveKeyName - && $liveValue) - || ($setting['id'] - === $testKeyName - && $testValue) - ) { - $settings[$key]['value'] = '**********'; - } - } - return $settings; - } - - /** - * Save settings - * - * @since 1.0 - */ - public function save() - { - global $current_section; - - $settings = $this->get_settings($current_section); - if ('applepay_button' === $current_section) { - $this->saveApplePaySettings(); - } else { - $settings = $this->saveApiKeys($settings); - WC_Admin_Settings::save_fields($settings); - } - } - - protected function saveApplePaySettings() - { - $nonce = filter_input(INPUT_POST, '_wpnonce', FILTER_SANITIZE_SPECIAL_CHARS); - $isNonceValid = wp_verify_nonce( - $nonce, - 'woocommerce-settings' - ); - if (!$isNonceValid) { - return; - } - $data = filter_var_array($_POST, FILTER_SANITIZE_SPECIAL_CHARS); - - $applepaySettings = []; - isset($data['enabled']) && ($data['enabled'] === '1') ? - $applepaySettings['enabled'] = 'yes' - : $applepaySettings['enabled'] = 'no'; - isset($data['display_logo']) && ($data['display_logo'] === '1') ? - $applepaySettings['display_logo'] = 'yes' - : $applepaySettings['display_logo'] = 'no'; - isset($data['mollie_apple_pay_button_enabled_cart']) - && ($data['mollie_apple_pay_button_enabled_cart'] === '1') ? - $applepaySettings['mollie_apple_pay_button_enabled_cart'] = 'yes' - : $applepaySettings['mollie_apple_pay_button_enabled_cart'] = 'no'; - isset($data['mollie_apple_pay_button_enabled_product']) - && ($data['mollie_apple_pay_button_enabled_product'] === '1') - ? - $applepaySettings['mollie_apple_pay_button_enabled_product'] = 'yes' - : - $applepaySettings['mollie_apple_pay_button_enabled_product'] = 'no'; - isset($data['title']) ? $applepaySettings['title'] = $data['title'] - : $applepaySettings['title'] = ''; - isset($data['description']) ? - $applepaySettings['description'] = $data['description'] - : $applepaySettings['description'] = ''; - update_option( - 'mollie_wc_gateway_applepay_settings', - $applepaySettings - ); - } - - /** - * @param $settings - * - * @return array - */ - protected function saveApiKeys($settings) - { - $nonce = filter_input(INPUT_POST, '_wpnonce', FILTER_SANITIZE_SPECIAL_CHARS); - $isNonceValid = wp_verify_nonce( - $nonce, - 'woocommerce-settings' - ); - if (!$isNonceValid) { - return $settings; - } - $liveKeyName = 'mollie-payments-for-woocommerce_live_api_key'; - $testKeyName = 'mollie-payments-for-woocommerce_test_api_key'; - $liveValueInDb = get_option($liveKeyName); - $testValueInDb = get_option($testKeyName); - $postedLiveValue = isset($_POST[$liveKeyName]) ? sanitize_text_field(wp_unslash($_POST[$liveKeyName])) : ''; - $postedTestValue = isset($_POST[$testKeyName]) ? sanitize_text_field(wp_unslash($_POST[$testKeyName])) : ''; - - foreach ($settings as $setting) { - if ( - $setting['id'] - === $liveKeyName - && $liveValueInDb - ) { - if ($postedLiveValue === '**********') { - $_POST[$liveKeyName] = $liveValueInDb; - } else { - $pattern = '/^live_\w{30,}$/'; - $this->validateApiKeyOrRemove( - $pattern, - $postedLiveValue, - $liveKeyName - ); - } - } elseif ( - $setting['id'] - === $testKeyName - && $testValueInDb - ) { - if ($postedTestValue === '**********') { - $_POST[$testKeyName] = $testValueInDb; - } else { - $pattern = '/^test_\w{30,}$/'; - $this->validateApiKeyOrRemove( - $pattern, - $postedTestValue, - $testKeyName - ); - } - } - } - return $settings; - } - - /** - * @param $pattern - * @param $value - * @param $keyName - * - */ - protected function validateApiKeyOrRemove($pattern, $value, $keyName) - { - $nonce = filter_input(INPUT_POST, '_wpnonce', FILTER_SANITIZE_SPECIAL_CHARS); - $isNonceValid = wp_verify_nonce( - $nonce, - 'woocommerce-settings' - ); - if (!$isNonceValid) { - return; - } - $hasApiFormat = preg_match($pattern, $value); - if (!$hasApiFormat) { - unset($_POST[$keyName]); - } - } - - /** - * @return array|mixed|void|null - */ - public function get_sections() - { - $isAppleEnabled = array_key_exists('mollie_wc_gateway_applepay', $this->registeredGateways); - $sections = [ - '' => __('General', 'mollie-payments-for-woocommerce'), - 'mollie_components' => __( - 'Mollie Components', - 'mollie-payments-for-woocommerce' - ), - 'advanced' => __('Advanced', 'mollie-payments-for-woocommerce'), - ]; - if ($isAppleEnabled) { - $sections['applepay_button'] = __( - 'Apple Pay Button', - 'mollie-payments-for-woocommerce' - ); - } - - return apply_filters( - 'woocommerce_get_sections_' . $this->id, - $sections - ); - } - - /** - * @return bool - */ - protected function isKlarnaEnabled(): bool - { - $klarnaGateways = [Constants::KLARNAPAYLATER, Constants::KLARNASLICEIT, Constants::KLARNAPAYNOW, Constants::KLARNA]; - $isKlarnaEnabled = false; - foreach ($klarnaGateways as $klarnaGateway) { - if ( - array_key_exists('mollie_wc_gateway_' . $klarnaGateway, $this->registeredGateways) - && array_key_exists($klarnaGateway, $this->paymentMethods) - && $this->paymentMethods[$klarnaGateway]->getProperty('enabled') === 'yes' - ) { - $isKlarnaEnabled = true; - break; - } - } - return $isKlarnaEnabled; - } - - private function warnAboutRequiredCheckoutFieldForBillie(string $content) - { - $isBillieEnabled = array_key_exists('mollie_wc_gateway_billie', $this->registeredGateways) - && array_key_exists('billie', $this->paymentMethods) - && $this->paymentMethods['billie']->getProperty('enabled') === 'yes'; - if ($isBillieEnabled) { - $content .= '
    '; - $content .= '

    '; - $content .= __( - 'You have activated Billie. To accept payments, please make sure all default WooCommerce checkout fields are enabled and required. The billing company field is required as well. Make sure to enable the billing company field in the WooCommerce settings if you are using Woocommerce blocks.', - 'mollie-payments-for-woocommerce' - ); - $content .= '

    '; - $content .= '
    '; - } - return $content; - } -} diff --git a/src/Settings/Page/PageAdvancedSettings.php b/src/Settings/Page/PageAdvancedSettings.php new file mode 100644 index 000000000..8325a6e1a --- /dev/null +++ b/src/Settings/Page/PageAdvancedSettings.php @@ -0,0 +1,39 @@ +settings = $settings; + $this->pluginUrl = $pluginUrl; + $this->currentSection = $currentSection; + $this->connectionStatus = $connectionStatus; + $this->testModeEnabled = $testModeEnabled; + $this->pages = $pages; + $this->mollieGateways = $mollieGateways; + $this->paymentMethods = $paymentMethods; + $this->dataHelper = $dataHelper; + } + + abstract public function config(): array; + + public function styles(): string + { + return ''; + } + + public function images(): string + { + return $this->pluginUrl . '/public/images/'; + } +} diff --git a/src/Settings/Page/Section/Advanced.php b/src/Settings/Page/Section/Advanced.php new file mode 100644 index 000000000..8b3c8967e --- /dev/null +++ b/src/Settings/Page/Section/Advanced.php @@ -0,0 +1,248 @@ + $this->settings->getSettingId('title'), + 'title' => __('Mollie advanced settings', 'mollie-payments-for-woocommerce'), + 'type' => 'title', + 'desc' => '

    ' . __('The following options are required to use the plugin and are used by all Mollie payment methods', 'mollie-payments-for-woocommerce') . '

    ', + ], + [ + 'id' => $this->settings->getSettingId('debug'), + 'title' => __('Debug Log', 'mollie-payments-for-woocommerce'), + 'type' => 'checkbox', + 'desc' => sprintf( + __( + "Log plugin events. View logs", + 'mollie-payments-for-woocommerce' + ), + $this->settings->getLogsUrl() + ), + 'default' => 'yes', + ], + [ + 'id' => $this->settings->getSettingId('order_status_cancelled_payments'), + 'title' => __('Order status after cancelled payment', 'mollie-payments-for-woocommerce'), + 'type' => 'select', + 'options' => [ + 'pending' => __('Pending', 'woocommerce'), + 'cancelled' => __('Cancelled', 'woocommerce'), + ], + 'desc' => __('Status for orders when a payment (not a Mollie order via the Orders API) is cancelled. Default: pending. Orders with status Pending can be paid with another payment method, customers can try again. Cancelled orders are final. Set this to Cancelled if you only have one payment method or don\'t want customers to re-try paying with a different payment method. This doesn\'t apply to payments for orders via the new Orders API and Klarna payments.', 'mollie-payments-for-woocommerce'), + 'default' => 'pending', + ], + [ + 'id' => $this->settings->getSettingId(SharedDataDictionary::SETTING_NAME_PAYMENT_LOCALE), + 'title' => __('Payment screen language', 'mollie-payments-for-woocommerce'), + 'type' => 'select', + 'options' => [ + SharedDataDictionary::SETTING_LOCALE_WP_LANGUAGE => __( + 'Automatically send WordPress language', + 'mollie-payments-for-woocommerce' + ) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', + SharedDataDictionary::SETTING_LOCALE_DETECT_BY_BROWSER => __( + 'Detect using browser language', + 'mollie-payments-for-woocommerce' + ), + 'en_US' => __('English', 'mollie-payments-for-woocommerce'), + 'nl_NL' => __('Dutch', 'mollie-payments-for-woocommerce'), + 'nl_BE' => __('Flemish (Belgium)', 'mollie-payments-for-woocommerce'), + 'fr_FR' => __('French', 'mollie-payments-for-woocommerce'), + 'fr_BE' => __('French (Belgium)', 'mollie-payments-for-woocommerce'), + 'de_DE' => __('German', 'mollie-payments-for-woocommerce'), + 'de_AT' => __('Austrian German', 'mollie-payments-for-woocommerce'), + 'de_CH' => __('Swiss German', 'mollie-payments-for-woocommerce'), + 'es_ES' => __('Spanish', 'mollie-payments-for-woocommerce'), + 'ca_ES' => __('Catalan', 'mollie-payments-for-woocommerce'), + 'pt_PT' => __('Portuguese', 'mollie-payments-for-woocommerce'), + 'it_IT' => __('Italian', 'mollie-payments-for-woocommerce'), + 'nb_NO' => __('Norwegian', 'mollie-payments-for-woocommerce'), + 'sv_SE' => __('Swedish', 'mollie-payments-for-woocommerce'), + 'fi_FI' => __('Finnish', 'mollie-payments-for-woocommerce'), + 'da_DK' => __('Danish', 'mollie-payments-for-woocommerce'), + 'is_IS' => __('Icelandic', 'mollie-payments-for-woocommerce'), + 'hu_HU' => __('Hungarian', 'mollie-payments-for-woocommerce'), + 'pl_PL' => __('Polish', 'mollie-payments-for-woocommerce'), + 'lv_LV' => __('Latvian', 'mollie-payments-for-woocommerce'), + 'lt_LT' => __('Lithuanian', 'mollie-payments-for-woocommerce'), + ], + 'desc' => sprintf( + /* translators: Placeholder 1: link tag Placeholder 2: closing tag */ + __('Sending a language (or locale) is required. The option \'Automatically send WordPress language\' will try to get the customer\'s language in WordPress (and respects multilanguage plugins) and convert it to a format Mollie understands. If this fails, or if the language is not supported, it will fall back to American English. You can also select one of the locales currently supported by Mollie, that will then be used for all customers.', 'mollie-payments-for-woocommerce'), + '', + '' + ), + 'default' => SharedDataDictionary::SETTING_LOCALE_WP_LANGUAGE, + ], + [ + 'id' => $this->settings->getSettingId('customer_details'), + 'title' => __('Store customer details at Mollie', 'mollie-payments-for-woocommerce'), + 'desc' => sprintf( + /* translators: Placeholder 1: enabled or disabled Placeholder 2: translated string */ + __( + 'Should Mollie store customers name and email address for Single Click Payments? Default %1$s. Required if WooCommerce Subscriptions is being used! Read more about %2$s and how it improves your conversion.', + 'mollie-payments-for-woocommerce' + ), + strtolower(__('Enabled', 'mollie-payments-for-woocommerce')), + __('Single Click Payments', 'mollie-payments-for-woocommerce') + ), + 'type' => 'checkbox', + 'default' => 'yes', + + ], + [ + 'id' => $this->settings->getSettingId('api_switch'), + 'title' => __( + 'Select API Method', + 'mollie-payments-for-woocommerce' + ), + 'type' => 'select', + 'options' => [ + PaymentService::PAYMENT_METHOD_TYPE_ORDER => ucfirst( + PaymentService::PAYMENT_METHOD_TYPE_ORDER + ) . ' (' . __('default', 'mollie-payments-for-woocommerce') + . ')', + PaymentService::PAYMENT_METHOD_TYPE_PAYMENT => ucfirst( + PaymentService::PAYMENT_METHOD_TYPE_PAYMENT + ), + ], + 'default' => PaymentService::PAYMENT_METHOD_TYPE_ORDER, + 'desc' => sprintf( + /* translators: Placeholder 1: opening link tag, placeholder 2: closing link tag */ + __( + 'Click %1$shere%2$s to read more about the differences between the Payments and Orders API', + 'mollie-payments-for-woocommerce' + ), + '', + '' + ), + ], + [ + 'id' => $this->settings->getSettingId('api_payment_description'), + 'title' => __( + 'API Payment Description', + 'mollie-payments-for-woocommerce' + ), + 'type' => 'text', + 'default' => '{orderNumber}', + 'desc' => sprintf( + '

    +
    +

    %1$s:

    +
      + %2$s +
    +
    +
    +

    %3$s', + _x('Available variables', 'Payment description options', 'mollie-payments-for-woocommerce'), + implode('', array_map( + static function ($label, $labelDescription) { + return sprintf( + '

  • + +
  • ', + $label, + substr($label, 1, -1), + $labelDescription + ); + }, + array_keys($this->paymentDescriptionLabels()), + $this->paymentDescriptionLabels() + )), + sprintf( + /* translators: Placeholder 1: Opening paragraph tag, placeholder 2: Closing paragraph tag */ + __( + 'Select among the available variables the description to be used for this transaction.%1$s(Note: this only works when the method is set to Payments API)%2$s', + 'mollie-payments-for-woocommerce' + ), + '

    ', + '

    ' + ) + ), + ], + [ + 'id' => $this->settings->getSettingId('gatewayFeeLabel'), + 'title' => __( + 'Surcharge gateway fee label', + 'mollie-payments-for-woocommerce' + ), + 'type' => 'text', + 'custom_attributes' => ['maxlength' => '30'], + 'default' => __('Gateway Fee', 'mollie-payments-for-woocommerce'), + 'desc' => __( + 'This is the label will appear in frontend when the surcharge applies', + 'mollie-payments-for-woocommerce' + ), + ], + [ + 'id' => $this->settings->getSettingId('removeOptionsAndTransients'), + 'title' => __( + 'Remove Mollie data from Database on uninstall', + 'mollie-payments-for-woocommerce' + ), + 'type' => 'checkbox', + 'default' => 'no', + 'desc' => __("Remove options and scheduled actions from database when uninstalling the plugin.", "mollie-payments-for-woocommerce") . ' (' . strtolower( + __('Clear now', 'mollie-payments-for-woocommerce') + ) . ')', + ], + [ + 'id' => $this->settings->getSettingId('sectionend'), + 'type' => 'sectionend', + ], + ]; + + return apply_filters( + 'inpsyde.mollie-advanced-settings', + $config, + $this->settings->getPluginId() + ); + } + + protected function paymentDescriptionLabels(): array + { + + return [ + '{orderNumber}' => _x('Order number', 'Label {orderNumber} description for payment description options', 'mollie-payments-for-woocommerce'), + '{storeName}' => _x('Site Title', 'Label {storeName} description for payment description options', 'mollie-payments-for-woocommerce'), + '{customer.firstname}' => _x('Customer\'s first name', 'Label {customer.firstname} description for payment description options', 'mollie-payments-for-woocommerce'), + '{customer.lastname}' => _x('Customer\'s last name', 'Label {customer.lastname} description for payment description options', 'mollie-payments-for-woocommerce'), + '{customer.company}' => _x('Customer\'s company name', 'Label {customer.company} description for payment description options', 'mollie-payments-for-woocommerce'), + ]; + } + + protected function cleanDbUrl(): string + { + + return add_query_arg( + ['cleanDB-mollie' => 1, 'nonce_mollie_cleanDb' => wp_create_nonce('nonce_mollie_cleanDb')] + ); + } + + protected function content(): string + { + ob_start(); + ?> + $this->settings->getSettingId('title'), + 'title' => '', + 'type' => 'title', + ], + $this->connectionStatusField($this->settings, $this->connectionStatus), + [ + 'id' => $this->settings->getSettingId('test_mode_enabled'), + 'title' => __('Mollie Payment Mode', 'mollie-payments-for-woocommerce'), + 'default' => 'no', + 'type' => 'select', + 'options' => [ + 'no' => 'Live API', + 'yes' => 'Test API', + ], + 'desc' => __( + 'Select Live API to receive real payments and Test API to test transactions without a fee.', + 'mollie-payments-for-woocommerce' + ), + 'desc_tip' => __( + 'Enable test mode if you want to test the plugin without using real payments.', + 'mollie-payments-for-woocommerce' + ), + ], + [ + 'id' => $this->settings->getSettingId('live_api_key'), + 'title' => __('Live API key', 'mollie-payments-for-woocommerce'), + 'default' => '', + 'type' => 'text', + 'desc' => sprintf( + __( + "Use your Live API key when you're ready to receive real payments.", + 'mollie-payments-for-woocommerce' + ), + 'https://my.mollie.com/dashboard/developers/api-keys?utm_source=woocommerce&utm_medium=plugin&utm_campaign=partner' + ), + 'css' => 'width: 350px', + 'placeholder' => __( + 'Live API key should start with live_', + 'mollie-payments-for-woocommerce' + ), + ], + [ + 'id' => $this->settings->getSettingId('test_api_key'), + 'title' => __('Test API key', 'mollie-payments-for-woocommerce'), + 'default' => '', + 'type' => 'text', + 'desc' => sprintf( + __( + "Use your Test APl key to check the connection and test transactions without a fee.", + 'mollie-payments-for-woocommerce' + ), + 'https://my.mollie.com/dashboard/developers/api-keys?utm_source=woocommerce&utm_medium=plugin&utm_campaign=partner' + ), + 'css' => 'width: 350px', + 'placeholder' => __( + 'Test API key should start with test_', + 'mollie-payments-for-woocommerce' + ), + ], + [ + 'id' => $this->settings->getSettingId('sectionend'), + 'type' => 'sectionend', + ], + ]; + } +} diff --git a/src/Settings/Page/Section/ConnectionStatusFields.php b/src/Settings/Page/Section/ConnectionStatusFields.php new file mode 100644 index 000000000..68312324d --- /dev/null +++ b/src/Settings/Page/Section/ConnectionStatusFields.php @@ -0,0 +1,46 @@ + $this->settings->getSettingId('title'), + 'title' => '', + 'type' => 'title', + ], + $this->connectionStatusField($this->settings, $this->connectionStatus), + $this->refreshStatusField(), + [ + 'id' => $this->settings->getSettingId('sectionend'), + 'type' => 'sectionend', + ], + ]; + } + + public function refreshStatusField(): array + { + $refreshNonce = wp_create_nonce('nonce_mollie_refresh_methods'); + $refreshUrl = add_query_arg( + ['refresh-methods' => 1, 'nonce_mollie_refresh_methods' => $refreshNonce] + ); + + return [ + 'id' => $this->settings->getSettingId('refresh_status'), + 'title' => __('Payment method availability', 'mollie-payments-for-woocommerce'), + 'value' => '' . __('Refresh Mollie payment methods', 'mollie-payments-for-woocommerce') . '', + 'desc' => __( + 'Click this button to refresh your payment methods, e.g. if you recently enabled new payment methods in your Mollie profile', + 'mollie-payments-for-woocommerce' + ), + 'type' => 'mollie_custom_input', + ]; + } +} diff --git a/src/Settings/Page/Section/ConnectionStatusTrait.php b/src/Settings/Page/Section/ConnectionStatusTrait.php new file mode 100644 index 000000000..2639fd9b5 --- /dev/null +++ b/src/Settings/Page/Section/ConnectionStatusTrait.php @@ -0,0 +1,36 @@ + $settings->getSettingId('connection_status'), + 'title' => __('Mollie Connection Status', 'mollie-payments-for-woocommerce'), + 'value' => $this->connectionStatus($settings, $connectionStatus), + 'type' => 'mollie_custom_input', + ]; + } + + protected function connectionStatus(Settings $settings, bool $connectionStatus): ?string + { + $testMode = $settings->isTestModeEnabled(); + if (!$connectionStatus) { + return __( + 'Failed to connect to Mollie API - check your API keys ✖', + 'mollie-payments-for-woocommerce' + ); + } + if ($testMode) { + return __('Successfully connected with Test API ✓', 'mollie-payments-for-woocommerce'); + } + return __('Successfully connected with Live API ✓', 'mollie-payments-for-woocommerce'); + } +} diff --git a/src/Settings/Page/Section/Header.php b/src/Settings/Page/Section/Header.php new file mode 100644 index 000000000..abfe91c8f --- /dev/null +++ b/src/Settings/Page/Section/Header.php @@ -0,0 +1,84 @@ + $this->settings->getSettingId('header'), + 'type' => 'mollie_content', + 'value' => $this->content(), + ], + ]; + } + + public function styles(): string + { + ob_start(); + ?> + + +
    +
    + +

    + + + +

    + +
    +
    + $this->settings->getSettingId('instructions'), + 'type' => 'mollie_content', + 'value' => $this->content(), + ], + ]; + } + + protected function content(): string + { + ob_start(); + ?> +

    +

    + API key.", + 'mollie-payments-for-woocommerce' + ), + 'https://my.mollie.com/dashboard/developers/api-keys?utm_source=woocommerce&utm_medium=plugin&utm_campaign=partner' + ), [ + 'a' => [ + 'target' => [], + 'href' => [], + ], + ]); ?> +

    +

    + +

    + $this->settings->getSettingId('instructions'), + 'type' => 'mollie_content', + 'value' => $this->content(), + ], + ]; + } + + protected function content(): string + { + ob_start(); + ?> +

    +

    + +

    +

    + + + +

    +
      +
    1. + Mollie Dashboard", + 'mollie-payments-for-woocommerce' + ), + 'https://my.mollie.com/dashboard/login?lang=en' + ), [ + 'a' => [ + 'href' => [], + 'target' => [], + ], + ]); ?> +
    2. +
    3. + Developers > API keys.", 'mollie-payments-for-woocommerce'), + [ + 'strong' => [], + ] + ); ?> +
    4. +
    5. + Copy next to your API key.", 'mollie-payments-for-woocommerce'), + [ + 'strong' => [], + ] + ); ?> +
    6. +
    7. + Live API key or Test API key fields below.", + 'mollie-payments-for-woocommerce' + ), + [ + 'strong' => [], + ] + ); ?> +
    8. +
    +

    + +

    + $this->settings->getSettingId('notices'), + 'type' => 'mollie_content', + 'value' => $this->content(), + ], + ]; + } + + protected function content(): string + { + ob_start(); + ?> +
    + warnAboutRequiredCheckoutFieldForBillie(); // WPCS: XSS ok. ?> + warnAboutRequiredCheckoutFieldForKlarna(); // WPCS: XSS ok. ?> + warnMollieBankTransferNotBACS(); // WPCS: XSS ok. ?> + warnDirectDebitStatus(); // WPCS: XSS ok. ?> +
    + paymentMethods["directdebit"]->getProperty('enabled') !== false; + $isSepaEnabled = !$hasCustomSepaSettings || $this->paymentMethods["directdebit"]->getProperty( + 'enabled' + ) === 'yes'; + $sepaGatewayAllowed = !empty($this->mollieGateways["mollie_wc_gateway_directdebit"]); + + if (!($sepaGatewayAllowed && !$isSepaEnabled)) { + return ''; + } + return $this->notice( + __( + "You have WooCommerce Subscriptions activated, but not SEPA Direct Debit. Enable SEPA Direct Debit if you want to allow customers to pay subscriptions with iDEAL and/or other 'first' payment methods.", + 'mollie-payments-for-woocommerce' + ) + ); + } + + protected function warnAboutRequiredCheckoutFieldForBillie(): string + { + $isBillieEnabled = array_key_exists('mollie_wc_gateway_billie', $this->mollieGateways) + && array_key_exists('billie', $this->paymentMethods) + && $this->paymentMethods['billie']->getProperty('enabled') === 'yes'; + + if (!$isBillieEnabled) { + return ''; + } + return $this->notice( + __( + 'You have activated Billie. To accept payments, please make sure all default WooCommerce checkout fields are enabled and required. The billing company field is required as well. Make sure to enable the billing company field in the WooCommerce settings if you are using Woocommerce blocks.', + 'mollie-payments-for-woocommerce' + ) + ); + } + + protected function warnAboutRequiredCheckoutFieldForKlarna(): string + { + if (!$this->isKlarnaEnabled()) { + return ''; + } + return $this->notice( + sprintf( + /* translators: Placeholder 1: Opening link tag. Placeholder 2: Closing link tag. Placeholder 3: Opening link tag. Placeholder 4: Closing link tag. */ + __( + 'You have activated Klarna. To accept payments, please make sure all default WooCommerce checkout fields are enabled and required. For more information, go to %1$sKlarna Pay Later documentation%2$s or %3$sKlarna Slice it documentation%4$s', + 'mollie-payments-for-woocommerce' + ), + '', + '', + '', + '' + ) + ); + } + + protected function warnMollieBankTransferNotBACS(): string + { + $woocommerceBanktransferGateway = new WC_Gateway_BACS(); + if (!$woocommerceBanktransferGateway->is_available()) { + return ''; + } + + return $this->notice( + __( + 'You have the WooCommerce default Direct Bank Transfer (BACS) payment gateway enabled in WooCommerce. Mollie strongly advices only using Bank Transfer via Mollie and disabling the default WooCommerce BACS payment gateway to prevent possible conflicts.', + 'mollie-payments-for-woocommerce' + ) + ); + } + + protected function isKlarnaEnabled(): bool + { + $klarnaGateways = [ + Constants::KLARNAPAYLATER, + Constants::KLARNASLICEIT, + Constants::KLARNAPAYNOW, + Constants::KLARNA, + ]; + $isKlarnaEnabled = false; + foreach ($klarnaGateways as $klarnaGateway) { + if ( + array_key_exists('mollie_wc_gateway_' . $klarnaGateway, $this->mollieGateways) + && array_key_exists($klarnaGateway, $this->paymentMethods) + && $this->paymentMethods[$klarnaGateway]->getProperty('enabled') === 'yes' + ) { + $isKlarnaEnabled = true; + break; + } + } + return $isKlarnaEnabled; + } + + protected function notice(string $message) + { + //notice-warning is-dismissible + ob_start(); + ?> +
    +

    + [ + 'href' => [], + 'target' => [], + ], + ]); ?> +

    + +
    + + + $this->settings->getSettingId('notices'), + 'type' => 'mollie_content', + 'value' => $this->content(), + ], + ]; + } + + protected function content(): string + { + ob_start(); + ?> +
    +
    + renderGateways(); // WPCS: XSS ok. ?> +
    +
    + refreshIfRequested(); + $this->cleanDbIfRequested(); + + $titleActivePaymentMethods = __( + 'Currently Active Payment Methods', + 'mollie-payments-for-woocommerce' + ); + $descriptionActivePaymentMethods = __( + 'These payment methods are active in your Mollie profile. + You can enable these payment methods in their settings to make them available for your customers.', + 'mollie-payments-for-woocommerce' + ); + $titleInactivePaymentMethods = __('Inactive Payment Methods', 'mollie-payments-for-woocommerce'); + $descriptionInactivePaymentMethods = __( + 'These payment methods are available in your Mollie profile but are + not currently active. Activate them to offer more payment options to your customers.', + 'mollie-payments-for-woocommerce' + ); + + $activatedGateways = ''; + $deactivatedGateways = ''; + + /** @var AbstractPaymentMethod $paymentMethod */ + foreach ($this->paymentMethods as $paymentMethod) { + $paymentMethodId = $paymentMethod->getProperty('id'); + $gatewayKey = 'mollie_wc_gateway_' . $paymentMethodId; + $enabledInMollie = array_key_exists($gatewayKey, $this->mollieGateways); + + $paymentGatewayButton = $this->paymentGatewayButton($paymentMethod, $enabledInMollie); + if ($enabledInMollie) { + $activatedGateways .= $paymentGatewayButton; + } else { + $deactivatedGateways .= $paymentGatewayButton; + } + } + + return $this->paymentGatewaysBlock( + $titleActivePaymentMethods, + $descriptionActivePaymentMethods, + $activatedGateways + ) . $this->paymentGatewaysBlock( + $titleInactivePaymentMethods, + $descriptionInactivePaymentMethods, + $deactivatedGateways + ); + } + + protected function paymentGatewaysBlock(string $title, string $description, string $html): string + { + ob_start(); + ?> +
    +

    +

    +
    + +
    +
    + + + + testModeEnabled; + $apiKey = $this->settings->getApiKey(); + /* Reload active Mollie methods */ + $methods = $this->dataHelper->getAllPaymentMethods($apiKey, $testMode, false); + foreach ($methods as $key => $method) { + $methods['mollie_wc_gateway_' . $method['id']] = $method; + unset($methods[$key]); + } + $this->mollieGateways = $methods; + } + } + + protected function cleanDbIfRequested() + { + if ( + isset($_GET['cleanDB-mollie']) && wp_verify_nonce( + filter_input(INPUT_GET, 'nonce_mollie_cleanDb', FILTER_SANITIZE_SPECIAL_CHARS), + 'nonce_mollie_cleanDb' + ) + ) { + $cleaner = $this->settings->cleanDb(); + $cleaner->cleanAll(); + //set default settings + foreach ($this->paymentMethods as $paymentMethod) { + $paymentMethod->getSettings(); + } + } + } + + protected function paymentGatewayButton(AbstractPaymentMethod $paymentMethod, $enabledInMollie): string + { + $documentationLink = $paymentMethod->getProperty('docs'); + $paymentMethodId = $paymentMethod->getProperty('id'); + $gatewayKey = 'mollie_wc_gateway_' . $paymentMethodId; + $button = '' . esc_html(__( + 'Manage Payment Method', + 'mollie-payments-for-woocommerce' + )) . ''; + $messageOrLink = ''; + $enabledInWoo = ($paymentMethod->getSettings())['enabled'] === 'yes'; + + if ($enabledInMollie && $enabledInWoo) { + $messageOrLink = '' . esc_html(__( + 'enabled', + 'mollie-payments-for-woocommerce' + )) . ''; + } elseif ($enabledInMollie && !$enabledInWoo) { + $messageOrLink = '' . esc_html(__( + 'disabled', + 'mollie-payments-for-woocommerce' + )) . ''; + } else { + if ($documentationLink) { + $messageOrLink = "" . esc_html(__( + 'More information', + 'mollie-payments-for-woocommerce' + )) . ''; + } + $button = '' . + esc_html(__('Activate Payment Method', 'mollie-payments-for-woocommerce')) + . ''; + } + + ob_start(); + ?> +
    + getIconUrl(); // WPCS: XSS ok.?> + title());?> + + +
    + $this->settings->getSettingId('notices'), + 'type' => 'mollie_content', + 'value' => $this->content(), + ], + ]; + } + + protected function content(): string + { + + $content = ''; + + return $content; + } + + protected function pageUrl(string $sectionId): string + { + return admin_url('admin.php?page=wc-settings&tab=mollie_settings§ion=' . sanitize_title($sectionId)); + } +} diff --git a/src/Settings/Settings.php b/src/Settings/Settings.php index c93589641..2d03aa453 100644 --- a/src/Settings/Settings.php +++ b/src/Settings/Settings.php @@ -332,7 +332,7 @@ public function isDebugEnabled() /** * @return string */ - public function getLogsUrl() + public function getLogsUrl(): string { return admin_url('admin.php?page=wc-status&tab=logs'); } @@ -384,6 +384,24 @@ public function updateMerchantIdAfterApiKeyChanges($oldValue, $value, $optionNam $this->updateMerchantIdOnApiKeyChanges($value, $option); } + public function getConnectionStatus(): bool + { + + $status = $this->statusHelper; + if (!$status->isCompatible()) { + return false; + } + + try { + $apiKey = $this->getApiKey(); + $apiClient = $this->apiHelper->getApiClient($apiKey); + $status->getMollieApiStatus($apiClient); + return true; + } catch (\Mollie\Api\Exceptions\ApiException $e) { + return false; + } + } + /** * Get plugin status * @@ -447,6 +465,10 @@ public function getPaymentConfirmationCheckTime() return $date->getTimestamp(); } + public function getPluginId() + { + return $this->pluginId; + } /** * @param string $setting * diff --git a/src/Settings/SettingsModule.php b/src/Settings/SettingsModule.php index 5cac11b53..61ecb6632 100644 --- a/src/Settings/SettingsModule.php +++ b/src/Settings/SettingsModule.php @@ -6,15 +6,14 @@ namespace Mollie\WooCommerce\Settings; -use Inpsyde\Modularity\Module\ExecutableModule; -use Inpsyde\Modularity\Module\ModuleClassNameIdTrait; -use Inpsyde\Modularity\Module\ServiceModule; use Mollie\WooCommerce\Notice\AdminNotice; use Mollie\WooCommerce\SDK\Api; -use Mollie\WooCommerce\Settings\Page\MollieSettingsPage; use Mollie\WooCommerce\Shared\Data; use Mollie\WooCommerce\Shared\Status; use Mollie\WooCommerce\Uninstall\CleanDb; +use Inpsyde\Modularity\Module\ExecutableModule; +use Inpsyde\Modularity\Module\ModuleClassNameIdTrait; +use Inpsyde\Modularity\Module\ServiceModule; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface as Logger; @@ -113,6 +112,7 @@ public function run(ContainerInterface $container): bool $this->dataHelper = $container->get('settings.data_helper'); assert($this->dataHelper instanceof Data); $pluginPath = $container->get('shared.plugin_path'); + $pluginUrl = $container->get('shared.plugin_url'); $paymentMethods = $container->get('gateway.paymentMethods'); // Add settings link to plugins page @@ -148,7 +148,7 @@ function () use ($optionName, $defaultAdvancedOptions, $defaultComponentsOptions $gateways = $container->get('gateway.instances'); $isSDDGatewayEnabled = $container->get('gateway.isSDDGatewayEnabled'); - $this->initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $paymentMethods); + $this->initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $pluginUrl, $paymentMethods); add_action( 'woocommerce_admin_settings_sanitize_option', [$this->settingsHelper, 'updateMerchantIdOnApiKeyChanges'], @@ -194,7 +194,8 @@ public function addPluginActionLinks(array $links): array public function maybeTestModeNotice(): bool { $testModeEnabled = get_option('mollie-payments-for-woocommerce_test_mode_enabled', true); - $shouldShowNotice = $testModeEnabled === 'yes'; + $testKeyEntered = get_option('mollie-payments-for-woocommerce_test_api_key', true); + $shouldShowNotice = $testModeEnabled === 'yes' && !empty($testKeyEntered); if (!$shouldShowNotice) { return false; } @@ -247,10 +248,11 @@ public function maybeSaveDefaultSettings($optionName, $testOption, $defaultOptio * @param $isSDDGatewayEnabled * @param $gateways * @param $pluginPath + * @param $pluginUrl * @param $paymentMethods * @return void */ - protected function initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $paymentMethods): void + protected function initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $pluginUrl, $paymentMethods): void { if (!$isSDDGatewayEnabled) { //remove directdebit gateway from gateways list @@ -258,10 +260,11 @@ protected function initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $plug } add_filter( 'woocommerce_get_settings_pages', - function ($settings) use ($pluginPath, $gateways, $paymentMethods) { + function ($settings) use ($pluginPath, $pluginUrl, $gateways, $paymentMethods) { $settings[] = new MollieSettingsPage( $this->settingsHelper, $pluginPath, + $pluginUrl, $gateways, $paymentMethods, $this->isTestModeEnabled, diff --git a/webpack.config.js b/webpack.config.js index fbd545086..19805a960 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -31,7 +31,8 @@ function configJavaScript ({ basePath }) .addEntry('paypalButtonBlockComponent.min', './resources/js/paypalButtonBlockComponent.js') .addEntry('applepayButtonBlockComponent.min', './resources/js/applepayButtonBlockComponent.js') .addEntry('rivertyCountryPlaceholder.min', './resources/js/rivertyCountryPlaceholder.js') - .enableSourceMaps(!Encore.isProduction()) + .addEntry('mollie-settings-2024.min', './resources/js/mollie-settings-2024.js') + .enableSourceMaps(!Encore.isProduction()) return extractEncoreConfig('javascript-configuration') } From e5969a9577e550adfbcf145ea307a7bb997fa6a0 Mon Sep 17 00:00:00 2001 From: carmenmaymo Date: Mon, 4 Nov 2024 14:21:04 +0100 Subject: [PATCH 2/7] Squash and merge PIWOO-319 This PR adds Apple express button --- inc/settings/mollie_applepay_settings.php | 0 package.json | 2 +- resources/js/applepayButtonBlock.js | 30 +++ resources/js/applepayButtonBlockComponent.js | 194 ------------------ .../js/blocks/ApplePayButtonComponent.js | 185 +++++++++++++++++ resources/js/mollieBlockIndex.js | 18 ++ resources/scss/mollie-applepaydirect.scss | 25 +++ src/Assets/AssetsModule.php | 4 +- src/Assets/MollieCheckoutBlocksSupport.php | 38 ++-- .../ApplePayButton/AppleAjaxRequests.php | 4 +- .../DataToAppleButtonScripts.php | 3 + .../ApplePayButton/ResponsesToApple.php | 30 ++- src/PaymentMethods/Applepay.php | 8 +- src/Shared/Data.php | 7 + .../DataToAppleButtonScriptsTest.php | 2 + .../ApplePayButton/ResponsesToAppleTest.php | 9 +- webpack.config.js | 2 +- 17 files changed, 336 insertions(+), 225 deletions(-) create mode 100644 inc/settings/mollie_applepay_settings.php create mode 100644 resources/js/applepayButtonBlock.js delete mode 100644 resources/js/applepayButtonBlockComponent.js create mode 100644 resources/js/blocks/ApplePayButtonComponent.js diff --git a/inc/settings/mollie_applepay_settings.php b/inc/settings/mollie_applepay_settings.php new file mode 100644 index 000000000..e69de29bb diff --git a/package.json b/package.json index d5429a333..a97339a4a 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "webpack": "^5.89.0" }, "scripts": { - "watch": "webpack --watch", + "watch": "BASE_PATH=. node_modules/.bin/encore dev --watch", "build": "BASE_PATH=. node_modules/.bin/encore dev", "setup": "gulp setup", "e2e-activation": "npx playwright test --project=activation", diff --git a/resources/js/applepayButtonBlock.js b/resources/js/applepayButtonBlock.js new file mode 100644 index 000000000..058da50c7 --- /dev/null +++ b/resources/js/applepayButtonBlock.js @@ -0,0 +1,30 @@ +import {ApplePayButtonComponent} from "./blocks/ApplePayButtonComponent"; + +( + function ({mollieApplePayBlockDataCart}) { + if (mollieApplePayBlockDataCart.length === 0) { + return + } + const {ApplePaySession} = window; + if (!(ApplePaySession && ApplePaySession.canMakePayments())) { + return null; + } + + const {registerExpressPaymentMethod} = wc.wcBlocksRegistry; + + registerExpressPaymentMethod({ + name: 'mollie_wc_gateway_applepay_express', + content: < ApplePayButtonComponent/>, + edit: < ApplePayButtonComponent/>, + ariaLabel: 'Apple Pay', + canMakePayment: () => true, + paymentMethodId: 'mollie_wc_gateway_applepay', + supports: { + features: ['products'], + }, + }); + } +) +( + window +) diff --git a/resources/js/applepayButtonBlockComponent.js b/resources/js/applepayButtonBlockComponent.js deleted file mode 100644 index 7c0215c6e..000000000 --- a/resources/js/applepayButtonBlockComponent.js +++ /dev/null @@ -1,194 +0,0 @@ -import {maybeShowButton} from './maybeShowApplePayButton.js'; -import {request} from "./applePayRequest"; -import {createAppleErrors} from "./applePayError"; - -( - function ({mollieApplePayBlockDataCart}) - { - if (mollieApplePayBlockDataCart.length === 0 ) { - return - } - const {product: {needShipping = true, subtotal}, shop: {countryCode, currencyCode = 'EUR', totalLabel = ''}, buttonMarkup, ajaxUrl} = mollieApplePayBlockDataCart - - const { registerPlugin } = wp.plugins; - const { ExperimentalOrderMeta } = wc.blocksCheckout; - const ApplePayButtonComponent = ( { cart, extensions } ) => { - return
    - } - const MollieApplePayButtonCart = () => { - return - - - }; - - registerPlugin( 'mollie-applepay-block-button', { - render: () => { - return ; - }, - scope: 'woocommerce-checkout' - } ); - - setTimeout(function(){ - if(!maybeShowButton()){ - return - } - const nonce = document.getElementById("woocommerce-process-checkout-nonce").value - let updatedContactInfo = [] - let selectedShippingMethod = [] - let redirectionUrl = '' - let applePaySession = () => { - const session = new ApplePaySession(3, request(countryCode, currencyCode, totalLabel, subtotal)) - session.begin() - session.onshippingmethodselected = function (event) { - jQuery.ajax({ - url: ajaxUrl, - method: 'POST', - data: { - action: 'mollie_apple_pay_update_shipping_method', - shippingMethod: event.shippingMethod, - callerPage: 'cart', - simplifiedContact: updatedContactInfo, - 'woocommerce-process-checkout-nonce': nonce, - }, - complete: (jqXHR, textStatus) => { - }, - success: (applePayShippingMethodUpdate, textStatus, jqXHR) => { - let response = applePayShippingMethodUpdate.data - selectedShippingMethod = event.shippingMethod - if (applePayShippingMethodUpdate.success === false) { - response.errors = createAppleErrors(response.errors) - } - this.completeShippingMethodSelection(response) - }, - error: (jqXHR, textStatus, errorThrown) => { - console.warn(textStatus, errorThrown) - session.abort() - }, - }) - } - session.onshippingcontactselected = function (event) { - jQuery.ajax({ - url: ajaxUrl, - method: 'POST', - data: { - action: 'mollie_apple_pay_update_shipping_contact', - simplifiedContact: event.shippingContact, - callerPage: 'cart', - needShipping: needShipping, - 'woocommerce-process-checkout-nonce': nonce, - }, - complete: (jqXHR, textStatus) => { - }, - success: (applePayShippingContactUpdate, textStatus, jqXHR) => { - let response = applePayShippingContactUpdate.data - updatedContactInfo = event.shippingContact - if (applePayShippingContactUpdate.success === false) { - response.errors = createAppleErrors(response.errors) - } - if (response.newShippingMethods) { - selectedShippingMethod = response.newShippingMethods[0] - } - this.completeShippingContactSelection(response) - }, - error: (jqXHR, textStatus, errorThrown) => { - console.warn(textStatus, errorThrown) - session.abort() - }, - }) - } - session.onvalidatemerchant = (applePayValidateMerchantEvent) => { - jQuery.ajax({ - url: ajaxUrl, - method: 'POST', - data: { - action: 'mollie_apple_pay_validation', - validationUrl: applePayValidateMerchantEvent.validationURL, - 'woocommerce-process-checkout-nonce': nonce, - }, - complete: (jqXHR, textStatus) => { - }, - success: (merchantSession, textStatus, jqXHR) => { - if (merchantSession.success === true) { - session.completeMerchantValidation(JSON.parse(merchantSession.data)) - } else { - console.warn(merchantSession.data) - session.abort() - } - }, - error: (jqXHR, textStatus, errorThrown) => { - console.warn(textStatus, errorThrown) - session.abort() - }, - }) - } - session.onpaymentauthorized = (ApplePayPayment) => { - const {billingContact, shippingContact } = ApplePayPayment.payment - - jQuery.ajax({ - url: ajaxUrl, - method: 'POST', - data: { - action: 'mollie_apple_pay_create_order_cart', - shippingContact: ApplePayPayment.payment.shippingContact, - billingContact: ApplePayPayment.payment.billingContact, - token: ApplePayPayment.payment.token, - shippingMethod: selectedShippingMethod, - 'mollie-payments-for-woocommerce_issuer_applepay': 'applepay', - 'woocommerce-process-checkout-nonce': nonce, - 'billing_first_name': billingContact.givenName || '', - 'billing_last_name': billingContact.familyName || '', - 'billing_company': '', - 'billing_country': billingContact.countryCode || '', - 'billing_address_1': billingContact.addressLines[0] || '', - 'billing_address_2': billingContact.addressLines[1] || '', - 'billing_postcode': billingContact.postalCode || '', - 'billing_city': billingContact.locality || '', - 'billing_state': billingContact.administrativeArea || '', - 'billing_phone': billingContact.phoneNumber || '000000000000', - 'billing_email': shippingContact.emailAddress || '', - 'shipping_first_name': shippingContact.givenName || '', - 'shipping_last_name': shippingContact.familyName || '', - 'shipping_company': '', - 'shipping_country': shippingContact.countryCode || '', - 'shipping_address_1': shippingContact.addressLines[0] || '', - 'shipping_address_2': shippingContact.addressLines[1] || '', - 'shipping_postcode': shippingContact.postalCode || '', - 'shipping_city': shippingContact.locality || '', - 'shipping_state': shippingContact.administrativeArea || '', - 'shipping_phone': shippingContact.phoneNumber || '000000000000', - 'shipping_email': shippingContact.emailAddress || '', - 'order_comments' : '', - 'payment_method' : 'mollie_wc_gateway_applepay', - '_wp_http_referer' : '/?wc-ajax=update_order_review' - }, - complete: (jqXHR, textStatus) => { - - }, - success: (authorizationResult, textStatus, jqXHR) => { - let result = authorizationResult.data - if (authorizationResult.success === true) { - redirectionUrl = result['returnUrl']; - session.completePayment(result['responseToApple']) - window.location.href = redirectionUrl - } else { - result.errors = createAppleErrors(result.errors) - session.completePayment(result) - } - }, - error: (jqXHR, textStatus, errorThrown) => { - console.warn(textStatus, errorThrown) - session.abort() - }, - }) - } - } - document.querySelector('#mollie_applepay_button').addEventListener('click', (evt) => { - applePaySession() - }) - },2000); - - } -) -( - window -) diff --git a/resources/js/blocks/ApplePayButtonComponent.js b/resources/js/blocks/ApplePayButtonComponent.js new file mode 100644 index 000000000..d712477cf --- /dev/null +++ b/resources/js/blocks/ApplePayButtonComponent.js @@ -0,0 +1,185 @@ +import {request} from "../applePayRequest"; +import {createAppleErrors} from "../applePayError"; + +export const ApplePayButtonComponent = ({cart, extensions}) => { + const mollieApplePayBlockDataCart = window.mollieApplePayBlockDataCart || window.mollieBlockData.mollieApplePayBlockDataCart + const nonce = document.getElementById("woocommerce-process-checkout-nonce").value + let updatedContactInfo = [] + let redirectionUrl = '' + const { + product: {needShipping = true, subtotal}, + shop: {countryCode, currencyCode = 'EUR', totalLabel = ''}, + ajaxUrl, + } = mollieApplePayBlockDataCart + + const findSelectedShippingMethod = (shippingRates) => { + let shippingRate = shippingRates.find((shippingMethod) => shippingMethod.selected === true) + const appleFormattedRate = { + amount: '', + detail: '', + label: shippingRate.name, + identifier: shippingRate.rate_id, + selected: shippingRate.selected, + } + return shippingRate ? appleFormattedRate : '' + } + + let applePaySession = () => { + const session = new ApplePaySession(3, request(countryCode, currencyCode, totalLabel, subtotal)) + const store = wp.data.select('wc/store/cart') + const shippingRates = store.getShippingRates()?.[0]?.shipping_rates; + let selectedShippingMethod = ''; + if (shippingRates && shippingRates.length > 0) { + selectedShippingMethod = findSelectedShippingMethod(shippingRates, selectedShippingMethod); + } + session.onshippingmethodselected = function (event) { + jQuery.ajax({ + url: ajaxUrl, + method: 'POST', + data: { + action: 'mollie_apple_pay_update_shipping_method', + shippingMethod: event.shippingMethod, + callerPage: 'cart', + simplifiedContact: updatedContactInfo, + 'woocommerce-process-checkout-nonce': nonce, + }, + success: (applePayShippingMethodUpdate, textStatus, jqXHR) => { + let response = applePayShippingMethodUpdate.data + selectedShippingMethod = event.shippingMethod + if (applePayShippingMethodUpdate.success === false) { + response.errors = createAppleErrors(response.errors) + } + this.completeShippingMethodSelection(response) + }, + error: (jqXHR, textStatus, errorThrown) => { + console.warn(textStatus, errorThrown) + session.abort() + }, + }) + } + session.onshippingcontactselected = function (event) { + jQuery.ajax({ + url: ajaxUrl, + method: 'POST', + data: { + action: 'mollie_apple_pay_update_shipping_contact', + simplifiedContact: event.shippingContact, + callerPage: 'cart', + needShipping: needShipping, + 'woocommerce-process-checkout-nonce': nonce, + shippingMethod: selectedShippingMethod, + }, + success: (applePayShippingContactUpdate, textStatus, jqXHR) => { + let response = applePayShippingContactUpdate.data + updatedContactInfo = event.shippingContact + if (applePayShippingContactUpdate.success === false) { + response.errors = createAppleErrors(response.errors) + } + if (response.newShippingMethods) { + selectedShippingMethod = response.newShippingMethods[0] + } + this.completeShippingContactSelection(response) + }, + error: (jqXHR, textStatus, errorThrown) => { + console.warn(textStatus, errorThrown) + session.abort() + }, + }) + } + session.onvalidatemerchant = (applePayValidateMerchantEvent) => { + jQuery.ajax({ + url: ajaxUrl, + method: 'POST', + data: { + action: 'mollie_apple_pay_validation', + validationUrl: applePayValidateMerchantEvent.validationURL, + 'woocommerce-process-checkout-nonce': nonce, + }, + success: (merchantSession, textStatus, jqXHR) => { + if (merchantSession.success === true) { + session.completeMerchantValidation(JSON.parse(merchantSession.data)) + } else { + console.warn(merchantSession.data) + session.abort() + } + }, + error: (jqXHR, textStatus, errorThrown) => { + console.warn(textStatus, errorThrown) + session.abort() + }, + }) + } + session.onpaymentauthorized = (ApplePayPayment) => { + const {billingContact, shippingContact} = ApplePayPayment.payment + + jQuery.ajax({ + url: ajaxUrl, + method: 'POST', + data: { + action: 'mollie_apple_pay_create_order_cart', + shippingContact: ApplePayPayment.payment.shippingContact, + billingContact: ApplePayPayment.payment.billingContact, + token: ApplePayPayment.payment.token, + shippingMethod: selectedShippingMethod, + 'mollie-payments-for-woocommerce_issuer_applepay': 'applepay', + 'woocommerce-process-checkout-nonce': nonce, + 'billing_first_name': billingContact.givenName || '', + 'billing_last_name': billingContact.familyName || '', + 'billing_company': '', + 'billing_country': billingContact.countryCode || '', + 'billing_address_1': billingContact.addressLines[0] || '', + 'billing_address_2': billingContact.addressLines[1] || '', + 'billing_postcode': billingContact.postalCode || '', + 'billing_city': billingContact.locality || '', + 'billing_state': billingContact.administrativeArea || '', + 'billing_phone': billingContact.phoneNumber || '000000000000', + 'billing_email': shippingContact.emailAddress || '', + 'shipping_first_name': shippingContact.givenName || '', + 'shipping_last_name': shippingContact.familyName || '', + 'shipping_company': '', + 'shipping_country': shippingContact.countryCode || '', + 'shipping_address_1': shippingContact.addressLines[0] || '', + 'shipping_address_2': shippingContact.addressLines[1] || '', + 'shipping_postcode': shippingContact.postalCode || '', + 'shipping_city': shippingContact.locality || '', + 'shipping_state': shippingContact.administrativeArea || '', + 'shipping_phone': shippingContact.phoneNumber || '000000000000', + 'shipping_email': shippingContact.emailAddress || '', + 'order_comments': '', + 'payment_method': 'mollie_wc_gateway_applepay', + '_wp_http_referer': '/?wc-ajax=update_order_review' + }, + success: (authorizationResult, textStatus, jqXHR) => { + let result = authorizationResult.data + if (authorizationResult.success === true) { + redirectionUrl = result['returnUrl']; + session.completePayment(result['responseToApple']) + window.location.href = redirectionUrl + } else { + result.errors = createAppleErrors(result.errors) + session.completePayment(result) + } + }, + error: (jqXHR, textStatus, errorThrown) => { + console.warn(textStatus, errorThrown) + session.abort() + }, + }) + } + session.begin() + } + + return ( + + ); +} + +export default ApplePayButtonComponent; diff --git a/resources/js/mollieBlockIndex.js b/resources/js/mollieBlockIndex.js index 04c6d367b..fdfaa0141 100644 --- a/resources/js/mollieBlockIndex.js +++ b/resources/js/mollieBlockIndex.js @@ -1,10 +1,12 @@ import molliePaymentMethod from './blocks/molliePaymentMethod' +import ApplePayButtonComponent from './blocks/ApplePayButtonComponent' ( function ({ mollieBlockData, wc, _, jQuery}) { if (_.isEmpty(mollieBlockData)) { return; } + window.onload = (event) => { const { registerPaymentMethod } = wc.wcBlocksRegistry; const { checkoutData, defaultFields } = wc.wcSettings.allSettings; @@ -47,8 +49,24 @@ import molliePaymentMethod from './blocks/molliePaymentMethod' gatewayData.forEach(item => { let register = () => registerPaymentMethod(molliePaymentMethod(useEffect, ajaxUrl, filters, gatewayData, availableGateways, item, jQuery, requiredFields, isCompanyFieldVisible, isPhoneFieldVisible)); if (item.name === 'mollie_wc_gateway_applepay' && !isBlockEditor) { + const {isExpressEnabled} = item; if ((isAppleSession && window.ApplePaySession.canMakePayments())) { register(); + if (isExpressEnabled !== true) { + return; + } + const {registerExpressPaymentMethod} = wc.wcBlocksRegistry; + registerExpressPaymentMethod({ + name: 'mollie_wc_gateway_applepay_express', + content: , + edit: , + ariaLabel: 'Apple Pay', + canMakePayment: () => true, + paymentMethodId: 'mollie_wc_gateway_applepay', + supports: { + features: ['products'], + }, + }) } return; } diff --git a/resources/scss/mollie-applepaydirect.scss b/resources/scss/mollie-applepaydirect.scss index 0cb757d88..07e9ae8fd 100644 --- a/resources/scss/mollie-applepaydirect.scss +++ b/resources/scss/mollie-applepaydirect.scss @@ -3,10 +3,35 @@ } .apple-pay-button { display: inline-block; + width: 100%; -webkit-appearance: -apple-pay-button; -apple-pay-button-type: checkout; /* also: check-out, book, or subscribe */ } +@media (max-width: 480px) { + .apple-pay-button { + height: 41px; + min-height: 40px; + max-height: 47px; + } +} + +@media (min-width: 481px) and (max-width: 1024px) { + .apple-pay-button { + height: 48px; + min-height: 48px; + max-height: 55px; + } +} + +@media (min-width: 1025px) { + .apple-pay-button { + height: 56px; + min-height: 56px; + max-height: 64px; + } +} + .apple-pay-button-black { -apple-pay-button-style: black; } diff --git a/src/Assets/AssetsModule.php b/src/Assets/AssetsModule.php index b4312bad7..6a400719c 100644 --- a/src/Assets/AssetsModule.php +++ b/src/Assets/AssetsModule.php @@ -74,13 +74,13 @@ public function registerButtonsBlockScripts(string $pluginUrl, string $pluginPat 'mollie_applepayButtonBlock', $this->getPluginUrl( $pluginUrl, - '/public/js/applepayButtonBlockComponent.min.js' + '/public/js/applepayButtonBlock.min.js' ), [], (string) filemtime( $this->getPluginPath( $pluginPath, - '/public/js/applepayButtonBlockComponent.min.js' + '/public/js/applepayButtonBlock.min.js' ) ), true diff --git a/src/Assets/MollieCheckoutBlocksSupport.php b/src/Assets/MollieCheckoutBlocksSupport.php index 450f6b76f..16d2d7481 100644 --- a/src/Assets/MollieCheckoutBlocksSupport.php +++ b/src/Assets/MollieCheckoutBlocksSupport.php @@ -64,12 +64,13 @@ public function get_payment_method_script_handles(): array public static function localizeWCBlocksData($dataService, $gatewayInstances) { - + wp_enqueue_style('mollie-applepaydirect'); wp_localize_script( self::$scriptHandle, 'mollieBlockData', [ 'gatewayData' => self::gatewayDataForWCBlocks($dataService, $gatewayInstances), + 'mollieApplePayBlockDataCart' => $dataService->mollieApplePayBlockDataCart(), ] ); } @@ -112,26 +113,26 @@ public static function gatewayDataForWCBlocks(Data $dataService, array $gatewayI $isSepaEnabled = isset($gatewayInstances['mollie_wc_gateway_directdebit']) && $gatewayInstances['mollie_wc_gateway_directdebit']->enabled === 'yes'; /** @var MolliePaymentGateway $gateway */ foreach ($gatewayInstances as $gatewayKey => $gateway) { - $gatewayId = is_string($gateway->paymentMethod()->getProperty('id')) ? $gateway->paymentMethod( - )->getProperty('id') : ""; + $method = $gateway->paymentMethod(); + $gatewayId = is_string($method->getProperty('id')) ? $method->getProperty('id') : ""; if ($gateway->enabled !== 'yes' || ($gatewayId === 'directdebit' && !is_admin())) { continue; } - $content = $gateway->paymentMethod()->getProcessedDescriptionForBlock(); + $content = $method->getProcessedDescriptionForBlock(); $issuers = false; - if ($gateway->paymentMethod()->getProperty('paymentFields') === true) { - $paymentFieldsService = $gateway->paymentMethod()->paymentFieldsService(); - $paymentFieldsService->setStrategy($gateway->paymentMethod()); - $issuers = $gateway->paymentMethod()->paymentFieldsService()->getStrategyMarkup($gateway); + if ($method->getProperty('paymentFields') === true) { + $paymentFieldsService = $method->paymentFieldsService(); + $paymentFieldsService->setStrategy($method); + $issuers = $method->paymentFieldsService()->getStrategyMarkup($gateway); } if ($gatewayId === 'creditcard') { $content .= $issuers; $issuers = false; } - $title = $gateway->paymentMethod()->title(); + $title = $method->title(); $labelMarkup = "{$title}{$gateway->icon}"; - $hasSurcharge = $gateway->paymentMethod()->hasSurcharge(); + $hasSurcharge = $method->hasSurcharge(); $countryCodes = [ 'BE' => '+32xxxxxxxxx', 'NL' => '+316xxxxxxxx', @@ -154,15 +155,16 @@ public static function gatewayDataForWCBlocks(Data $dataService, array $gatewayI 'edit' => $content, 'paymentMethodId' => $gatewayKey, 'allowedCountries' => is_array( - $gateway->paymentMethod()->getProperty('allowed_countries') - ) ? $gateway->paymentMethod()->getProperty('allowed_countries') : [], - 'ariaLabel' => $gateway->paymentMethod()->getProperty('defaultDescription'), - 'supports' => self::gatewaySupportsFeatures($gateway->paymentMethod(), $isSepaEnabled), - 'errorMessage' => $gateway->paymentMethod()->getProperty('errorMessage'), - 'companyPlaceholder' => $gateway->paymentMethod()->getProperty('companyPlaceholder'), - 'phoneLabel' => $gateway->paymentMethod()->getProperty('phoneLabel'), + $method->getProperty('allowed_countries') + ) ? $method->getProperty('allowed_countries') : [], + 'ariaLabel' => $method->getProperty('defaultDescription'), + 'supports' => self::gatewaySupportsFeatures($method, $isSepaEnabled), + 'errorMessage' => $method->getProperty('errorMessage'), + 'companyPlaceholder' => $method->getProperty('companyPlaceholder'), + 'phoneLabel' => $method->getProperty('phoneLabel'), 'phonePlaceholder' => $phonePlaceholder, - 'birthdatePlaceholder' => $gateway->paymentMethod()->getProperty('birthdatePlaceholder'), + 'birthdatePlaceholder' => $method->getProperty('birthdatePlaceholder'), + 'isExpressEnabled' => $gatewayId === 'applepay' && $method->getProperty('mollie_apple_pay_button_enabled_express_checkout') === 'yes', ]; } $dataToScript['gatewayData'] = $gatewayData; diff --git a/src/Buttons/ApplePayButton/AppleAjaxRequests.php b/src/Buttons/ApplePayButton/AppleAjaxRequests.php index 59a82fb98..ec1b28b1a 100644 --- a/src/Buttons/ApplePayButton/AppleAjaxRequests.php +++ b/src/Buttons/ApplePayButton/AppleAjaxRequests.php @@ -191,7 +191,7 @@ public function updateShippingContact() } $paymentDetails = $this->whichCalculateTotals($applePayRequestDataObject); - $response = $this->responseTemplates->appleFormattedResponse($paymentDetails); + $response = $this->responseTemplates->appleFormattedResponse($paymentDetails, $applePayRequestDataObject); $this->responseTemplates->responseSuccess($response); } @@ -212,7 +212,7 @@ public function updateShippingMethod() $this->responseTemplates->responseWithDataErrors($applePayRequestDataObject->errors()); } $paymentDetails = $this->whichCalculateTotals($applePayRequestDataObject); - $response = $this->responseTemplates->appleFormattedResponse($paymentDetails); + $response = $this->responseTemplates->appleFormattedResponse($paymentDetails, $applePayRequestDataObject); $this->responseTemplates->responseSuccess($response); } diff --git a/src/Buttons/ApplePayButton/DataToAppleButtonScripts.php b/src/Buttons/ApplePayButton/DataToAppleButtonScripts.php index b6e551b25..d3e37ab1c 100644 --- a/src/Buttons/ApplePayButton/DataToAppleButtonScripts.php +++ b/src/Buttons/ApplePayButton/DataToAppleButtonScripts.php @@ -14,6 +14,9 @@ class DataToAppleButtonScripts */ public function applePayScriptData(bool $isBlock = false): array { + if (is_admin()) { + return []; + } $base_location = wc_get_base_location(); $shopCountryCode = $base_location['country']; $currencyCode = get_woocommerce_currency(); diff --git a/src/Buttons/ApplePayButton/ResponsesToApple.php b/src/Buttons/ApplePayButton/ResponsesToApple.php index b4b580c2b..2f9f34cde 100644 --- a/src/Buttons/ApplePayButton/ResponsesToApple.php +++ b/src/Buttons/ApplePayButton/ResponsesToApple.php @@ -84,11 +84,15 @@ public function responseWithDataErrors($errorList) * * @return array */ - public function appleFormattedResponse(array $paymentDetails) + public function appleFormattedResponse(array $paymentDetails, $applePayRequestDataObject) { $response = []; if ($paymentDetails['shippingMethods']) { - $response['newShippingMethods'] = $paymentDetails['shippingMethods']; + $selectedShippingMethod = $applePayRequestDataObject->shippingMethod(); + $response['newShippingMethods'] = $this->reorderShippingMethods( + $paymentDetails['shippingMethods'], + $selectedShippingMethod + ); } $response['newLineItems'] = $this->appleNewLineItemsResponse( @@ -101,6 +105,28 @@ public function appleFormattedResponse(array $paymentDetails) return $response; } + /** + * Reorders the shipping methods to have the selected shipping method on top so we see it as selected + * @param array $methods + * @param array $selectedShippingMethod + * @return array + */ + private function reorderShippingMethods(array $methods, array $selectedShippingMethod): array + { + $reordered_methods = []; + + foreach ($methods as $key => $method) { + if ($method['identifier'] === $selectedShippingMethod['identifier']) { + $reordered_methods[] = $method; + unset($methods[$key]); + break; + } + } + + return array_merge($reordered_methods, array_values($methods)); + } + + /** * Returns a success response to be handled by the script */ diff --git a/src/PaymentMethods/Applepay.php b/src/PaymentMethods/Applepay.php index b1ae1f9eb..226993aaf 100644 --- a/src/PaymentMethods/Applepay.php +++ b/src/PaymentMethods/Applepay.php @@ -33,7 +33,6 @@ public function getFormFields($generalFormFields): array $paymentMethodFormFieds = [ 'mollie_apple_pay_button_enabled_cart' => [ 'title' => __('Enable Apple Pay Button on Cart page', 'mollie-payments-for-woocommerce'), - /* translators: Placeholder 1: enabled or disabled */ 'desc' => __( 'Enable the Apple Pay direct buy button on the Cart page', 'mollie-payments-for-woocommerce' @@ -43,7 +42,6 @@ public function getFormFields($generalFormFields): array ], 'mollie_apple_pay_button_enabled_product' => [ 'title' => __('Enable Apple Pay Button on Product page', 'mollie-payments-for-woocommerce'), - /* translators: Placeholder 1: enabled or disabled */ 'desc' => __( 'Enable the Apple Pay direct buy button on the Product page', 'mollie-payments-for-woocommerce' @@ -51,6 +49,12 @@ public function getFormFields($generalFormFields): array 'type' => 'checkbox', 'default' => 'no', ], + 'mollie_apple_pay_button_enabled_express_checkout' => [ + 'title' => __('Enable Apple Pay Express Button on Checkout page', 'mollie-payments-for-woocommerce'), + 'desc' => __('Enable the Apple Pay direct buy button on the Express Buttons section of the Checkout page', 'mollie-payments-for-woocommerce'), + 'type' => 'checkbox', + 'default' => 'no', + ], ]; return array_merge($generalFormFields, $paymentMethodFormFieds); } diff --git a/src/Shared/Data.php b/src/Shared/Data.php index 54230c6db..cf38fd51f 100644 --- a/src/Shared/Data.php +++ b/src/Shared/Data.php @@ -7,6 +7,7 @@ use Exception; use InvalidArgumentException; use Mollie\Api\Resources\Method; +use Mollie\WooCommerce\Buttons\ApplePayButton\DataToAppleButtonScripts; use Mollie\WooCommerce\SDK\Api; use Mollie\WooCommerce\Settings\Settings; use Psr\Log\LoggerInterface as Logger; @@ -786,4 +787,10 @@ protected function addRecurringPaymentMethods($apiKey, bool $testMode, bool $use } return $result; } + + public function mollieApplePayBlockDataCart() + { + $dataToScripts = new DataToAppleButtonScripts(); + return $dataToScripts->applePayScriptData(true); + } } diff --git a/tests/php/Functional/ApplePayButton/DataToAppleButtonScriptsTest.php b/tests/php/Functional/ApplePayButton/DataToAppleButtonScriptsTest.php index 1d4c79cea..40fe4bbda 100644 --- a/tests/php/Functional/ApplePayButton/DataToAppleButtonScriptsTest.php +++ b/tests/php/Functional/ApplePayButton/DataToAppleButtonScriptsTest.php @@ -52,6 +52,7 @@ public function testApplePayScriptDataOnProduct() 'wc_get_product' => $this->wcProduct(), 'admin_url' => 'admin-ajax.php', 'get_option' => false, + 'is_admin' => false, ] ); @@ -97,6 +98,7 @@ public function testApplePayScriptDataOnCart() 'admin_url' => 'admin-ajax.php', 'WC' => $this->wooCommerce($subtotal), 'wp_nonce_field'=> 'testNonce', + 'is_admin' => false, ] ); diff --git a/tests/php/Functional/ApplePayButton/ResponsesToAppleTest.php b/tests/php/Functional/ApplePayButton/ResponsesToAppleTest.php index 5f5c793e3..59908b6b0 100644 --- a/tests/php/Functional/ApplePayButton/ResponsesToAppleTest.php +++ b/tests/php/Functional/ApplePayButton/ResponsesToAppleTest.php @@ -71,7 +71,8 @@ public function testAppleFormattedResponseWithoutShippingMethod() ] ]; - + //shippingMethods is null this is not going to run + $applePayRequestDataObject = []; expect('get_bloginfo') ->once() ->with('name') @@ -82,7 +83,7 @@ public function testAppleFormattedResponseWithoutShippingMethod() $logger = $this->helperMocks->loggerMock(); $appleGateway = $this->mollieGateway('applepay', false, true); $responsesTemplate = new ResponsesToApple($logger, $appleGateway); - $response = $responsesTemplate->appleFormattedResponse($paymentDetails); + $response = $responsesTemplate->appleFormattedResponse($paymentDetails, $applePayRequestDataObject); self::assertEquals($response, $expectedResponse); } @@ -107,6 +108,8 @@ public function testAppleFormattedResponseWithShippingMethod() 'taxes' => $taxes, 'total' => $total ]; + //shippingMethods is null this is not going to run + $applePayRequestDataObject = []; $expectedResponse = [ 'newLineItems'=>[ [ @@ -143,7 +146,7 @@ public function testAppleFormattedResponseWithShippingMethod() $logger = $this->helperMocks->loggerMock(); $appleGateway = $this->mollieGateway('applepay', false, true); $responsesTemplate = new ResponsesToApple($logger, $appleGateway); - $response = $responsesTemplate->appleFormattedResponse($paymentDetails); + $response = $responsesTemplate->appleFormattedResponse($paymentDetails, $applePayRequestDataObject); self::assertEquals($response, $expectedResponse); } diff --git a/webpack.config.js b/webpack.config.js index 19805a960..6ef260ea6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -29,7 +29,7 @@ function configJavaScript ({ basePath }) .addEntry('mollie-components-blocks.min', './resources/js/mollie-components-blocks.js') .addEntry('mollieBlockIndex.min', './resources/js/mollieBlockIndex.js') .addEntry('paypalButtonBlockComponent.min', './resources/js/paypalButtonBlockComponent.js') - .addEntry('applepayButtonBlockComponent.min', './resources/js/applepayButtonBlockComponent.js') + .addEntry('applepayButtonBlock.min', './resources/js/applepayButtonBlock.js') .addEntry('rivertyCountryPlaceholder.min', './resources/js/rivertyCountryPlaceholder.js') .addEntry('mollie-settings-2024.min', './resources/js/mollie-settings-2024.js') .enableSourceMaps(!Encore.isProduction()) From 55dc2eabe36bea8e673c28373e41f3b4344eeef1 Mon Sep 17 00:00:00 2001 From: carmenmaymo Date: Mon, 4 Nov 2024 14:22:08 +0100 Subject: [PATCH 3/7] Update modules bootstrap --- mollie-payments-for-woocommerce.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mollie-payments-for-woocommerce.php b/mollie-payments-for-woocommerce.php index fbafd7de6..1ddb62437 100644 --- a/mollie-payments-for-woocommerce.php +++ b/mollie-payments-for-woocommerce.php @@ -153,7 +153,10 @@ function initialize() new UninstallModule(), ]; $modules = apply_filters('mollie_wc_plugin_modules', $modules); - $bootstrap->boot(...$modules); + foreach ($modules as $module) { + $bootstrap->addModule($module); + } + $bootstrap->boot(); } catch (Throwable $throwable) { handleException($throwable); } From 19dae4ad570f0dda180dd5c9704ddf4617a664a3 Mon Sep 17 00:00:00 2001 From: carmenmaymo Date: Mon, 4 Nov 2024 14:22:29 +0100 Subject: [PATCH 4/7] Update version --- mollie-payments-for-woocommerce.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mollie-payments-for-woocommerce.php b/mollie-payments-for-woocommerce.php index 1ddb62437..77d4377bc 100644 --- a/mollie-payments-for-woocommerce.php +++ b/mollie-payments-for-woocommerce.php @@ -3,11 +3,11 @@ * Plugin Name: Mollie Payments for WooCommerce * Plugin URI: https://www.mollie.com * Description: Accept payments in WooCommerce with the official Mollie plugin - * Version: 7.8.2 + * Version: 7.9.0-beta * Author: Mollie * Author URI: https://www.mollie.com * Requires at least: 5.0 - * Tested up to: 6.6 + * Tested up to: 6.7 * Text Domain: mollie-payments-for-woocommerce * Domain Path: /languages * License: GPLv2 or later From 9a03654b25a288a7c774f325f140892da1cb215c Mon Sep 17 00:00:00 2001 From: carmenmaymo Date: Mon, 4 Nov 2024 14:24:08 +0100 Subject: [PATCH 5/7] Move clear options to advanced section PIWOO-564 --- src/Settings/Page/Section/Advanced.php | 33 ++++++-- src/Settings/Page/Section/PaymentMethods.php | 80 ++++++++------------ 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/src/Settings/Page/Section/Advanced.php b/src/Settings/Page/Section/Advanced.php index 8b3c8967e..454d0f37d 100644 --- a/src/Settings/Page/Section/Advanced.php +++ b/src/Settings/Page/Section/Advanced.php @@ -11,6 +11,7 @@ class Advanced extends AbstractSection { public function config(): array { + $this->cleanDbIfRequested(); $config = [ [ 'id' => $this->settings->getSettingId('title'), @@ -48,9 +49,9 @@ public function config(): array 'type' => 'select', 'options' => [ SharedDataDictionary::SETTING_LOCALE_WP_LANGUAGE => __( - 'Automatically send WordPress language', - 'mollie-payments-for-woocommerce' - ) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', + 'Automatically send WordPress language', + 'mollie-payments-for-woocommerce' + ) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', SharedDataDictionary::SETTING_LOCALE_DETECT_BY_BROWSER => __( 'Detect using browser language', 'mollie-payments-for-woocommerce' @@ -110,8 +111,8 @@ public function config(): array 'type' => 'select', 'options' => [ PaymentService::PAYMENT_METHOD_TYPE_ORDER => ucfirst( - PaymentService::PAYMENT_METHOD_TYPE_ORDER - ) . ' (' . __('default', 'mollie-payments-for-woocommerce') + PaymentService::PAYMENT_METHOD_TYPE_ORDER + ) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', PaymentService::PAYMENT_METHOD_TYPE_PAYMENT => ucfirst( PaymentService::PAYMENT_METHOD_TYPE_PAYMENT @@ -202,8 +203,8 @@ class="mollie-settings-advanced-payment-desc-label button button-secondary butto 'type' => 'checkbox', 'default' => 'no', 'desc' => __("Remove options and scheduled actions from database when uninstalling the plugin.", "mollie-payments-for-woocommerce") . ' (' . strtolower( - __('Clear now', 'mollie-payments-for-woocommerce') - ) . ')', + __('Clear now', 'mollie-payments-for-woocommerce') + ) . ')', ], [ 'id' => $this->settings->getSettingId('sectionend'), @@ -245,4 +246,22 @@ protected function content(): string settings->cleanDb(); + $cleaner->cleanAll(); + //set default settings + foreach ($this->paymentMethods as $paymentMethod) { + $paymentMethod->getSettings(); + } + } + } + } diff --git a/src/Settings/Page/Section/PaymentMethods.php b/src/Settings/Page/Section/PaymentMethods.php index e1a9308af..4bcd17a73 100644 --- a/src/Settings/Page/Section/PaymentMethods.php +++ b/src/Settings/Page/Section/PaymentMethods.php @@ -35,22 +35,21 @@ protected function content(): string public function renderGateways(): string { $this->refreshIfRequested(); - $this->cleanDbIfRequested(); $titleActivePaymentMethods = __( - 'Currently Active Payment Methods', - 'mollie-payments-for-woocommerce' + 'Currently Active Payment Methods', + 'mollie-payments-for-woocommerce' ); $descriptionActivePaymentMethods = __( - 'These payment methods are active in your Mollie profile. + 'These payment methods are active in your Mollie profile. You can enable these payment methods in their settings to make them available for your customers.', - 'mollie-payments-for-woocommerce' + 'mollie-payments-for-woocommerce' ); $titleInactivePaymentMethods = __('Inactive Payment Methods', 'mollie-payments-for-woocommerce'); $descriptionInactivePaymentMethods = __( - 'These payment methods are available in your Mollie profile but are + 'These payment methods are available in your Mollie profile but are not currently active. Activate them to offer more payment options to your customers.', - 'mollie-payments-for-woocommerce' + 'mollie-payments-for-woocommerce' ); $activatedGateways = ''; @@ -71,14 +70,14 @@ public function renderGateways(): string } return $this->paymentGatewaysBlock( - $titleActivePaymentMethods, - $descriptionActivePaymentMethods, - $activatedGateways - ) . $this->paymentGatewaysBlock( - $titleInactivePaymentMethods, - $descriptionInactivePaymentMethods, - $deactivatedGateways - ); + $titleActivePaymentMethods, + $descriptionActivePaymentMethods, + $activatedGateways + ) . $this->paymentGatewaysBlock( + $titleInactivePaymentMethods, + $descriptionInactivePaymentMethods, + $deactivatedGateways + ); } protected function paymentGatewaysBlock(string $title, string $description, string $html): string @@ -99,7 +98,7 @@ protected function paymentGatewaysBlock(string $title, string $description, stri protected function getGatewaySettingsUrl(string $gatewayClassName): string { return admin_url( - 'admin.php?page=wc-settings&tab=checkout§ion=' . sanitize_title(strtolower($gatewayClassName)) + 'admin.php?page=wc-settings&tab=checkout§ion=' . sanitize_title(strtolower($gatewayClassName)) ); } @@ -178,8 +177,8 @@ protected function refreshIfRequested() isset($_GET['refresh-methods']) && isset($_GET['nonce_mollie_refresh_methods']) && wp_verify_nonce( - filter_input(INPUT_GET, 'nonce_mollie_refresh_methods', FILTER_SANITIZE_SPECIAL_CHARS), - 'nonce_mollie_refresh_methods' + filter_input(INPUT_GET, 'nonce_mollie_refresh_methods', FILTER_SANITIZE_SPECIAL_CHARS), + 'nonce_mollie_refresh_methods' ) ) { $testMode = $this->testModeEnabled; @@ -194,53 +193,36 @@ protected function refreshIfRequested() } } - protected function cleanDbIfRequested() - { - if ( - isset($_GET['cleanDB-mollie']) && wp_verify_nonce( - filter_input(INPUT_GET, 'nonce_mollie_cleanDb', FILTER_SANITIZE_SPECIAL_CHARS), - 'nonce_mollie_cleanDb' - ) - ) { - $cleaner = $this->settings->cleanDb(); - $cleaner->cleanAll(); - //set default settings - foreach ($this->paymentMethods as $paymentMethod) { - $paymentMethod->getSettings(); - } - } - } - protected function paymentGatewayButton(AbstractPaymentMethod $paymentMethod, $enabledInMollie): string { $documentationLink = $paymentMethod->getProperty('docs'); $paymentMethodId = $paymentMethod->getProperty('id'); $gatewayKey = 'mollie_wc_gateway_' . $paymentMethodId; $button = '' . esc_html(__( - 'Manage Payment Method', - 'mollie-payments-for-woocommerce' - )) . ''; + $gatewayKey + ) . '">' . esc_html(__( + 'Manage Payment Method', + 'mollie-payments-for-woocommerce' + )) . ''; $messageOrLink = ''; $enabledInWoo = ($paymentMethod->getSettings())['enabled'] === 'yes'; if ($enabledInMollie && $enabledInWoo) { $messageOrLink = '' . esc_html(__( - 'enabled', - 'mollie-payments-for-woocommerce' - )) . ''; + 'enabled', + 'mollie-payments-for-woocommerce' + )) . ''; } elseif ($enabledInMollie && !$enabledInWoo) { $messageOrLink = '' . esc_html(__( - 'disabled', - 'mollie-payments-for-woocommerce' - )) . ''; + 'disabled', + 'mollie-payments-for-woocommerce' + )) . ''; } else { if ($documentationLink) { $messageOrLink = "" . esc_html(__( - 'More information', - 'mollie-payments-for-woocommerce' - )) . ''; + 'More information', + 'mollie-payments-for-woocommerce' + )) . ''; } $button = '' . esc_html(__('Activate Payment Method', 'mollie-payments-for-woocommerce')) From 4d467ecbf7ec0066accbca8e27ce4406b10ec255 Mon Sep 17 00:00:00 2001 From: carmenmaymo Date: Mon, 4 Nov 2024 14:33:27 +0100 Subject: [PATCH 6/7] Check keys before saving in all cases PIWOO-566 --- src/Settings/MollieSettingsPage.php | 73 +++++++++++++++-------------- src/Shared/Data.php | 4 +- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/Settings/MollieSettingsPage.php b/src/Settings/MollieSettingsPage.php index ac0625360..61e835f2c 100644 --- a/src/Settings/MollieSettingsPage.php +++ b/src/Settings/MollieSettingsPage.php @@ -199,43 +199,46 @@ protected function saveApiKeys($settings) if (!$isNonceValid) { return $settings; } - $liveKeyName = 'mollie-payments-for-woocommerce_live_api_key'; - $testKeyName = 'mollie-payments-for-woocommerce_test_api_key'; - $liveValueInDb = get_option($liveKeyName); - $testValueInDb = get_option($testKeyName); - $postedLiveValue = isset($_POST[$liveKeyName]) ? sanitize_text_field(wp_unslash($_POST[$liveKeyName])) : ''; - $postedTestValue = isset($_POST[$testKeyName]) ? sanitize_text_field(wp_unslash($_POST[$testKeyName])) : ''; + $apiKeys = [ + 'live' => [ + 'keyName' => 'mollie-payments-for-woocommerce_live_api_key', + 'pattern' => '/^live_\w{30,}$/', + 'valueInDb' => get_option('mollie-payments-for-woocommerce_live_api_key'), + 'postedValue' => isset($_POST['mollie-payments-for-woocommerce_live_api_key']) + ? sanitize_text_field(wp_unslash($_POST['mollie-payments-for-woocommerce_live_api_key'])) + : '' + ], + 'test' => [ + 'keyName' => 'mollie-payments-for-woocommerce_test_api_key', + 'pattern' => '/^test_\w{30,}$/', + 'valueInDb' => get_option('mollie-payments-for-woocommerce_test_api_key'), + 'postedValue' => isset($_POST['mollie-payments-for-woocommerce_test_api_key']) + ? sanitize_text_field(wp_unslash($_POST['mollie-payments-for-woocommerce_test_api_key'])) + : '' + ] + ]; foreach ($settings as $setting) { - if ( - $setting['id'] - === $liveKeyName - && $liveValueInDb - ) { - if ($postedLiveValue === '**********') { - $_POST[$liveKeyName] = $liveValueInDb; - } else { - $pattern = '/^live_\w{30,}$/'; - $this->validateApiKeyOrRemove( - $pattern, - $postedLiveValue, - $liveKeyName - ); - } - } elseif ( - $setting['id'] - === $testKeyName - && $testValueInDb - ) { - if ($postedTestValue === '**********') { - $_POST[$testKeyName] = $testValueInDb; - } else { - $pattern = '/^test_\w{30,}$/'; - $this->validateApiKeyOrRemove( - $pattern, - $postedTestValue, - $testKeyName - ); + foreach ($apiKeys as $type => $apiKey) { + if ($setting['id'] === $apiKey['keyName']) { + if ($apiKey['postedValue'] === '**********') { + // If placeholder is detected but no DB value, validate as new key + if (!$apiKey['valueInDb']) { + $this->validateApiKeyOrRemove( + $apiKey['pattern'], + '', // No DB value; treat as new + $apiKey['keyName'] + ); + } else { + $_POST[$apiKey['keyName']] = $apiKey['valueInDb']; + } + } else { + $this->validateApiKeyOrRemove( + $apiKey['pattern'], + $apiKey['postedValue'], + $apiKey['keyName'] + ); + } } } } diff --git a/src/Shared/Data.php b/src/Shared/Data.php index cf38fd51f..a20770bb0 100644 --- a/src/Shared/Data.php +++ b/src/Shared/Data.php @@ -113,9 +113,9 @@ public function isTestModeEnabled(): bool /** * @param bool $overrideTestMode * - * @return null|string + * @return false|string */ - public function getApiKey($overrideTestMode = 2): ?string + public function getApiKey($overrideTestMode = 2) { return $this->settingsHelper->getApiKey($overrideTestMode); } From 39d2111c529173c9d48f70a02a2c116f954b79e7 Mon Sep 17 00:00:00 2001 From: carmenmaymo Date: Mon, 4 Nov 2024 14:50:03 +0100 Subject: [PATCH 7/7] Fix CS --- src/Settings/MollieSettingsPage.php | 58 ++++++++++-------- src/Settings/Page/Section/Advanced.php | 15 +++-- src/Settings/Page/Section/PaymentMethods.php | 62 ++++++++++---------- 3 files changed, 72 insertions(+), 63 deletions(-) diff --git a/src/Settings/MollieSettingsPage.php b/src/Settings/MollieSettingsPage.php index 61e835f2c..cafb4ac87 100644 --- a/src/Settings/MollieSettingsPage.php +++ b/src/Settings/MollieSettingsPage.php @@ -206,7 +206,7 @@ protected function saveApiKeys($settings) 'valueInDb' => get_option('mollie-payments-for-woocommerce_live_api_key'), 'postedValue' => isset($_POST['mollie-payments-for-woocommerce_live_api_key']) ? sanitize_text_field(wp_unslash($_POST['mollie-payments-for-woocommerce_live_api_key'])) - : '' + : '', ], 'test' => [ 'keyName' => 'mollie-payments-for-woocommerce_test_api_key', @@ -214,32 +214,13 @@ protected function saveApiKeys($settings) 'valueInDb' => get_option('mollie-payments-for-woocommerce_test_api_key'), 'postedValue' => isset($_POST['mollie-payments-for-woocommerce_test_api_key']) ? sanitize_text_field(wp_unslash($_POST['mollie-payments-for-woocommerce_test_api_key'])) - : '' - ] + : '', + ], ]; foreach ($settings as $setting) { - foreach ($apiKeys as $type => $apiKey) { - if ($setting['id'] === $apiKey['keyName']) { - if ($apiKey['postedValue'] === '**********') { - // If placeholder is detected but no DB value, validate as new key - if (!$apiKey['valueInDb']) { - $this->validateApiKeyOrRemove( - $apiKey['pattern'], - '', // No DB value; treat as new - $apiKey['keyName'] - ); - } else { - $_POST[$apiKey['keyName']] = $apiKey['valueInDb']; - } - } else { - $this->validateApiKeyOrRemove( - $apiKey['pattern'], - $apiKey['postedValue'], - $apiKey['keyName'] - ); - } - } + foreach ($apiKeys as $apiKey) { + $this->processApiKeys($setting['id'], $apiKey); } } return $settings; @@ -266,4 +247,33 @@ protected function validateApiKeyOrRemove($pattern, $value, $keyName) unset($_POST[$keyName]); } } + + /** + * @param $id + * @param array $apiKey + * @return void + */ + public function processApiKeys($id, array $apiKey): void + { + if ($id === $apiKey['keyName']) { + if ($apiKey['postedValue'] === '**********') { + // If placeholder is detected but no DB value, validate as new key + if (!$apiKey['valueInDb']) { + $this->validateApiKeyOrRemove( + $apiKey['pattern'], + '', // No DB value; treat as new + $apiKey['keyName'] + ); + } else { + $_POST[$apiKey['keyName']] = $apiKey['valueInDb']; + } + } else { + $this->validateApiKeyOrRemove( + $apiKey['pattern'], + $apiKey['postedValue'], + $apiKey['keyName'] + ); + } + } + } } diff --git a/src/Settings/Page/Section/Advanced.php b/src/Settings/Page/Section/Advanced.php index 454d0f37d..a4e048a91 100644 --- a/src/Settings/Page/Section/Advanced.php +++ b/src/Settings/Page/Section/Advanced.php @@ -49,9 +49,9 @@ public function config(): array 'type' => 'select', 'options' => [ SharedDataDictionary::SETTING_LOCALE_WP_LANGUAGE => __( - 'Automatically send WordPress language', - 'mollie-payments-for-woocommerce' - ) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', + 'Automatically send WordPress language', + 'mollie-payments-for-woocommerce' + ) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', SharedDataDictionary::SETTING_LOCALE_DETECT_BY_BROWSER => __( 'Detect using browser language', 'mollie-payments-for-woocommerce' @@ -111,8 +111,8 @@ public function config(): array 'type' => 'select', 'options' => [ PaymentService::PAYMENT_METHOD_TYPE_ORDER => ucfirst( - PaymentService::PAYMENT_METHOD_TYPE_ORDER - ) . ' (' . __('default', 'mollie-payments-for-woocommerce') + PaymentService::PAYMENT_METHOD_TYPE_ORDER + ) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', PaymentService::PAYMENT_METHOD_TYPE_PAYMENT => ucfirst( PaymentService::PAYMENT_METHOD_TYPE_PAYMENT @@ -203,8 +203,8 @@ class="mollie-settings-advanced-payment-desc-label button button-secondary butto 'type' => 'checkbox', 'default' => 'no', 'desc' => __("Remove options and scheduled actions from database when uninstalling the plugin.", "mollie-payments-for-woocommerce") . ' (' . strtolower( - __('Clear now', 'mollie-payments-for-woocommerce') - ) . ')', + __('Clear now', 'mollie-payments-for-woocommerce') + ) . ')', ], [ 'id' => $this->settings->getSettingId('sectionend'), @@ -263,5 +263,4 @@ protected function cleanDbIfRequested() } } } - } diff --git a/src/Settings/Page/Section/PaymentMethods.php b/src/Settings/Page/Section/PaymentMethods.php index 4bcd17a73..11fc8f676 100644 --- a/src/Settings/Page/Section/PaymentMethods.php +++ b/src/Settings/Page/Section/PaymentMethods.php @@ -37,19 +37,19 @@ public function renderGateways(): string $this->refreshIfRequested(); $titleActivePaymentMethods = __( - 'Currently Active Payment Methods', - 'mollie-payments-for-woocommerce' + 'Currently Active Payment Methods', + 'mollie-payments-for-woocommerce' ); $descriptionActivePaymentMethods = __( - 'These payment methods are active in your Mollie profile. + 'These payment methods are active in your Mollie profile. You can enable these payment methods in their settings to make them available for your customers.', - 'mollie-payments-for-woocommerce' + 'mollie-payments-for-woocommerce' ); $titleInactivePaymentMethods = __('Inactive Payment Methods', 'mollie-payments-for-woocommerce'); $descriptionInactivePaymentMethods = __( - 'These payment methods are available in your Mollie profile but are + 'These payment methods are available in your Mollie profile but are not currently active. Activate them to offer more payment options to your customers.', - 'mollie-payments-for-woocommerce' + 'mollie-payments-for-woocommerce' ); $activatedGateways = ''; @@ -70,14 +70,14 @@ public function renderGateways(): string } return $this->paymentGatewaysBlock( - $titleActivePaymentMethods, - $descriptionActivePaymentMethods, - $activatedGateways - ) . $this->paymentGatewaysBlock( - $titleInactivePaymentMethods, - $descriptionInactivePaymentMethods, - $deactivatedGateways - ); + $titleActivePaymentMethods, + $descriptionActivePaymentMethods, + $activatedGateways + ) . $this->paymentGatewaysBlock( + $titleInactivePaymentMethods, + $descriptionInactivePaymentMethods, + $deactivatedGateways + ); } protected function paymentGatewaysBlock(string $title, string $description, string $html): string @@ -98,7 +98,7 @@ protected function paymentGatewaysBlock(string $title, string $description, stri protected function getGatewaySettingsUrl(string $gatewayClassName): string { return admin_url( - 'admin.php?page=wc-settings&tab=checkout§ion=' . sanitize_title(strtolower($gatewayClassName)) + 'admin.php?page=wc-settings&tab=checkout§ion=' . sanitize_title(strtolower($gatewayClassName)) ); } @@ -177,8 +177,8 @@ protected function refreshIfRequested() isset($_GET['refresh-methods']) && isset($_GET['nonce_mollie_refresh_methods']) && wp_verify_nonce( - filter_input(INPUT_GET, 'nonce_mollie_refresh_methods', FILTER_SANITIZE_SPECIAL_CHARS), - 'nonce_mollie_refresh_methods' + filter_input(INPUT_GET, 'nonce_mollie_refresh_methods', FILTER_SANITIZE_SPECIAL_CHARS), + 'nonce_mollie_refresh_methods' ) ) { $testMode = $this->testModeEnabled; @@ -199,30 +199,30 @@ protected function paymentGatewayButton(AbstractPaymentMethod $paymentMethod, $e $paymentMethodId = $paymentMethod->getProperty('id'); $gatewayKey = 'mollie_wc_gateway_' . $paymentMethodId; $button = '' . esc_html(__( - 'Manage Payment Method', - 'mollie-payments-for-woocommerce' - )) . ''; + $gatewayKey + ) . '">' . esc_html(__( + 'Manage Payment Method', + 'mollie-payments-for-woocommerce' + )) . ''; $messageOrLink = ''; $enabledInWoo = ($paymentMethod->getSettings())['enabled'] === 'yes'; if ($enabledInMollie && $enabledInWoo) { $messageOrLink = '' . esc_html(__( - 'enabled', - 'mollie-payments-for-woocommerce' - )) . ''; + 'enabled', + 'mollie-payments-for-woocommerce' + )) . ''; } elseif ($enabledInMollie && !$enabledInWoo) { $messageOrLink = '' . esc_html(__( - 'disabled', - 'mollie-payments-for-woocommerce' - )) . ''; + 'disabled', + 'mollie-payments-for-woocommerce' + )) . ''; } else { if ($documentationLink) { $messageOrLink = "" . esc_html(__( - 'More information', - 'mollie-payments-for-woocommerce' - )) . ''; + 'More information', + 'mollie-payments-for-woocommerce' + )) . ''; } $button = '' . esc_html(__('Activate Payment Method', 'mollie-payments-for-woocommerce'))