| 1 |
<?php declare(strict_types=1); |
| 2 |
|
| 3 |
namespace MultiSafepay\WooCommerce; |
| 4 |
|
| 5 |
use MultiSafepay\WooCommerce\Blocks\BlocksController; |
| 6 |
use MultiSafepay\WooCommerce\PaymentMethods\Filters\CancelOrderStatuses; |
| 7 |
use MultiSafepay\WooCommerce\PaymentMethods\Filters\CheckoutPaymentUrl; |
| 8 |
use MultiSafepay\WooCommerce\PaymentMethods\Filters\GatewayByCountry; |
| 9 |
use MultiSafepay\WooCommerce\PaymentMethods\Filters\GatewayByMinAmount; |
| 10 |
use MultiSafepay\WooCommerce\PaymentMethods\Filters\GatewayByUserRole; |
| 11 |
use MultiSafepay\WooCommerce\PaymentMethods\Filters\NonDuplicatedBrandedNames; |
| 12 |
use MultiSafepay\WooCommerce\PaymentMethods\Filters\PaymentGatewaysRegistration; |
| 13 |
use MultiSafepay\WooCommerce\PaymentMethods\Filters\PaymentMethodTitle; |
| 14 |
use MultiSafepay\WooCommerce\PaymentMethods\Filters\TransactionOrderId; |
| 15 |
use MultiSafepay\WooCommerce\PaymentMethods\PaymentMethodsController; |
| 16 |
use MultiSafepay\WooCommerce\Services\PaymentComponentService; |
| 17 |
use MultiSafepay\WooCommerce\Services\PostepayMigrationService; |
| 18 |
use MultiSafepay\WooCommerce\Services\Qr\QrPaymentComponentService; |
| 19 |
use MultiSafepay\WooCommerce\Services\Qr\QrPaymentWebhook; |
| 20 |
use MultiSafepay\WooCommerce\Services\ValidationService; |
| 21 |
use MultiSafepay\WooCommerce\Settings\SettingsController; |
| 22 |
use MultiSafepay\WooCommerce\Settings\ThirdPartyCompatibility; |
| 23 |
use MultiSafepay\WooCommerce\Utils\CustomLinks; |
| 24 |
use MultiSafepay\WooCommerce\Utils\Internationalization; |
| 25 |
use MultiSafepay\WooCommerce\Utils\Loader; |
| 26 |
|
| 27 |
/** |
| 28 |
* This class is the core of the plugin. |
| 29 |
* Is used to define internationalization, admin and front hooks. |
| 30 |
*/ |
| 31 |
class Main { |
| 32 |
|
| 33 |
/** |
| 34 |
* The loader that's responsible for maintaining and registering all hooks |
| 35 |
* |
| 36 |
* @var Loader Maintains and registers all hooks for the plugin. |
| 37 |
*/ |
| 38 |
public $loader; |
| 39 |
|
| 40 |
/** |
| 41 |
* Define the core functionality of the plugin. |
| 42 |
* |
| 43 |
* Load the dependencies, define the locale, and set the hooks for the admin area and |
| 44 |
* the public face of the site. |
| 45 |
*/ |
| 46 |
public function __construct() { |
| 47 |
$this->loader = new Loader(); |
| 48 |
$this->compatibilities(); |
| 49 |
$this->set_locale(); |
| 50 |
$this->custom_links_in_plugin_list(); |
| 51 |
$this->settings_hooks(); |
| 52 |
$this->block_hooks(); |
| 53 |
$this->payment_methods_hooks(); |
| 54 |
$this->payment_components_hooks(); |
| 55 |
$this->payment_components_qr_hooks(); |
| 56 |
$this->callback_hooks(); |
| 57 |
$this->validation_hooks(); |
| 58 |
} |
| 59 |
|
| 60 |
/** |
| 61 |
* Define compatibilities with third party plugins |
| 62 |
* |
| 63 |
* @return void |
| 64 |
*/ |
| 65 |
private function compatibilities(): void { |
| 66 |
$compatibilities = new ThirdPartyCompatibility(); |
| 67 |
$this->loader->add_action( 'before_woocommerce_init', $compatibilities, 'declare_all_compatibilities' ); |
| 68 |
} |
| 69 |
|
| 70 |
/** |
| 71 |
* Define the locale for this plugin for internationalization. |
| 72 |
* |
| 73 |
* Uses the Internationalization class in order to set the domain and register the hook |
| 74 |
* with WordPress. |
| 75 |
* |
| 76 |
* @return void |
| 77 |
*/ |
| 78 |
private function set_locale() { |
| 79 |
$plugin_i18n = new Internationalization(); |
| 80 |
$this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' ); |
| 81 |
} |
| 82 |
|
| 83 |
|
| 84 |
/** |
| 85 |
* Define the custom links in the plugin list |
| 86 |
* |
| 87 |
* @see https://developer.wordpress.org/reference/hooks/plugin_action_links_plugin_file/ |
| 88 |
* |
| 89 |
* @return void |
| 90 |
*/ |
| 91 |
private function custom_links_in_plugin_list(): void { |
| 92 |
$custom_links = new CustomLinks(); |
| 93 |
$this->loader->add_filter( 'plugin_action_links_multisafepay/multisafepay.php', $custom_links, 'get_links' ); |
| 94 |
} |
| 95 |
|
| 96 |
/** |
| 97 |
* Register the hooks related to the common settings |
| 98 |
* of the plugin. |
| 99 |
* |
| 100 |
* @return void |
| 101 |
*/ |
| 102 |
private function settings_hooks(): void { |
| 103 |
$plugin_settings = new SettingsController(); |
| 104 |
|
| 105 |
// Filter get_option for some option names. |
| 106 |
$this->loader->add_filter( 'option_multisafepay_testmode', $plugin_settings, 'filter_multisafepay_settings_as_booleans' ); |
| 107 |
$this->loader->add_filter( 'option_multisafepay_debugmode', $plugin_settings, 'filter_multisafepay_settings_as_booleans' ); |
| 108 |
$this->loader->add_filter( 'option_multisafepay_second_chance', $plugin_settings, 'filter_multisafepay_settings_as_booleans' ); |
| 109 |
$this->loader->add_filter( 'option_multisafepay_final_order_status', $plugin_settings, 'filter_multisafepay_settings_as_booleans' ); |
| 110 |
$this->loader->add_filter( 'option_multisafepay_disable_shopping_cart', $plugin_settings, 'filter_multisafepay_settings_as_booleans' ); |
| 111 |
$this->loader->add_filter( 'option_multisafepay_time_active', $plugin_settings, 'filter_multisafepay_settings_as_int' ); |
| 112 |
|
| 113 |
if ( is_admin() ) { |
| 114 |
// Enqueue styles and JavaScript file in controller settings page |
| 115 |
$this->loader->add_action( 'admin_enqueue_scripts', $plugin_settings, 'enqueue_styles_and_scripts', 1 ); |
| 116 |
// Add menu page for common settings page |
| 117 |
$this->loader->add_action( 'admin_menu', $plugin_settings, 'register_common_settings_page', 9 ); |
| 118 |
// Add the new settings page the WooCommerce screen options |
| 119 |
$this->loader->add_filter( 'woocommerce_screen_ids', $plugin_settings, 'set_wc_screen_options_in_common_settings_page' ); |
| 120 |
// Register settings |
| 121 |
$this->loader->add_action( 'admin_init', $plugin_settings, 'register_common_settings' ); |
| 122 |
// Filter and return ordered the results of the fields |
| 123 |
$this->loader->add_filter( 'multisafepay_common_settings_fields', $plugin_settings, 'filter_multisafepay_common_settings_fields', 10, 1 ); |
| 124 |
|
| 125 |
// Handle PostePay migration in the admin area |
| 126 |
$postepay_migration = new PostepayMigrationService(); |
| 127 |
$this->loader->add_action( 'admin_init', $postepay_migration, 'postepay_migration', 5 ); |
| 128 |
} |
| 129 |
} |
| 130 |
|
| 131 |
/** |
| 132 |
* Register the hooks related to the payment methods |
| 133 |
* of the plugin. |
| 134 |
* |
| 135 |
* @return void |
| 136 |
*/ |
| 137 |
private function payment_methods_hooks(): void { |
| 138 |
$this->payment_methods_filters_hooks(); |
| 139 |
$this->payment_methods_actions_hooks( new PaymentMethodsController() ); |
| 140 |
} |
| 141 |
|
| 142 |
/** |
| 143 |
* Register payment methods filter hooks. |
| 144 |
* |
| 145 |
* @return void |
| 146 |
*/ |
| 147 |
private function payment_methods_filters_hooks(): void { |
| 148 |
// Register the MultiSafepay payment gateways in WooCommerce. |
| 149 |
$this->loader->add_filter( 'woocommerce_payment_gateways', ( new PaymentGatewaysRegistration() ), 'get_woocommerce_payment_gateways' ); |
| 150 |
// Filter transaction order id on callback |
| 151 |
$this->loader->add_filter( 'multisafepay_transaction_order_id', ( new TransactionOrderId() ), 'multisafepay_transaction_order_id', 11 ); |
| 152 |
// Filter per country |
| 153 |
$this->loader->add_filter( 'woocommerce_available_payment_gateways', ( new GatewayByCountry() ), 'filter_gateway_per_country', 11 ); |
| 154 |
// Filter per min amount |
| 155 |
$this->loader->add_filter( 'woocommerce_available_payment_gateways', ( new GatewayByMinAmount() ), 'filter_gateway_per_min_amount', 12 ); |
| 156 |
// Filter per user role |
| 157 |
$this->loader->add_filter( 'woocommerce_available_payment_gateways', ( new GatewayByUserRole() ), 'filter_gateway_per_user_roles', 13 ); |
| 158 |
// Filter duplicated branded payment methods |
| 159 |
$this->loader->add_filter( 'woocommerce_available_payment_gateways', ( new NonDuplicatedBrandedNames() ), 'filter_non_duplicated_branded_names', 14 ); |
| 160 |
// Replace checkout payment url if a payment link has been generated in backoffice |
| 161 |
$this->loader->add_filter( 'woocommerce_get_checkout_payment_url', ( new CheckoutPaymentUrl() ), 'replace_checkout_payment_url', 10, 2 ); |
| 162 |
// Allow cancel orders for on-hold status |
| 163 |
$this->loader->add_filter( 'woocommerce_valid_order_statuses_for_cancel', ( new CancelOrderStatuses() ), 'allow_cancel_multisafepay_orders_with_on_hold_status', 10, 2 ); |
| 164 |
// Use the stored order payment method title in the admin order context |
| 165 |
if ( is_admin() && ! wp_doing_ajax() ) { |
| 166 |
$this->loader->add_filter( 'woocommerce_gateway_title', ( new PaymentMethodTitle() ), 'filter_gateway_title_by_order_payment_method_title', 10, 2 ); |
| 167 |
} |
| 168 |
} |
| 169 |
|
| 170 |
/** |
| 171 |
* Register payment methods action hooks. |
| 172 |
* |
| 173 |
* @param PaymentMethodsController $payment_methods |
| 174 |
* @return void |
| 175 |
*/ |
| 176 |
private function payment_methods_actions_hooks( PaymentMethodsController $payment_methods ): void { |
| 177 |
// Enqueue styles in payment methods |
| 178 |
$this->loader->add_action( 'wp_enqueue_scripts', $payment_methods, 'enqueue_styles' ); |
| 179 |
// Set MultiSafepay transaction as shipped |
| 180 |
$this->loader->add_action( 'woocommerce_order_status_' . str_replace( 'wc-', '', get_option( 'multisafepay_trigger_transaction_to_shipped', 'wc-completed' ) ), $payment_methods, 'set_multisafepay_transaction_as_shipped', 10, 1 ); |
| 181 |
// Set MultiSafepay transaction as invoiced |
| 182 |
$this->loader->add_action( 'woocommerce_order_status_' . str_replace( 'wc-', '', get_option( 'multisafepay_trigger_transaction_to_invoiced', 'wc-completed' ) ), $payment_methods, 'set_multisafepay_transaction_as_invoiced', 11, 1 ); |
| 183 |
// Generate orders from backend. |
| 184 |
if ( is_admin() ) { |
| 185 |
$this->loader->add_action( 'woocommerce_new_order', $payment_methods, 'generate_orders_from_backend', 10, 1 ); |
| 186 |
} |
| 187 |
// One notification URL for all payment methods |
| 188 |
$this->loader->add_action( 'woocommerce_api_multisafepay', $payment_methods, 'callback' ); |
| 189 |
// One endpoint to handle notifications via POST. |
| 190 |
$this->loader->add_action( 'rest_api_init', $payment_methods, 'multisafepay_register_rest_route' ); |
| 191 |
// Ajax related to Apple Pay Direct validation |
| 192 |
$this->loader->add_action( 'wp_ajax_applepay_direct_validation', $payment_methods, 'applepay_direct_validation' ); |
| 193 |
$this->loader->add_action( 'wp_ajax_nopriv_applepay_direct_validation', $payment_methods, 'applepay_direct_validation' ); |
| 194 |
// Getting total price update for payment methods |
| 195 |
$this->loader->add_action( 'wp_ajax_get_updated_total_price', $payment_methods, 'get_updated_total_price' ); |
| 196 |
$this->loader->add_action( 'wp_ajax_nopriv_get_updated_total_price', $payment_methods, 'get_updated_total_price' ); |
| 197 |
// Add the MultiSafepay transaction link in the order details page |
| 198 |
$this->loader->add_action( 'woocommerce_admin_order_data_after_payment_info', $payment_methods, 'add_multisafepay_transaction_link' ); |
| 199 |
} |
| 200 |
|
| 201 |
/** |
| 202 |
* Register the hooks related to the MultiSafepay payment component |
| 203 |
* |
| 204 |
* @return void |
| 205 |
*/ |
| 206 |
public function payment_components_hooks(): void { |
| 207 |
$payment_component_service = new PaymentComponentService(); |
| 208 |
// Allow to refresh the data sent to initialize the Payment Components, when in the checkout, something changed in the order details |
| 209 |
$this->loader->add_action( 'wp_ajax_refresh_payment_component_config', $payment_component_service, 'refresh_payment_component_config' ); |
| 210 |
$this->loader->add_action( 'wp_ajax_nopriv_refresh_payment_component_config', $payment_component_service, 'refresh_payment_component_config' ); |
| 211 |
} |
| 212 |
|
| 213 |
/** |
| 214 |
* Register the hooks related to the MultiSafepay payment component with QR |
| 215 |
* |
| 216 |
* @return void |
| 217 |
*/ |
| 218 |
public function payment_components_qr_hooks() { |
| 219 |
$qr_payment_component_service = new QrPaymentComponentService(); |
| 220 |
// Set the MultiSafepay QR code transaction |
| 221 |
$this->loader->add_action( 'wp_ajax_set_multisafepay_qr_code_transaction', $qr_payment_component_service, 'set_multisafepay_qr_code_transaction' ); |
| 222 |
$this->loader->add_action( 'wp_ajax_nopriv_set_multisafepay_qr_code_transaction', $qr_payment_component_service, 'set_multisafepay_qr_code_transaction' ); |
| 223 |
// Get the redirect URL for the order submitted via Payment Components QR |
| 224 |
$this->loader->add_action( 'wp_ajax_get_qr_order_redirect_url', $qr_payment_component_service, 'get_qr_order_redirect_url' ); |
| 225 |
$this->loader->add_action( 'wp_ajax_nopriv_get_qr_order_redirect_url', $qr_payment_component_service, 'get_qr_order_redirect_url' ); |
| 226 |
} |
| 227 |
|
| 228 |
/** |
| 229 |
* Register the hooks related to the processing of the MultiSafepay payment component with QR webhooks |
| 230 |
* |
| 231 |
* @return void |
| 232 |
*/ |
| 233 |
public function callback_hooks() { |
| 234 |
$qr_payment_webhook = new QrPaymentWebhook(); |
| 235 |
// Handle the balancer after submit a QR order, to know where to redirect the user |
| 236 |
$this->loader->add_action( 'rest_api_init', $qr_payment_webhook, 'multisafepay_register_rest_route_qr_balancer' ); |
| 237 |
// Handle the webhook request from MultiSafepay for the payment status update for QR orders |
| 238 |
$this->loader->add_action( 'rest_api_init', $qr_payment_webhook, 'multisafepay_register_rest_route_qr_notification' ); |
| 239 |
} |
| 240 |
|
| 241 |
/** |
| 242 |
* Register the MultiSafepay payment methods in WooCommerce Blocks. |
| 243 |
* |
| 244 |
* @return void |
| 245 |
*/ |
| 246 |
public function block_hooks(): void { |
| 247 |
$blocks = new BlocksController(); |
| 248 |
// Use the dedicated WooCommerce Blocks lifecycle hook; it is the safe init point after Blocks dependencies are loaded. |
| 249 |
$this->loader->add_action( 'woocommerce_blocks_loaded', $blocks, 'register_multisafepay_payment_methods_blocks' ); |
| 250 |
// Map MultiSafepay Payment Component data from WooCommerce Blocks into WC_Order metadata. |
| 251 |
$this->loader->add_action( 'woocommerce_rest_checkout_process_payment_with_context', $blocks, 'map_blocks_payment_data_to_order_meta', 10, 2 ); |
| 252 |
} |
| 253 |
|
| 254 |
/** |
| 255 |
* Register the hooks related to field validation |
| 256 |
* |
| 257 |
* @return void |
| 258 |
*/ |
| 259 |
public function validation_hooks(): void { |
| 260 |
$validation_service = new ValidationService(); |
| 261 |
// Register AJAX action for zip code validation |
| 262 |
$this->loader->add_action( 'wp_ajax_multisafepay_validate_postcode', $validation_service, 'validate_postcode' ); |
| 263 |
$this->loader->add_action( 'wp_ajax_nopriv_multisafepay_validate_postcode', $validation_service, 'validate_postcode' ); |
| 264 |
} |
| 265 |
|
| 266 |
/** |
| 267 |
* Run the loader to execute the hooks with WordPress. |
| 268 |
* |
| 269 |
* @return void |
| 270 |
*/ |
| 271 |
public function init() { |
| 272 |
$this->loader->init(); |
| 273 |
} |
| 274 |
} |
| 275 |
|