* * @see http://wcpos.com * @package WCPOS\WooCommercePOS */ namespace WCPOS\WooCommercePOS\Templates; use Exception; use WCPOS\WooCommercePOS\Services\Settings; /** * Payment class. */ class Payment { /** * The order ID. * * @var int */ private $order_id; /** * The order. * * @var \WC_Order */ private $order; /** * The coupon nonce. * * @var string */ private $coupon_nonce; /** * The troubleshooting form nonce. * * @var string */ private $troubleshooting_form_nonce; /** * Disable wp_head setting. * * @var bool */ private $disable_wp_head; /** * Disable wp_footer setting. * * @var bool */ private $disable_wp_footer; /** * Constructor. * * @param int $order_id The order ID. */ public function __construct( int $order_id ) { $this->order_id = $order_id; $this->check_troubleshooting_form_submission(); $settings_service = Settings::instance(); $this->disable_wp_head = (bool) $settings_service->get_settings( 'checkout', 'disable_wp_head' ); $this->disable_wp_footer = (bool) $settings_service->get_settings( 'checkout', 'disable_wp_footer' ); // this is a checkout page. add_filter( 'woocommerce_is_checkout', '__return_true' ); // remove the terms and conditions checkbox. add_filter( 'woocommerce_checkout_show_terms', '__return_false' ); // remove junk from head. add_filter( 'show_admin_bar', '__return_false' ); remove_action( 'wp_head', 'rsd_link' ); remove_action( 'wp_head', 'wp_generator' ); remove_action( 'wp_head', 'feed_links', 2 ); remove_action( 'wp_head', 'index_rel_link' ); remove_action( 'wp_head', 'wlwmanifest_link' ); remove_action( 'wp_head', 'feed_links_extra', 3 ); remove_action( 'wp_head', 'start_post_rel_link', 10, 0 ); remove_action( 'wp_head', 'parent_post_rel_link', 10, 0 ); remove_action( 'wp_head', 'adjacent_posts_rel_link', 10, 0 ); remove_action( 'wp_head', 'wp_shortlink_wp_head', 10, 0 ); remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 ); add_action( 'wp_enqueue_scripts', array( $this, 'remove_scripts_and_styles' ), 100 ); } /** * Each theme will apply its own styles to the checkout page. * I want to keep it simple, so we remove all styles and scripts associated with the active theme. * NOTE: This is not perfect, we don't know the theme handle, so we just take a guess from the source URL. * * @return void */ /** * Remove enqueued scripts and styles. * * This function dequeues all scripts and styles that are not specified in the WCPOS settings, * unless they are specifically included by the 'woocommerce_pos_payment_template_dequeue_script_handles' * and 'woocommerce_pos_payment_template_dequeue_style_handles' filters. * * @since 1.3.0 */ public function remove_scripts_and_styles(): void { global $wp_styles, $wp_scripts; /** * List of script handles to exclude from the payment template. * * @since 1.3.0 */ $script_exclude_list = apply_filters( 'woocommerce_pos_payment_template_dequeue_script_handles', Settings::instance()->dequeue_script_handles() ); /** * List of style handles to exclude from the payment template. * * @since 1.3.0 */ $style_exclude_list = apply_filters( 'woocommerce_pos_payment_template_dequeue_style_handles', Settings::instance()->dequeue_style_handles() ); // Loop through all enqueued styles and dequeue those that are in the exclusion list. if ( \is_array( $style_exclude_list ) ) { foreach ( $wp_styles->queue as $handle ) { if ( \in_array( $handle, $style_exclude_list, true ) ) { wp_dequeue_style( $handle ); } } } // Loop through all enqueued scripts and dequeue those that are in the exclusion list. if ( \is_array( $script_exclude_list ) ) { foreach ( $wp_scripts->queue as $handle ) { if ( \in_array( $handle, $script_exclude_list, true ) ) { wp_dequeue_script( $handle ); } } } } /** * Render the payment template. * * @return void */ public function get_template(): void { if ( ! \defined( 'WOOCOMMERCE_CHECKOUT' ) ) { \define( 'WOOCOMMERCE_CHECKOUT', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- WooCommerce constant. } do_action( 'woocommerce_pos_before_pay' ); try { // initialize order and nonces before the user is switched to customer. $this->initialize_order_and_nonces(); // Verify order key to prevent unauthenticated access. // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Order key is the auth mechanism here, matching WooCommerce core behavior. $provided_key = isset( $_GET['key'] ) ? sanitize_text_field( wp_unslash( $_GET['key'] ) ) : ''; if ( ! $provided_key || $provided_key !== $this->order->get_order_key() ) { wp_die( esc_html__( 'Sorry, this order cannot be paid for. The order key is missing or invalid.', 'woocommerce-pos' ), /* translators: Short WCPOS UI label; keep concise. */ esc_html__( 'Error', 'woocommerce-pos' ), array( 'response' => 403 ) ); } /* * The wp_set_current_user() function changes the global user object but it does not authenticate the user * for the current session. This means that it will not affect nonce creation or validation because WordPress * nonces are tied to the user's session. * * @TODO - is this the best way to do this? */ wp_set_current_user( $this->order->get_customer_id() ); add_filter( 'nonce_user_logged_out', array( $this, 'nonce_user_logged_out' ), 10, 2 ); // Logged in customer trying to pay for someone else's order. if ( ! current_user_can( 'pay_for_order', $this->order_id ) ) { wp_die( esc_html__( 'This order cannot be paid for. Please contact us if you need assistance.', 'woocommerce-pos' ) ); } // We need to reload the gateways here to use the current customer details. WC()->payment_gateways()->init(); $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); $order_button_text = apply_filters( 'woocommerce_pay_order_button_text', /* translators: Short WCPOS UI label; keep concise. */ __( 'Pay for order', 'woocommerce-pos' ) ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WooCommerce core hook. include woocommerce_pos_locate_template( 'payment.php' ); } catch ( Exception $e ) { wc_print_notice( $e->getMessage(), 'error' ); } } /** * Render the troubleshooting form HTML. * * @return string */ public function get_troubleshooting_form_html(): string { global $wp_styles, $wp_scripts; $style_handles = $wp_styles->queue; $script_handles = $wp_scripts->queue; $style_exclude_list = apply_filters( 'woocommerce_pos_payment_template_dequeue_style_handles', Settings::instance()->dequeue_style_handles() ); $script_exclude_list = apply_filters( 'woocommerce_pos_payment_template_dequeue_script_handles', Settings::instance()->dequeue_script_handles() ); $merged_style_handles = array_unique( array_merge( $style_handles, $style_exclude_list ) ); $merged_script_handles = array_unique( array_merge( $script_handles, $script_exclude_list ) ); ob_start(); ?>