ments-for-woocommerce'); $presentationText .= 'Contact info@mollie.com'; $presentationText .= ' if you have any questions or comments about this plugin.

'; $presentationText .= '

Our pricing is always per transaction. No startup fees, no monthly fees, and no gateway fees. No hidden fees, period.

'; $presentation = '' . '
'.__('Plugin Documentation', 'mollie-payments-for-woocommerce').' | '.__('Contact Support', 'mollie-payments-for-woocommerce').'
' . '' . '

'.$presentationText.'

'; $content = '' . $presentation . $this->getPluginStatus() . $this->getMollieMethods(); $debug_desc = __('Log plugin events.', 'mollie-payments-for-woocommerce'); // Display location of log files /* translators: Placeholder 1: Location of the log files */ $debug_desc .= ' ' . sprintf( __( 'Log files are saved to %s', 'mollie-payments-for-woocommerce' ), defined('WC_LOG_DIR') ? WC_LOG_DIR : WC()->plugin_path() . '/logs/' ); // Global Mollie settings $mollie_settings = array( array( 'id' => $this->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') . '

', ), array( 'id' => $this->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 %s API key in your %sMollie profile%s', 'mollie-payments-for-woocommerce'), 'live', '', '' ), 'css' => 'width: 350px', 'placeholder' => $live_placeholder = __('Live API key should start with live_', 'mollie-payments-for-woocommerce'), 'custom_attributes' => array( 'placeholder' => $live_placeholder, 'pattern' => '^live_\w{30,}$', ), ), array( 'id' => $this->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'), ), array( 'id' => $this->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 %s API key in your %sMollie profile%s', 'mollie-payments-for-woocommerce'), 'test', '', '' ), 'css' => 'width: 350px', 'placeholder' => $test_placeholder = __('Test API key should start with test_', 'mollie-payments-for-woocommerce'), 'custom_attributes' => array( 'placeholder' => $test_placeholder, 'pattern' => '^test_\w{30,}$', ), ), [ 'id' => $this->getSettingId('debug'), 'title' => __('Debug Log', 'mollie-payments-for-woocommerce'), 'type' => 'checkbox', 'desc' => $debug_desc, 'default' => 'yes', ], array( 'id' => $this->getSettingId('sectionend'), 'type' => 'sectionend', ), ); return $this->mergeSettings($settings, $mollie_settings); } public function getPaymentConfirmationCheckTime() { $time = strtotime(self::DEFAULT_TIME_PAYMENT_CONFIRMATION_CHECK); $date = new DateTime(); if ($date->getTimestamp() > $time){ $date->setTimestamp($time); $date->add(new DateInterval('P1D')); } else { $date->setTimestamp($time); } return $date->getTimestamp(); } /** * @param string $setting * @return string */ protected function getSettingId ($setting) { global $wp_version; $setting_id = Mollie_WC_Plugin::PLUGIN_ID . '_' . trim($setting); $setting_id_length = strlen($setting_id); $max_option_name_length = 191; /** * Prior to WooPress version 4.4.0, the maximum length for wp_options.option_name is 64 characters. * @see https://core.trac.wordpress.org/changeset/34030 */ if ($wp_version < '4.4.0') { $max_option_name_length = 64; } if ($setting_id_length > $max_option_name_length) { trigger_error("Setting id $setting_id ($setting_id_length) to long for database column wp_options.option_name which is varchar($max_option_name_length).", E_USER_WARNING); } return $setting_id; } /** * @param array $settings * @param array $mollie_settings * @return array */ protected function mergeSettings(array $settings, array $mollie_settings) { $new_settings = array(); $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 $content * * @return string */ protected function checkDirectDebitStatus( $content ) { $ideal_gateway = new Mollie_WC_Gateway_iDEAL(); $sepa_gateway = new Mollie_WC_Gateway_DirectDebit(); if ( ( class_exists( 'WC_Subscription' ) ) && ( $ideal_gateway->is_available() ) && ( ! $sepa_gateway->is_available() ) ) { $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 ) { $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 ) { $woocommerce_klarnapaylater_gateway = new Mollie_WC_Gateway_KlarnaPayLater(); $woocommerce_klarnasliceit_gateway = new Mollie_WC_Gateway_KlarnaSliceIt(); if ($woocommerce_klarnapaylater_gateway->is_available() || $woocommerce_klarnasliceit_gateway->is_available()) { $content .= '

'; $content .= __( 'To accept Klarna payments via Mollie, all default WooCommerce checkout fields should be enabled and required. Please ensure that is the case.', 'mollie-payments-for-woocommerce' ); $content .= '

'; return $content; } return $content; } /** * Get current locale by WordPress * * Default to self::SETTING_LOCALE_DEFAULT_LANGUAGE * * @return string */ protected function getCurrentLocale() { $locale = apply_filters(self::FILTER_WPML_CURRENT_LOCALE, get_locale()); // Convert known exceptions $locale = $locale === 'nl_NL_formal' ? 'nl_NL' : $locale; $locale = $locale === 'de_DE_formal' ? 'de_DE' : $locale; $locale = $locale === 'no_NO' ? 'nb_NO' : $locale; return $this->extractValidLanguageCode([$locale]); } /** * Retrieve the browser language * * @return string */ protected function browserLanguage() { if (empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { return self::SETTING_LOCALE_DEFAULT_LANGUAGE; } $httpAcceptedLanguages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); foreach ($httpAcceptedLanguages as $index => $languageCode) { $languageCode = explode(';', $languageCode)[0]; if (strpos($languageCode, '-') !== false) { $languageCode = str_replace('-', '_', $languageCode); } $httpAcceptedLanguages[$index] = $languageCode; } $httpAcceptedLanguages = array_filter($httpAcceptedLanguages); if (!$httpAcceptedLanguages) { return self::SETTING_LOCALE_DEFAULT_LANGUAGE; } return $this->extractValidLanguageCode($httpAcceptedLanguages); } /** * Extract a valid code Language from the given arguments * * The language Code could contains valid language codes that are not supported such as * country codes. * * Since the Browser can send both country and region codes we need to map the country code * to a region code on the fly. * * The method does that, it try to retrieve the language code if it's exists within the * allowed language codes dictionary, if not it will try to retrieve the first one that * contains the country code. * * @param array $languageCodes * @return string */ protected function extractValidLanguageCode(array $languageCodes) { // TODO Need Assertion to ensure $languageCodes is not empty and contains only strings /** * Filter Allowed Language Codes * * @param array $allowedLanguageCodes */ $allowedLanguageCodes = apply_filters( self::FILTER_ALLOWED_LANGUAGE_CODE_SETTING, self::ALLOWED_LANGUAGE_CODES ); if (empty($allowedLanguageCodes)) { // TODO Need validation for Language Code return (string)$languageCodes[0]; } foreach ($languageCodes as $index => $languageCode) { if (in_array($languageCode, $allowedLanguageCodes, true)) { return $languageCode; } } foreach ($languageCodes as $languageCode) { foreach ($allowedLanguageCodes as $currentAllowedLanguageCode) { $countryCode = substr($currentAllowedLanguageCode, 0, 2); if ($countryCode === $languageCode) { return $currentAllowedLanguageCode; } } } return self::SETTING_LOCALE_DEFAULT_LANGUAGE; } /** * Init all the gateways and add to the db for the first time * @param $gateway */ protected function updateGatewaySettings($gateway) { $gateway->settings['enabled'] = $gateway->is_available() ? 'yes' : 'no'; update_option( $gateway->id . "_settings", $gateway->settings ); } }