Reputation: 2327
I've created a custom shipping method following Woocommerce Shipping Method API. In the init
method of my shipping method class, I'm trying to get all shipping classes using WC()->shipping->get_shipping_classes()
.
This call fails as a PHP fatal error:
Fatal error: Uncaught Error: Call to a member function get_shipping_classes() on null...
This suggests that WC()->shipping
is null
which is basically an instance of WC_Shipping
class.
I'm doing similar to Flat rate shipping method of Woocommerce core. The similar code works in the Woocommerce as seen here.
Here's my shipping method class:
class WCS_City_Shipping_Method extends WC_Shipping_Flat_Rate {
/**
* Cities applicable on
*
* @var array
*/
public $cities = array();
/**
* Constructor.
*
* @since 1.0.0
*/
public function __construct( $instance_id = 0 ) {
$this->id = 'city_shipping';
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Flat Rate City Shipping', 'woocommerce-city-shipping' );
$this->method_description = __( 'Applies only when shipping city matches one of provided.', 'woocommerce-city-shipping' );
$this->supports = array( 'shipping-zones', 'instance-settings', );
$this->init();
// Save settings
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* Init.
*
* Initialize user set variables.
*
* @since 1.0.0
*/
public function init() {
$this->instance_form_fields = include( 'settings-city-shipping.php' );
$this->title = $this->get_option( 'title' );
$this->tax_status = $this->get_option( 'tax_status' );
$this->cities = $this->get_option( 'cities' );
$this->cost = $this->get_option( 'cost' );
$this->type = $this->get_option( 'type', 'class' );
}
/**
* ... Rest of code
*
*/
}
And here's settings-city-shipping.php
which was included in init
method.
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$shipping_classes = WC()->shipping->get_shipping_classes(); // Fatal error here
The shipping method is added using the filter as:
// Add shipping method
add_filter( 'woocommerce_shipping_methods', array( $this, 'add_shipping_method_class' ) );
public function add_shipping_method_class( $methods ) {
if ( class_exists( 'WCS_City_Shipping_Method' ) ) {
$methods['city_shipping'] = 'WCS_City_Shipping_Method';
}
return $methods;
}
Please help to find what is causing fatal error and how to get all shipping classes.
Upvotes: 1
Views: 1740
Reputation: 2327
It was a silly mistake. I had initialized the WCS_City_Shipping_Method
class in the initialization code of the plugin class for this custom shipping method. The code was running before Woocommerce
was ready and so causing fatal error.
I had missed this important line from Woocommerce Shipping API documentation:
To ensure the classes you need to extend exist, you should wrap your class in a function which is called after all plugins are loaded.
Anyways, I solved issue by not initializing the class and wrapping it into a method which runs on plugins_loaded
action hook. Here are the changes:
public function plugins_loaded_action() {
// Load shipping method class
add_action( 'woocommerce_shipping_init', array( $this, 'wcs_shipping_method' ) );
}
// Placed in plugin class init method
add_action( 'plugins_loaded', array( $this, 'plugins_loaded_action' ) );
public function wcs_shipping_method() {
require_once plugin_dir_path( __FILE__ ) . 'includes/class-wcs-method.php';
}
Upvotes: 0