uawdijnntqw1x1x1
IP : 216.73.216.109
Hostname : premium160.web-hosting.com
Kernel : Linux premium160.web-hosting.com 4.18.0-553.54.1.lve.el8.x86_64 #1 SMP Wed Jun 4 13:01:13 UTC 2025 x86_64
Disable Function : None :)
OS : Linux
PATH:
/
home
/
batcwwjx
/
www
/
wp-content
/
plugins
/
charitable
/
.
/
includes
/
gateways
/
class-charitable-gateways.php
/
/
<?php /** * Class that sets up the gateways. * * @package Charitable/Classes/Charitable_Gateways * @author David Bisset * @copyright Copyright (c) 2023, WP Charitable LLC * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License * @since 1.0.0 * @version 1.6.57 * @version 1.8.7 - Added Square. */ // Exit if accessed directly. if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'Charitable_Gateways' ) ) : /** * Charitable_Gateways * * @since 1.0.0 */ class Charitable_Gateways { /** * The single instance of this class. * * @since 1.0.0 * * @var Charitable_Gateways|null */ private static $instance = null; /** * All available payment gateways. * * @since 1.0.0 * * @var array */ private $gateways; /** * Set up the class. * * Note that the only way to instantiate an object is with the charitable_start method, * which can only be called during the start phase. In other words, don't try * to instantiate this object. * * @since 1.0.0 */ protected function __construct() { add_action( 'init', array( $this, 'check_settings' ), 10 ); add_action( 'init', array( $this, 'register_gateways' ), 1 ); add_action( 'init', array( $this, 'connect_gateways' ), 99 ); // Stripe. add_action( 'init', array( $this, 'disconnect_gateways' ), 99 ); // Stripe. add_action( 'charitable_make_default_gateway', array( $this, 'handle_gateway_settings_request' ) ); add_action( 'charitable_enable_gateway', array( $this, 'handle_gateway_settings_request' ) ); add_action( 'charitable_disable_gateway', array( $this, 'handle_gateway_settings_request' ) ); add_filter( 'charitable_settings_fields_gateways_gateway', array( $this, 'register_gateway_settings' ), 10, 2 ); add_action( 'charitable_disable_gateway', array( $this, 'handle_gateway_settings_request' ) ); /** * Square Connect */ add_action( 'init', array( $this, 'disconnect_gateways_square' ), 99 ); // Square. add_action( 'init', array( $this, 'refresh_square_token' ), 99 ); // Square. add_action( 'init', array( $this, 'get_gateway_error_message' ), 99 ); do_action( 'charitable_gateway_start', $this ); add_action( 'wp_ajax_charitable-show-stripe-keys', array( $this, 'show_stripe_manual_keys_ajax' ), 10 ); add_action( 'wp_ajax_charitable_switch_square_gateways', array( $this, 'handle_square_gateway_switch' ) ); add_action( 'wp_ajax_charitable_switch_square_core_to_legacy', array( $this, 'handle_square_core_to_legacy_switch' ) ); // Dequeue Square Legacy scripts if Square Legacy is not active. add_action( 'wp_enqueue_scripts', array( $this, 'maybe_dequeue_square_legacy_scripts' ), 999 ); } /** * Returns and/or create the single instance of this class. * * @since 1.2.0 * * @return Charitable_Gateways */ public static function get_instance() { if ( is_null( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Register gateways. * * To register a new gateway, you need to hook into the `charitable_payment_gateways` * hook and give Charitable the name of your gateway class. * * @since 1.2.0 * * @return void */ public function register_gateways() { /** * Filter the list of payment gateways. * * @since 1.2.0 * @version 1.8.7 * * @param array $gateways The list of gateways in gateway ID => gateway class format. */ $gateways = array( 'stripe' => 'Charitable_Gateway_Stripe_AM', 'paypal' => 'Charitable_Gateway_Paypal', 'offline' => 'Charitable_Gateway_Offline', ); // Always add Square Core to the available gateways. $gateways['square_core'] = 'Charitable_Gateway_Square'; $this->gateways = apply_filters( 'charitable_payment_gateways', $gateways ); // If Legacy mode is active and Square Legacy gateway is active, deactivate Square Core. if ( charitable_square_legacy_mode() && $this->is_active_gateway( 'square' ) ) { $this->disable_gateway( 'square_core' ); if ( charitable_is_debug( 'square' ) ) { error_log( '[Charitable Square Core] Deactivated Square Core because Square Legacy is active' ); // phpcs:ignore } } } /** * Receives a request to enable or disable a payment gateway and validates it before passing it off. * * @since 1.0.0 * * @return void */ public function handle_gateway_settings_request() { if ( ! wp_verify_nonce( $_REQUEST['_nonce'], 'gateway' ) ) { // phpcs:ignore wp_die( __( 'Cheatin\' eh?!', 'charitable' ) ); // phpcs:ignore } $gateway = isset( $_REQUEST['gateway_id'] ) ? $_REQUEST['gateway_id'] : false; /* Gateway must be set */ if ( false === $gateway ) { wp_die( __( 'Missing gateway.', 'charitable' ) ); // phpcs:ignore } /* Validate gateway. */ if ( ! isset( $this->gateways[ $gateway ] ) ) { wp_die( __( 'Invalid gateway.', 'charitable' ) ); // phpcs:ignore } switch ( $_REQUEST['charitable_action'] ) { // phpcs:ignore case 'disable_gateway': $this->disable_gateway( $gateway ); break; case 'enable_gateway': $this->enable_gateway( $gateway ); $this->redirect_gateway_settings( $gateway ); break; case 'make_default_gateway': $this->set_default_gateway( $gateway ); break; default: /** * Do something when a gateway settings request takes place. * * @since 1.0.0 * * @param string $action The action taking place. * @param string $gateway_id The gateway ID. */ do_action( 'charitable_gateway_settings_request', $_REQUEST['charitable_action'], $gateway ); // phpcs:ignore } } /** * Returns all available payment gateways. * * @since 1.0.0 * * @return array */ public function get_available_gateways() { if ( isset( $this->gateways['stripe'] ) ) { $this->gateways['stripe'] = charitable()->is_stripe_connect_addon() ? 'Charitable_Gateway_Stripe_AM' : $this->gateways['stripe']; } return $this->gateways; } /** * Returns the current active gateways. * * @since 1.0.0 * * @return string[] */ public function get_active_gateways() { $active_gateways = charitable_get_option( 'active_gateways', array() ); // Force cleanup of 'square' gateway if charitable-square plugin is not active (runs once per 24 hours). $this->maybe_force_cleanup_square_gateway( $active_gateways ); foreach ( $active_gateways as $gateway_id => $gateway_class ) { if ( ! class_exists( $gateway_class ) ) { unset( $active_gateways[ $gateway_id ] ); } } // Remove 'square' gateway if charitable-square plugin is not active. if ( isset( $active_gateways['square'] ) && ! $this->is_square_addon_active() ) { unset( $active_gateways['square'] ); } uksort( $active_gateways, array( $this, 'sort_by_default' ) ); // force the strip active gateway normally for stripe addon to point to the stripe built into core. if ( isset( $active_gateways['stripe'] ) ) { $active_gateways['stripe'] = 'Charitable_Gateway_Stripe_AM'; } /** * Filter the list of active gateways. * * @since 1.0.0 * * @param array $gateways Active gateways. */ return apply_filters( 'charitable_active_gateways', $active_gateways ); } /** * Returns an array of the active gateways, in ID => name format. * * This is useful for select/radio input fields. * * @since 1.0.0 * * @return string[] */ public function get_gateway_choices() { $gateways = array(); foreach ( $this->get_active_gateways() as $id => $class ) { $gateway = new $class(); $gateways[ $id ] = $gateway->get_label(); } return $gateways; } /** * Returns a text description of the active gateways. * * @since 1.3.0 * * @return string[] */ public function get_active_gateways_names() { $gateways = array(); foreach ( $this->get_active_gateways() as $id => $class ) { $gateway = new $class(); $gateways[] = $gateway->get_name(); } return $gateways; } /** * Return the gateway class name for a given gateway. * * @since 1.0.0 * * @param string $gateway Gateway ID. * @return string|false */ public function get_gateway( $gateway ) { return isset( $this->gateways[ $gateway ] ) ? $this->gateways[ $gateway ] : false; } /** * Return the gateway object for a given gateway. * * @since 1.0.0 * * @param string $gateway Gateway ID. * @return Charitable_Gateway|null */ public function get_gateway_object( $gateway ) { $class = $this->get_gateway( $gateway ); $object = $class ? new $class() : null; /** * Filter the gateway object. * * @since 1.6.30 * * @param Charitable_Gateway|null $object The gateway object. */ return apply_filters( 'charitable_gateway_object_' . $gateway, $object, $gateway ); } /** * Returns whether the passed gateway is active. * * @since 1.0.0 * * @param string $gateway_id Gateway ID. * @return boolean */ public function is_active_gateway( $gateway_id ) { return array_key_exists( $gateway_id, $this->get_active_gateways() ); } /** * Checks whether the submitted gateway is valid. * * @since 1.4.3 * * @param string $gateway Gateway ID. * @return boolean */ public function is_valid_gateway( $gateway ) { /** * Validate a particular gatewya. * * @since 1.4.3 * * @param boolean $valid Whether a gateway is valid. * @param string $gateway The gateway ID. */ if ( charitable_is_debug( 'webhook' ) ) { // phpcs:disable error_log( 'is_valid_gateway' ); error_log( print_r( $gateway, true ) ); error_log( print_r( $this->gateways, true ) ); // phpcs:enable } return apply_filters( 'charitable_is_valid_gateway', array_key_exists( $gateway, $this->gateways ), $gateway ); } /** * Returns the default gateway. * * @since 1.0.0 * * @return string */ public function get_default_gateway() { return charitable_get_option( 'default_gateway', '' ); } /** * Provide default gateway settings fields. * * @since 1.0.0 * * @param array $settings Gateway settings. * @param Charitable_Gateway $gateway The gateway's helper object. * @return array */ public function register_gateway_settings( $settings, Charitable_Gateway $gateway ) { add_filter( 'charitable_settings_fields_gateways_gateway_' . $gateway->get_gateway_id(), array( $gateway, 'default_gateway_settings' ), 5 ); add_filter( 'charitable_settings_fields_gateways_gateway_' . $gateway->get_gateway_id(), array( $gateway, 'gateway_settings' ), 15 ); /** * Filter the settings to show for a particular gateway. * * @since 1.0.0 * * @param array $settings Gateway settings. */ return apply_filters( 'charitable_settings_fields_gateways_gateway_' . $gateway->get_gateway_id(), $settings ); } /** * Returns true if test mode is enabled. * * @since 1.0.0 * * @return boolean */ public function in_test_mode() { $enabled = charitable_get_option( 'test_mode', false ); /** * Return whether Charitable is in test mode. * * @since 1.0.0 * * @param boolean $enabled Whether test mode is on. */ return apply_filters( 'charitable_in_test_mode', $enabled ); } /** * Checks whether all of the active gateways support a feature. * * If ANY gateway doesn't support the feature, this returns false. * * @since 1.4.0 * * @param string $feature Feature to search for. * @return boolean */ public function all_gateways_support( $feature ) { foreach ( $this->get_active_gateways() as $gateway_id => $gateway_class ) { $gateway_object = new $gateway_class(); if ( false === $gateway_object->supports( $feature ) ) { return false; } } return true; } /** * Checks whether any of the active gateways support a feature. * * If any gateway supports the feature, this returns true. Otherwise false. * * @since 1.4.0 * * @param string $feature Feature to check for. * @return boolean */ public function any_gateway_supports( $feature ) { foreach ( $this->get_active_gateways() as $gateway_id => $gateway_class ) { $gateway_object = new $gateway_class(); if ( true === $gateway_object->supports( $feature ) ) { return true; } } return false; } /** * Checks whether all of the active gateways support AJAX. * * If ANY gateway doesn't support AJAX, this returns false. * * @since 1.3.0 * * @return boolean */ public function gateways_support_ajax() { return $this->all_gateways_support( '1.3.0' ); } /** * Return an array of recommended gateways for the current site. * * Note that this will only return gateways that are not already * available on the site. i.e. If you have Stripe installed, it * will not suggest that. * * @since 1.5.0 * * @return array */ public function get_recommended_gateways() { $available = $this->get_available_gateways(); $gateways = array( 'payfast' => __( 'Payfast', 'charitable' ), 'paystack' => __( 'Paystack', 'charitable' ), 'stripe' => __( 'Stripe', 'charitable' ), 'authorize_net' => __( 'Authorize.Net', 'charitable' ), 'windcave' => __( 'Windcave', 'charitable' ), 'braintree' => __( 'Braintree', 'charitable' ), 'mollie' => __( 'Mollie', 'charitable' ), 'gocardless' => __( 'GoCardless', 'charitable' ), 'payrexx' => __( 'Payrexx', 'charitable' ), ); /* If the user has already enabled one of these, leave them alone. :) */ foreach ( $gateways as $gateway_id => $gateway ) { if ( array_key_exists( $gateway_id, $available ) ) { return array(); } } $currency = charitable_get_default_currency(); $locale = get_locale(); if ( 'en_ZA' == $locale || 'ZAR' == $currency ) { return charitable_array_subset( $gateways, array( 'payfast', 'paystack' ) ); } if ( in_array( $currency, array( 'NGN', 'GHS' ) ) ) { return charitable_array_subset( $gateways, array( 'paystack' ) ); } if ( in_array( $locale, array( 'en_NZ', 'en_AU', 'en_GB' ) ) || in_array( $currency, array( 'NZD', 'AUD', 'GBP' ) ) ) { return charitable_array_subset( $gateways, array( 'stripe', 'gocardless' ) ); } if ( in_array( $locale, array( 'ms_MY', 'ja', 'zh_HK' ) ) || in_array( $currency, array( 'MYR', 'JPY', 'HKD' ) ) ) { return charitable_array_subset( $gateways, array( 'stripe', 'windcave' ) ); } if ( in_array( $locale, array( 'th' ) ) || in_array( $currency, array( 'BND', 'FJD', 'KWD', 'PGK', 'SBD', 'THB', 'TOP', 'VUV', 'WST' ) ) ) { return charitable_array_subset( $gateways, array( 'windcave' ) ); } if ( in_array( $currency, array( 'EUR' ) ) ) { return charitable_array_subset( $gateways, array( 'stripe', 'mollie' ) ); } if ( in_array( $currency, array( 'CHF', 'DKK' ) ) ) { return charitable_array_subset( $gateways, array( 'stripe', 'payrexx' ) ); } return charitable_array_subset( $gateways, array( 'stripe', 'braintree' ) ); } /** * Sets the default gateway. * * @since 1.0.0 * * @param string $gateway Gateway ID. * @return void */ protected function set_default_gateway( $gateway ) { $settings = get_option( 'charitable_settings' ); $settings['default_gateway'] = $gateway; update_option( 'charitable_settings', $settings ); charitable_get_admin_notices()->add_success( __( 'Default Gateway Updated', 'charitable' ) ); do_action( 'charitable_set_gateway_gateway', $gateway ); } /** * Enable a payment gateway. * * @since 1.0.0 * * @param string $gateway Gateway ID. * @param bool $show_update_message Whether to show the update message. * @return void */ protected function enable_gateway( $gateway, $show_update_message = true ) { $settings = get_option( 'charitable_settings' ); if ( false === $settings || ! is_array( $settings ) ) { echo 'settings is false'; $settings = array(); } $active_gateways = isset( $settings['active_gateways'] ) ? $settings['active_gateways'] : array(); $active_gateways[ $gateway ] = $this->gateways[ $gateway ]; if ( ! isset( $settings['active_gateways'] ) ) { $settings['active_gateways'] = array(); } $settings['active_gateways'] = $active_gateways; /* If this is the only gateway, make it the default gateway */ if ( 1 == count( $settings['active_gateways'] ) ) { $settings['default_gateway'] = $gateway; } update_option( 'charitable_settings', $settings ); if ( $show_update_message ) { Charitable_Settings::get_instance()->add_update_message( __( 'Gateway enabled', 'charitable' ), 'success' ); } /** * Do something when a payment gateway is enabled. * * @since 1.0.0 * * @param string $gateway The payment gateway. */ do_action( 'charitable_gateway_enable', $gateway ); } /** * Disable a payment gateway. * * @since 1.0.0 * * @param string $gateway Gateway ID. * @return void */ protected function disable_gateway( $gateway ) { $settings = get_option( 'charitable_settings' ); if ( ! isset( $settings['active_gateways'][ $gateway ] ) ) { return; } unset( $settings['active_gateways'][ $gateway ] ); /* Set a new default gateway */ if ( $gateway == $this->get_default_gateway() ) { $settings['default_gateway'] = count( $settings['active_gateways'] ) ? key( $settings['active_gateways'] ) : ''; } update_option( 'charitable_settings', $settings ); Charitable_Settings::get_instance()->add_update_message( __( 'Gateway disabled', 'charitable' ), 'success' ); /** * Do something when a payment gateway is disabled. * * @since 1.0.0 * * @param string $gateway The payment gateway. */ do_action( 'charitable_gateway_disable', $gateway ); } /** * Connects to Stripe by saving account information passed back to the plugin. * * @since 4.2.2 * * @return void */ public function connect_gateways() { // Current user cannot handle this request. if ( ! current_user_can( 'manage_options' ) ) { return; } // Do not need to handle this request, bail. if ( ! isset( $_GET['wpcharitable_gateway_connect_completion'] ) || // phpcs:ignore 'stripe_connect' !== $_GET['wpcharitable_gateway_connect_completion'] || // phpcs:ignore ! isset( $_GET['state'] ) // phpcs:ignore ) { return; } // Unable to redirect, bail. if ( headers_sent() ) { return; } if ( isset( $_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'] ) ) { $current_url = ( is_ssl() ? 'https' : 'http' ) . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; } else { $current_url = ''; } $customer_site_url = remove_query_arg( array( 'state', 'wpcharitable_gateway_connect_completion', ), $current_url ); $wpcharitable_credentials_url = add_query_arg( array( 'live_mode' => (int) ! charitable_get_option( 'test_mode' ), 'state' => sanitize_text_field( $_GET['state'] ), // phpcs:ignore 'customer_site_url' => urlencode( $customer_site_url ), ), 'https://wpcharitable.com/stripe-connect/?wpcharitable_gateway_connect_credentials=stripe_connect' ); // You might need to add add_filter('https_ssl_verify', '__return_false'); here if testing locally. $response = wp_remote_get( esc_url_raw( $wpcharitable_credentials_url ) ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { $stripe_account_settings_url = add_query_arg( array( 'tab' => 'gateways', 'page' => 'charitable-settings', 'group' => 'gateways_stripe', ), admin_url( 'admin.php' ) ); $message = wpautop( sprintf( /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */ __( 'There was an error getting your Square credentials. Please %1$stry again%2$s. If you continue to have this problem, please contact support.', 'charitable' ), '<a href="' . esc_url( $stripe_account_settings_url ) . '">', '</a>' ) ); wp_die( $message ); } $body = wp_remote_retrieve_body( $response ); /** @var string $body */ $body = json_decode( $body, true ); /** @var array<array<string>> $body */ $account_data = $body['data']; $this->save_account_information( $account_data ); // update the option to track that we are using stripe connect. update_option( 'charitable_using_stripe_connect', time() ); /** * Allow further processing after connecting a Stripe account. * * @since 3.6.0 * * @param array $data Stripe response data. */ do_action( 'wpcharitable_stripe_account_connected', $account_data ); wp_redirect( esc_url_raw( $customer_site_url ) ); exit; } /** * Refreshes the Square token. * * @since 1.8.7 * * @return void */ public function refresh_square_token() { // Current user cannot handle this request. if ( ! current_user_can( 'manage_options' ) || charitable_square_legacy_mode() ) { return; } // Do not need to handle this request, bail. if ( ! isset( $_GET['wpcharitable_gateway_refresh_token_completion'] ) || // phpcs:ignore 'square_connect' !== $_GET['wpcharitable_gateway_refresh_token_completion'] || // phpcs:ignore ! isset( $_GET['state'] ) // phpcs:ignore ) { return; } // Unable to redirect, bail. if ( headers_sent() ) { return; } if ( charitable_is_debug( 'square' ) ) { error_log( 'checking for use: refresh_square_token' ); // phpcs:ignore } if ( isset( $_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'] ) ) { $current_url = ( is_ssl() ? 'https' : 'http' ) . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; // phpcs:ignore } else { $current_url = ''; } $customer_site_url = remove_query_arg( array( 'state', 'wpcharitable_gateway_refresh_token_completion', 'message', ), $current_url ); $wpcharitable_credentials_url = add_query_arg( array( 'live_mode' => (int) ! charitable_get_option( 'test_mode' ), 'state' => sanitize_text_field( $_GET['state'] ), // phpcs:ignore 'code' => 'request_credentials', 'customer_site_url' => urlencode( $customer_site_url ), ), 'https://connect.wpcharitable.com/square-connect/' ); $response = wp_remote_get( esc_url_raw( $wpcharitable_credentials_url ) ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { $square_account_settings_url = add_query_arg( array( 'tab' => 'gateways', 'page' => 'charitable-settings', 'group' => 'gateways_square_core', ), admin_url( 'admin.php' ) ); $message = wpautop( sprintf( /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */ __( 'There was an error getting your Square credentials. Please %1$stry again%2$s. If you continue to have this problem, please contact support.', 'charitable' ), '<a href="' . esc_url( $square_account_settings_url ) . '">', '</a>' ) ); wp_die( $message ); // phpcs:ignore } $body = wp_remote_retrieve_body( $response ); $body = json_decode( $body, true ); $account_data = $body['data']; $this->save_account_information_square( $account_data ); // Don't show the success message if we are on the welcome / getting started page (otherwise it's fine). if ( ! isset( $_GET['page'] ) || 'charitable-getting-started' !== $_GET['page'] ) { // phpcs:ignore // translators: %s is the mode of the connection. charitable_get_admin_notices()->add_success( sprintf( __( 'You have reconnected and updated your access token for Square in %s mode.', 'charitable' ), charitable_get_option( 'test_mode' ) ? 'test' : 'live' ) ); } // update the option to track that we are using square connect. // Get the value and update it. $charitable_using_square_connect = get_option( 'charitable_using_square_connect', array() ); if ( ! is_array( $charitable_using_square_connect ) ) { $charitable_using_square_connect = array(); } $charitable_using_square_connect['test'] = time(); update_option( 'charitable_using_square_connect', $charitable_using_square_connect ); /** * Allow further processing after reconnecting a Square account. * * @since 3.6.0 * * @param array $data Square response data. */ do_action( 'wpcharitable_square_token_refreshed', $account_data ); wp_safe_redirect( esc_url_raw( $customer_site_url ) ); exit; } /** * Schedule the Square token renewal cron job. * * @since 1.8.7 * * @param string $mode The mode to schedule the cron for (test/live). * @return void */ private function schedule_square_token_renewal_cron( $mode ) { // Clear any existing cron jobs for this mode. wp_clear_scheduled_hook( 'charitable_square_token_renewal', array( $mode ) ); // Schedule the cron job to run every 14 days. wp_schedule_event( time() + ( 14 * DAY_IN_SECONDS ), '14days', 'charitable_square_token_renewal', array( $mode ) ); } /** * Renew the Square token via cron job. * * @since 1.8.7 * * @param string $mode The mode to renew the token for (test/live). * @return void */ public function renew_square_token_cron( $mode ) { if ( charitable_is_debug( 'square' ) ) { // phpcs:disable error_log( 'renew_square_token_cron for test mode: ' . $mode ); // phpcs:enable } // Get the URL to renew the token. $url = Charitable_Gateway_Square::get_instance()->get_square_renew_token_url( '', true ); if ( charitable_is_debug( 'square' ) ) { // phpcs:disable error_log( 'url: ' . $url ); // phpcs:enable } // Clear both failed and success options. delete_option( 'wpcharitable_square_failed_token_renewal_' . $mode ); delete_option( 'wpcharitable_square_token_refreshed_' . $mode ); if ( empty( $url ) ) { update_option( 'wpcharitable_square_failed_token_renewal_' . $mode, time() ); return; } // Add SSL verification argsget_square_renew_token_url. $args = array( 'timeout' => 30, 'sslverify' => false, // Temporarily disable SSL verification. 'headers' => array( 'Content-Type' => 'application/json', ), ); // Make the request to the proxy server. $response = wp_remote_get( esc_url_raw( $url ), $args ); if ( charitable_is_debug( 'square' ) ) { // phpcs:disable error_log( 'response: ' . print_r( $response, true ) ); // phpcs:enable } if ( is_wp_error( $response ) ) { if ( charitable_is_debug( 'square' ) ) { // phpcs:disable error_log( 'The cron job url has failed with a wp_error: ' . $response->get_error_message() ); // phpcs:enable } update_option( 'wpcharitable_square_failed_token_renewal_' . $mode, time() ); return; } $response_code = wp_remote_retrieve_response_code( $response ); if ( 200 !== $response_code ) { if ( charitable_is_debug( 'square' ) ) { // phpcs:disable error_log( 'The cron job url has failed with response code: ' . $response_code ); // phpcs:enable } update_option( 'wpcharitable_square_failed_token_renewal_' . $mode, time() ); return; } $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); if ( charitable_is_debug( 'square' ) ) { // phpcs:disable error_log( 'data: ' . print_r( $data, true ) ); error_log( 'body: ' . print_r( $body, true ) ); // phpcs:enable } if ( empty( $data ) || ! isset( $data['data'] ) ) { if ( charitable_is_debug( 'square' ) ) { // phpcs:disable error_log( 'The cron job url has failed - no data returned.' ); // phpcs:enable } update_option( 'wpcharitable_square_failed_token_renewal_' . $mode, time() ); return; } // Update the stored tokens. $settings = get_option( 'charitable_settings' ); $settings['gateways_square'][ $mode ]['access_token'] = isset( $data['data']['access_token'] ) ? sanitize_text_field( $data['data']['access_token'] ) : false; $settings['gateways_square'][ $mode ]['refresh_token'] = isset( $data['data']['refresh_token'] ) ? sanitize_text_field( $data['data']['refresh_token'] ) : false; $settings['gateways_square'][ $mode ]['token_refresh_date'] = time(); update_option( 'charitable_settings', $settings ); // Clear any failure notices. delete_option( 'wpcharitable_square_failed_token_renewal_' . $mode ); // Add a success notice. update_option( 'wpcharitable_square_token_refreshed_' . $mode, time() ); if ( charitable_is_debug( 'square' ) ) { // phpcs:disable error_log( 'wpcharitable_square_token_refreshed_' . $mode . ' updated to: ' . time() ); // phpcs:enable } } /** * Saves the account information sent back from Square, alongside other, to identify the connected account. * * @since 1.8.7 * * @param array<string> $data Square oAuth account data. * @param string $gateway_id The gateway ID. * @return void */ private function save_account_information_square( $data, $gateway_id = 'square' ) { if ( charitable_is_debug( 'square' ) ) { // phpcs:disable error_log( 'save_account_information_square' ); error_log( print_r( $data, true ) ); // phpcs:enable } $mode = $this->in_test_mode() ? 'test' : 'live'; $settings = get_option( 'charitable_settings' ); $settings[ 'gateways_' . $gateway_id ][ $mode ]['access_token'] = isset( $data['access_token'] ) ? sanitize_text_field( $data['access_token'] ) : false; $settings[ 'gateways_' . $gateway_id ][ $mode ]['refresh_token'] = isset( $data['refresh_token'] ) ? sanitize_text_field( $data['refresh_token'] ) : false; $settings[ 'gateways_' . $gateway_id ][ $mode ]['merchant_id'] = isset( $data['merchant_id'] ) ? sanitize_text_field( $data['merchant_id'] ) : false; $settings[ 'gateways_' . $gateway_id ][ $mode ]['location_id'] = isset( $data['location_id'] ) ? sanitize_text_field( $data['location_id'] ) : false; $settings[ 'gateways_' . $gateway_id ][ $mode ]['token_refresh_date'] = time(); update_option( 'charitable_settings', $settings ); // We save the AES key in it's own WordPress options field, marked as 'charitable_square_aes_key_test' or 'charitable_square_aes_key_live'. $aes_key = isset( $data['aes_key'] ) ? sanitize_text_field( $data['aes_key'] ) : false; if ( charitable_is_debug( 'square' ) ) { // phpcs:disable error_log( 'aes_key: ' . $aes_key ); // phpcs:enable } update_option( 'charitable_square_aes_key_' . $mode, $aes_key ); // Schedule the token renewal cron job. $this->schedule_square_token_renewal_cron( $mode ); do_action( 'charitable_save_account_information_gateway_' . $gateway_id, $settings, $data, $gateway_id ); } /** * Saves the account information sent back from Stripe, alongside other, to identify the connected account. * * @since 4.4.2 * @version 1.8.1.12 * * @param array<string> $data Stripe oAuth account data. * @param string $gateway_id The gateway ID. * @return void */ private function save_account_information( $data, $gateway_id = 'stripe' ) { $prefix = $this->in_test_mode() ? 'test' : 'live'; $settings = get_option( 'charitable_settings' ); $settings[ 'gateways_' . $gateway_id ]['live_secret_key'] = ''; $settings[ 'gateways_' . $gateway_id ]['live_public_key'] = ''; $settings[ 'gateways_' . $gateway_id ]['test_secret_key'] = ''; $settings[ 'gateways_' . $gateway_id ]['test_public_key'] = ''; $settings[ 'gateways_' . $gateway_id ][ $prefix . '_secret_key' ] = isset( $data['secret_key'] ) ? sanitize_text_field( $data['secret_key'] ) : false; $settings[ 'gateways_' . $gateway_id ][ $prefix . '_public_key' ] = isset( $data['publishable_key'] ) ? sanitize_text_field( $data['publishable_key'] ) : false; if ( charitable_is_debug( 'webhook' ) ) { // phpcs:disable error_log( 'save_account_information' ); error_log( print_r( $settings, true ) ); // phpcs:enable } update_option( 'charitable_settings', $settings ); // Don't show the success message if we are on the welcome / getting started page (otherwise it's fine). if ( ! isset( $_GET['page'] ) || 'charitable-getting-started' !== $_GET['page'] ) { // phpcs:ignore charitable_get_admin_notices()->add_success( __( 'Stripe Information Updated', 'charitable' ) ); } do_action( 'charitable_save_account_information_gateway_' . $gateway_id, $settings, $data, $gateway_id ); } /** * Disconnects from Stripe by removing associated account information. * * This does not deauthorize the application within the Stripe account. * * @since 4.2.2 * * @return void */ public function disconnect_gateways() { // Do not need to handle this request, bail. if ( ! ( isset( $_GET['page'] ) && 'charitable-settings' === $_GET['page'] ) || ! isset( $_GET['wpcharitable-stripe-disconnect'] ) ) { return; } // Current user cannot handle this request. if ( ! current_user_can( 'manage_options' ) ) { return; } if ( ! isset( $_GET['_wpnonce'] ) ) { return; } // Invalid nonce, bail. if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'wpcharitable-stripe-connect-disconnect' ) ) { return; } $settings = get_option( 'charitable_settings' ); unset( $settings['gateways_stripe']['live_secret_key'] ); unset( $settings['gateways_stripe']['live_public_key'] ); unset( $settings['gateways_stripe']['test_secret_key'] ); unset( $settings['gateways_stripe']['test_public_key'] ); update_option( 'charitable_settings', $settings ); // update the option to track that we are using stripe connect. delete_option( 'charitable_using_stripe_connect' ); charitable_get_admin_notices()->add_success( __( 'Stripe Connected Removed', 'charitable' ) ); do_action( 'charitable_remove_connection_gateway_stripe', $settings ); $redirect_url = add_query_arg( array( 'tab' => 'gateways', 'page' => 'charitable-settings', 'group' => 'gateways_stripe', ), admin_url( 'admin.php' ) ); wp_safe_redirect( $redirect_url ); exit; } /** * Disconnects from Square by removing associated account information. * Also remove webhooks from the Square account. * * This does not deauthorize the application within the Square account. * LEGIT BEING CALLED. * * @since 1.8.7 * * @return void */ public function disconnect_gateways_square() { // Do not need to handle this request, bail. if ( ! ( isset( $_GET['page'] ) && 'charitable-settings' === $_GET['page'] ) || ! isset( $_GET['wpcharitable-square-disconnect'] ) || charitable_square_legacy_mode() ) { return; } // We need to know if this is a sandbox or live disconnect. if ( ! isset( $_GET['mode'] ) ) { return; } $mode = sanitize_text_field( wp_unslash( $_GET['mode'] ) ); $mode = 'sandbox' === $mode ? 'test' : 'live'; // Current user cannot handle this request or nonce is invalid. if ( ! current_user_can( 'manage_options' ) || ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ), 'wpcharitable-square-connect-disconnect' ) ) { if ( charitable_is_debug( 'webhook' ) ) { error_log( 'disconnect_gateways_square - user cannot manage options or nonce is invalid' ); // phpcs:ignore } return; } $settings = get_option( 'charitable_settings' ); // Delete the Square connection error notice. delete_option( 'charitable_square_connection_error_notice' ); // Attempt to disconnect / remove webhooks from the Square account. $this->remove_webhooks_from_square_account( $mode, $settings ); $settings['gateways_square'][ $mode ] = array(); update_option( 'charitable_settings', $settings ); // remove the option to track that we are using square connect (test or live). $charitable_using_square_connect = get_option( 'charitable_using_square_connect', array() ); if ( isset( $charitable_using_square_connect[ $mode ] ) ) { unset( $charitable_using_square_connect[ $mode ] ); update_option( 'charitable_using_square_connect', $charitable_using_square_connect ); } // translators: %s is the mode of the connection. charitable_get_admin_notices()->add_success( sprintf( __( 'Your connection to Square in %s mode has been removed.', 'charitable' ), $mode ) ); do_action( 'charitable_remove_connection_gateway_square', $settings ); $redirect_url = add_query_arg( array( 'tab' => 'gateways', 'page' => 'charitable-settings', 'group' => 'gateways_square_core', ), admin_url( 'admin.php' ) ); wp_safe_redirect( $redirect_url ); exit; } /** * Redirects to the gateway settings page once a gateway has been activated. * * @since 1.7.0 * * @param string $gateway Gateway ID. * @return void */ public function redirect_gateway_settings( $gateway ) { $settings_url = add_query_arg( array( 'group' => 'gateways_' . $gateway, ), admin_url( 'admin.php?page=charitable-settings&tab=gateways' ) ); wp_safe_redirect( $settings_url ); exit; } /** * Sort the active gateways, placing the default gateway first. * * @since 1.4.0 * * @param string $a Gateway to compare. * @param string $b Gateway to compare against. * @return int */ protected function sort_by_default( $a, $b ) { $default = $this->get_default_gateway(); if ( $a == $default ) { // phpcs:ignore return -1; } if ( $b == $default ) { // phpcs:ignore return 1; } return 0; } /** * Remove webhooks from the Square account. * * @since 1.8.7 * * @param string $mode The mode to remove the webhooks from. * @param array $settings The settings array. * @param bool $force_remove Whether to force remove the webhooks. * @return void */ public function remove_webhooks_from_square_account( $mode, $settings = array(), $force_remove = true ) { if ( charitable_is_debug( 'square' ) ) { error_log( 'remove_webhooks_from_square_account' ); // phpcs:ignore } // Check if settings are empty and if so, get the settings from the database. if ( empty( $settings ) ) { $settings = get_option( 'charitable_settings' ); } $access_token = $settings['gateways_square'][ $mode ]['access_token']; // Test to see if we have the access token. if ( empty( $access_token ) ) { // if force_remove is true, we can remove the webhooks from the Square account in Charitable. if ( $force_remove ) { if ( charitable_is_debug( 'square' ) ) { error_log( 'remove_webhooks_from_square_account:force_remove' ); // phpcs:ignore } $settings['gateways_square'][ $mode ]['webhooks'] = array(); update_option( 'charitable_settings', $settings ); return; } return; } elseif ( isset( $settings['gateways_square'][ $mode ]['webhook_id'] ) ) { $webhook_manager = new Charitable_Square_WebhooksManager( $mode, $access_token ); $result = $webhook_manager->remove_webhook( $access_token, $settings['gateways_square'][ $mode ]['webhook_id'] ); } if ( charitable_is_debug( 'square' ) ) { error_log( 'remove_webhooks_from_square_account:deactivate_webhook' ); // phpcs:ignore } return $result; } /** * Ensure there is a settings option when landing on settings pages, even if init blank. Mostly applicable to new installs. * * @since 1.4.0 * @since 1.8.1.11 * * @return void */ public function check_settings() { if ( isset( $_GET['page'] ) && 'charitable-settings' !== $_GET['page'] ) { // phpcs:ignore return; } $settings = get_option( 'charitable_settings' ); // attach this to CHARITABLE_DEBUG constant. if ( charitable_is_debug() ) { // phpcs:disable // error_log( 'checking_settings' ); // error_log( print_r( $settings, true ) ); // phpcs:enable } // If there is no settings, or the settings are empty, set the test mode to true and stripe is default gateway. if ( false === $settings || ( is_array( $settings ) && empty( $settings ) ) ) { $this->enable_gateway( 'stripe', false ); $settings = (array) get_option( 'charitable_settings' ); $settings['test_mode'] = true; update_option( 'charitable_settings', $settings ); } } /** * Check the setup stored value of the payment methods. * * @since 1.8.4 * * @return bool */ public function check_setup_payment_methods() { $payment_methods = get_option( 'charitable_setup_payment_methods', array() ); if ( ! is_array( $payment_methods ) ) { return false; } $payment_methods = array_map( 'sanitize_text_field', $payment_methods ); if ( empty( $payment_methods ) ) { return false; } $gateways_enbled = 0; if ( in_array( 'stripe', $payment_methods, true ) ) { // check if this gateway is already enabled. if ( ! $this->is_active_gateway( 'stripe' ) ) { $this->enable_gateway( 'stripe', false ); ++$gateways_enbled; } } if ( in_array( 'paypal', $payment_methods, true ) ) { // check if this gateway is already enabled. if ( ! $this->is_active_gateway( 'paypal' ) ) { $this->enable_gateway( 'paypal', false ); ++$gateways_enbled; } } if ( in_array( 'offline', $payment_methods, true ) ) { // check if this gateway is already enabled. if ( ! $this->is_active_gateway( 'offline' ) ) { $this->enable_gateway( 'offline', false ); } } if ( $gateways_enbled > 0 && class_exists( 'Charitable_Checklist' ) ) { $checklist_class = Charitable_Checklist::get_instance(); $checklist_class->mark_step_completed( 'connect-payment' ); } return true; } /** * Display the test and live fields that represent the manual keys for Stripe that users might be already using prior to 1.7.0. * * @since 1.7.0 */ public function show_stripe_manual_keys_ajax() { if ( ! isset( $_POST ) || 'charitable-show-stripe-keys' !== $_POST['action'] ) { // phpcs:ignore return; } // Invalid nonce, bail. if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'charitable-show-stripe-keys' ) ) { // phpcs:ignore return; } // Current user cannot handle this request. if ( ! current_user_can( 'manage_options' ) ) { return; } $settings = get_option( 'charitable_settings' ); if ( false === $settings ) { return; } $gateway_id = 'stripe'; $live_secret_key = $settings[ 'gateways_' . $gateway_id ]['live_secret_key']; $live_public_key = $settings[ 'gateways_' . $gateway_id ]['live_public_key']; $test_secret_key = $settings[ 'gateways_' . $gateway_id ]['test_secret_key']; $test_public_key = $settings[ 'gateways_' . $gateway_id ]['test_public_key']; $html = '<tr><th scope="row">Live Settings</th><td><hr /> </td></tr><tr class="wide"><th scope="row">Live Secret Key</th><td><input type="text" id="charitable_settings_gateways_stripe_live_secret_key" name="charitable_settings[gateways_stripe][live_secret_key]" value="' . trim( $live_secret_key ) . '" class="charitable-settings-field wide" /> </td></tr><tr class="wide"><th scope="row">Live Publishable Key</th><td><input type="text" id="charitable_settings_gateways_stripe_live_public_key" name="charitable_settings[gateways_stripe][live_public_key]" value="' . trim( $live_public_key ) . '" class="charitable-settings-field wide" /> </td></tr><tr><th scope="row">Test Settings</th><td><hr /> </td></tr><tr class="wide"><th scope="row">Test Secret Key</th><td><input type="text" id="charitable_settings_gateways_stripe_test_secret_key" name="charitable_settings[gateways_stripe][test_secret_key]" value="' . trim( $test_secret_key ) . '" class="charitable-settings-field wide" /> </td></tr><tr class="wide"><th scope="row">Test Publishable Key</th><td><input type="text" id="charitable_settings_gateways_stripe_test_public_key" name="charitable_settings[gateways_stripe][test_public_key]" value="' . trim( $test_public_key ) . '" class="charitable-settings-field wide" /> </td></tr>'; wp_send_json_success( $html ); } /** * Returns the error message for the square connect gateway. * * @since 1.8.7 * * @return void */ public function get_gateway_error_message() { if ( ! isset( $_GET['square_connect_error'] ) && ! isset( $_GET['square_connect_error_description'] ) ) { // phpcs:ignore return; } $square_connect_error = sanitize_text_field( wp_unslash( $_GET['square_connect_error'] ) ); // phpcs:ignore $square_connect_error_description = sanitize_text_field( wp_unslash( $_GET['square_connect_error_description'] ) ); // phpcs:ignore $support_link = 'https://wpcharitable.com/support'; switch ( $square_connect_error ) { case 'access_denied': switch ( $square_connect_error_description ) { case 'user_denied': $message = __( 'You have denied access to Square Connect.', 'charitable' ); break; case 'missing_state_or_code': $message = sprintf( /* translators: %s: Support link URL */ __( 'There has been an issue with your request. Please try again or <a href="%s">contact support</a>.', 'charitable' ), $support_link ); break; case 'missing_init_request': $message = sprintf( /* translators: %s: Support link URL */ __( 'There has been an issue confirming your request. Please try again or <a href="%s">contact support</a>.', 'charitable' ), $support_link ); break; default: $message = sprintf( /* translators: %s: Support link URL */ __( 'Your connect to Square has been canceled for an unknown reason. Please try again or <a href="%s">contact support</a>.', 'charitable' ), $support_link ); break; } break; case 'connect_error': switch ( $square_connect_error_description ) { case 'error_refreshing_token': $refresh_by_date = Charitable_Gateway_Square::get_instance()->get_personal_access_token_should_refresh( 'test' ); $message = sprintf( /* translators: %s: Refresh by date */ __( 'There has been an issue refreshing your Square token. Token should be refreshed by: %1$s. Please try again or <a href="%2$s">contact support</a>.', 'charitable' ), $refresh_by_date, $support_link ); break; case 'missing_response_fields': case 'credentials_not_saved': $message = sprintf( /* translators: %s: Support link URL */ __( 'There has been an issue confirming your Square token. Please try again or <a href="%s">contact support</a>.', 'charitable' ), $support_link ); break; case 'response_error': case 'merchant_id_not_found': case 'save_credentials_error': case 'missing_state_or_code': case 'invalid_request': case 'error_getting_credentials': case 'missing_state_or_site_url': case 'error_getting_credentials': case 'missing_information_for_gateway_connect': case 'error_saving_init_request': $message = sprintf( /* translators: %s: Support link URL */ __( 'There has been an issue communicating with Square. Please try again or <a href="%s">contact support</a>.', 'charitable' ), $support_link ); break; default: $message = sprintf( /* translators: %s: Support link URL */ __( 'There has been an issue with your request. Please try again or <a href="%s">contact support</a>.', 'charitable' ), $support_link ); break; } break; default: $message = sprintf( /* translators: %s: Support link URL */ __( 'There has been an issue with your request. Please try again or <a href="%s">contact support</a>.', 'charitable' ), $support_link ); } charitable_get_admin_notices()->add_notice( $message, 'error', false, true ); } /** * Get the personal access refresh token. * * @since 1.8.7 * * @param string $mode The mode to get the personal access refresh token for. * @return string */ private function get_personal_access_refresh_token( $mode = 'test' ) { $square_settings = charitable_get_option( 'gateways_square', array() ); if ( ! empty( $square_settings[ $mode ]['refresh_token'] ) ) { return $square_settings[ $mode ]['refresh_token']; } return ''; } /** * Add custom cron schedules. * * @since 1.8.7 * * @param array $schedules Existing cron schedules. * @return array */ public function add_cron_schedules( $schedules ) { $schedules['14days'] = array( 'interval' => 14 * DAY_IN_SECONDS, 'display' => __( 'Every 14 days', 'charitable' ), ); return $schedules; } /** * Handle the square gateway switch. * * @since 1.8.7 * * @return void */ public function handle_square_gateway_switch() { // Verify nonce. if ( ! wp_verify_nonce( $_POST['nonce'], 'charitable_admin_nonce' ) ) { wp_send_json_error( array( 'message' => __( 'Security check failed.', 'charitable' ) ) ); } // Check user permissions. if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'charitable' ) ) ); } // Check if Square Legacy is active and Square Core is not active. if ( ! $this->is_active_gateway( 'square' ) || $this->is_active_gateway( 'square_core' ) ) { wp_send_json_error( array( 'message' => __( 'Invalid gateway state for switching.', 'charitable' ) ) ); } // Disable Square Legacy. $this->disable_gateway( 'square' ); // Enable Square Core. $this->enable_gateway( 'square_core', false ); // Get the redirect URL for Square Core settings. $redirect_url = add_query_arg( array( 'page' => 'charitable-settings', 'tab' => 'gateways', 'group' => 'gateways_square_core', ), admin_url( 'admin.php' ) ); wp_send_json_success( array( 'redirect_url' => $redirect_url ) ); } /** * Handle the square core to legacy switch. * * @since 1.8.7 * * @return void */ public function handle_square_core_to_legacy_switch() { // Verify nonce. if ( ! wp_verify_nonce( $_POST['nonce'], 'charitable_admin_nonce' ) ) { wp_send_json_error( array( 'message' => __( 'Security check failed.', 'charitable' ) ) ); } // Check user permissions. if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'charitable' ) ) ); } // Check if Square Core is active and Square Legacy is not active. if ( ! $this->is_active_gateway( 'square_core' ) || $this->is_active_gateway( 'square' ) ) { wp_send_json_error( array( 'message' => __( 'Invalid gateway state for switching.', 'charitable' ) ) ); } if ( charitable_is_debug() ) { error_log( 'Charitable: Starting Square Core to Legacy gateway switch process.' ); // phpcs:ignore } // Disconnect Square Core connections for both live and test modes. $this->disconnect_square_core_connections(); // Disable Square Core. $this->disable_gateway( 'square_core' ); // Enable Square Legacy. $this->enable_gateway( 'square', false ); if ( charitable_is_debug() ) { error_log( 'Charitable: Successfully switched from Square Core to Square Legacy gateway.' ); // phpcs:ignore } // Get the redirect URL for Square Legacy settings. $redirect_url = add_query_arg( array( 'page' => 'charitable-settings', 'tab' => 'gateways', 'group' => 'gateways_square', ), admin_url( 'admin.php' ) ); wp_send_json_success( array( 'redirect_url' => $redirect_url ) ); } /** * Disconnect Square Core connections for both live and test modes. * * @since 1.8.7 * * @return void */ private function disconnect_square_core_connections() { if ( charitable_is_debug() ) { error_log( 'Charitable: Starting Square Core connection disconnection process.' ); // phpcs:ignore } // Check if Charitable_Square_Connection class exists. if ( ! class_exists( 'Charitable_Square_Connection' ) ) { if ( charitable_is_debug() ) { error_log( 'Charitable: Charitable_Square_Connection class not found. Skipping disconnect process.' ); // phpcs:ignore } return; } // Check and disconnect live mode connection. $live_connection = Charitable_Square_Connection::get( 'live' ); if ( $live_connection && $live_connection->is_configured() ) { if ( charitable_is_debug() ) { error_log( 'Charitable: Found active Square Core live connection. Attempting to disconnect.' ); // phpcs:ignore } $this->disconnect_square_core_mode( $live_connection, 'live' ); } elseif ( charitable_is_debug() ) { error_log( 'Charitable: No active Square Core live connection found.' ); // phpcs:ignore } // Check and disconnect test mode connection. $test_connection = Charitable_Square_Connection::get( 'test' ); if ( $test_connection && $test_connection->is_configured() ) { if ( charitable_is_debug() ) { error_log( 'Charitable: Found active Square Core test connection. Attempting to disconnect.' ); // phpcs:ignore } $this->disconnect_square_core_mode( $test_connection, 'test' ); } elseif ( charitable_is_debug() ) { error_log( 'Charitable: No active Square Core test connection found.' ); // phpcs:ignore } if ( charitable_is_debug() ) { error_log( 'Charitable: Completed Square Core connection disconnection process.' ); // phpcs:ignore } } /** * Disconnect Square Core connection for a specific mode. * * @since 1.8.7 * * @param Charitable_Square_Connection $connection The connection object. * @param string $mode The mode (live/test). * @return void */ private function disconnect_square_core_mode( $connection, $mode ) { if ( charitable_is_debug() ) { error_log( 'Charitable: Disconnecting Square Core connection for mode: ' . $mode ); // phpcs:ignore } // Check if Charitable_Square_Connect class exists. if ( ! class_exists( 'Charitable_Square_Connect' ) ) { if ( charitable_is_debug() ) { error_log( 'Charitable: Charitable_Square_Connect class not found. Cannot disconnect mode: ' . $mode ); // phpcs:ignore } return; } try { // Get the Square Connect instance. $square_connect = Charitable_Square_Connect::get_instance(); // Use reflection to access the private handle_disconnect method. $reflection = new ReflectionClass( $square_connect ); $method = $reflection->getMethod( 'handle_disconnect' ); $method->setAccessible( true ); // Set the live_mode parameter for the disconnect process. $_GET['live_mode'] = ( $mode === 'live' ) ? 1 : 0; // Call the disconnect method without redirect. $method->invoke( $square_connect, false ); if ( charitable_is_debug() ) { error_log( 'Charitable: Successfully disconnected Square Core connection for mode: ' . $mode ); // phpcs:ignore } } catch ( Exception $e ) { if ( charitable_is_debug() ) { error_log( 'Charitable: Error disconnecting Square Core connection for mode ' . $mode . ': ' . $e->getMessage() ); // phpcs:ignore } } } /** * Dequeue Square Legacy scripts if Square Legacy is not active. * * @since 1.8.7 * * @return void */ public function maybe_dequeue_square_legacy_scripts() { // Only run on frontend. if ( is_admin() ) { return; } // Debug: Log the status checks. if ( charitable_is_debug( 'square' ) ) { error_log( '[Charitable Square] Script dequeue check - Legacy mode: ' . ( charitable_square_legacy_mode() ? 'true' : 'false' ) ); // phpcs:ignore error_log( '[Charitable Square] Script dequeue check - Square gateway active: ' . ( $this->is_active_gateway( 'square' ) ? 'true' : 'false' ) ); // phpcs:ignore } // Check if Square Legacy is active. if ( ! charitable_square_legacy_mode() || ! $this->is_active_gateway( 'square' ) ) { // Dequeue Square Legacy scripts and styles. wp_dequeue_script( 'charitable-square' ); wp_dequeue_script( 'square' ); wp_dequeue_style( 'charitable-square' ); // Deregister scripts to prevent them from being loaded. wp_deregister_script( 'charitable-square' ); wp_deregister_script( 'square' ); wp_deregister_style( 'charitable-square' ); if ( charitable_is_debug( 'square' ) ) { error_log( '[Charitable Square] Dequeued Square Legacy scripts - Square Legacy is not active' ); // phpcs:ignore } } elseif ( charitable_is_debug( 'square' ) ) { error_log( '[Charitable Square] Square Legacy scripts will remain loaded - Square Legacy is active' ); // phpcs:ignore } } /** * Check if charitable-square plugin is active. * * @since 1.8.7 * * @return boolean */ private function is_square_addon_active() { return is_plugin_active( 'charitable-square/charitable-square.php' ); } /** * Force cleanup of 'square' gateway if charitable-square plugin is not active. * Runs once per 24 hours (adjustable via filter) to avoid constant database checks. * * @since 1.8.7 * * @param array $active_gateways The current active gateways array. * @return void */ private function maybe_force_cleanup_square_gateway( $active_gateways ) { // Check if we need to run cleanup (once per 24 hours). $transient_name = 'charitable_square_cleanup_last_run'; $check_interval = apply_filters( 'charitable_square_cleanup_check_interval', 24 * HOUR_IN_SECONDS ); if ( get_transient( $transient_name ) ) { return; } // Check if 'square' gateway exists and charitable-square plugin is not active. if ( isset( $active_gateways['square'] ) && ! $this->is_square_addon_active() ) { try { // Get current settings. $settings = get_option( 'charitable_settings', array() ); if ( ! empty( $settings['active_gateways']['square'] ) ) { // Remove 'square' gateway from active gateways. unset( $settings['active_gateways']['square'] ); // Update default gateway if it was set to 'square'. if ( isset( $settings['default_gateway'] ) && 'square' === $settings['default_gateway'] ) { $settings['default_gateway'] = ''; } // Remove the option that warns users about incorrect square settings. delete_option( 'charitable_square_mode_connection_warning' ); // Save updated settings. $updated = update_option( 'charitable_settings', $settings ); if ( $updated ) { if ( charitable_is_debug( 'square' ) ) { error_log( '[Charitable Square] Successfully removed legacy square gateway from active gateways' ); // phpcs:ignore } } else { if ( charitable_is_debug( 'square' ) ) { error_log( '[Charitable Square] Failed to update settings when removing legacy square gateway' ); // phpcs:ignore } } } } catch ( Exception $e ) { if ( charitable_is_debug( 'square' ) ) { error_log( '[Charitable Square] Error during square gateway cleanup: ' . $e->getMessage() ); // phpcs:ignore } } } // Set transient to prevent running again for the specified interval. set_transient( $transient_name, time(), $check_interval ); } } endif;
/home/batcwwjx/www/wp-content/plugins/charitable/./includes/gateways/class-charitable-gateways.php