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 598bcef29..03fa454fb 100644 --- a/src/Activation/ActivationModule.php +++ b/src/Activation/ActivationModule.php @@ -40,9 +40,10 @@ public function run(ContainerInterface $container): bool 'init', [$this, 'pluginInit'] ); + + add_action('admin_init', [$this, 'mollieWcNoticeApiKeyMissing']); $this->declareCompatibleWithHPOS(); $this->handleTranslations(); - $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 c7638b054..d4464b366 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') }