phpwordpresswoocommerceextending-classeswordpress-plugin-creation

Extending WooCommerce COD payment gateway in a plugin


I would like to understand the sequence various classes are loaded in Wordpress. There are many plugins available in Wordpress, then who will be loaded earlier than another.

Consider I would like to develop a plugin that will use some existing class of Woocommerce. Basically my custom plugin will extend some class of Woocommerce (for example : WC_Gateway_COD)

How I can ensure the existing class ‘WC_Gateway_COD’ is already defined & loaded before it execute the below statement ?

if (class_exists('WC_Gateway_COD')) {
     class WC_my_custom_class extends WC_Gateway_COD {
             …..
             ….
     }
}  

Solution

  • To make a custom gateway based on an existing WooCommerce payment method as COD, It's recommended to copy the source code from WC_Gateway_COD Class in a plugin (adapting the code for your needs) like:

    defined( 'ABSPATH' ) or exit;
    // Make sure WooCommerce is active
    if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
        return;
    }
    
    add_filter( 'woocommerce_payment_gateways', 'wc_custom_add_to_gateways' );
    function wc_custom_add_to_gateways( $gateways ) {
        $gateways[] = 'WC_Gateway_COD2';
        return $gateways;
    }
    
    add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'wc_gateway_custom_plugin_links' );
    function wc_gateway_custom_plugin_links( $links ) {
        $plugin_links = array(
            '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout&section=cod2' ) . '">' . __( 'Configure', 'payment_cod2' ) . '</a>'
        );
        return array_merge( $plugin_links, $links );
    }
    
    add_action( 'plugins_loaded', 'wc_gateway_cod2_init', 11 );
    function wc_gateway_cod2_init() {
        class WC_Gateway_COD2 extends WC_Payment_Gateway {
    
            public $domain; // The text domain (optional)
    
            /**
             * Constructor for the gateway.
             */
            public function __construct() {
                $this->domain = 'payment_cod2'; // text domain name (for translations)
    
                // Setup general properties.
                $this->setup_properties();
        
                // Load the settings.
                $this->init_form_fields();
                $this->init_settings();
        
                // Get settings.
                $this->title              = $this->get_option( 'title' );
                $this->description        = $this->get_option( 'description' );
                $this->instructions       = $this->get_option( 'instructions' );
                $this->enable_for_methods = $this->get_option( 'enable_for_methods', array() );
                $this->enable_for_virtual = $this->get_option( 'enable_for_virtual', 'yes' ) === 'yes';
        
                add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
                add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'thankyou_page' ) );
                add_filter( 'woocommerce_payment_complete_order_status', array( $this, 'change_payment_complete_order_status' ), 10, 3 );
        
                // Customer Emails.
                add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 );
            }
        
            /**
             * Setup general properties for the gateway.
             */
            protected function setup_properties() {
                $this->id                 = 'cod2';
                $this->icon               = apply_filters( 'woocommerce_cod2_icon', '' );
                $this->method_title       = __( 'Cash on delivery', 'woocommerce' );
                $this->method_description = __( 'Have your customers pay with cash (or by other means) upon delivery.', 'woocommerce' );
                $this->has_fields         = false;
            }
    
            // and so on (the rest of the code)…
        }
    }
    

    You can unset / remove original COD payment gateway changing the 1st function like:

    add_filter( 'woocommerce_payment_gateways', 'wc_custom_add_to_gateways' );
    function wc_custom_add_to_gateways( $gateways ) {
        $gateways[] = 'WC_Gateway_COD2';
    
        unset($gateways['WC_Gateway_COD']; // Remove COD gateway
    
        return $gateways;
    }