Reputation:
I am trying to override a WooCommerce function load_country_states(). I am creating a custom WordPress plugin to do it. I read in some answers that one can't simply override a function in PHP. Whats the best way to rewrite a function defined in WordPress theme/plugin in a plugin? I have read this.
The function to modify:
/**
* Load the states.
*/
public function load_country_states() {
global $states;
// States set to array() are blank i.e. the country has no use for the state field.
$states = array(
'AF' => array(),
'AT' => array(),
'AX' => array(),
'BE' => array(),
'BI' => array(),
'CZ' => array(),
'DE' => array(),
'DK' => array(),
'EE' => array(),
'FI' => array(),
'FR' => array(),
'IS' => array(),
'IL' => array(),
'KR' => array(),
'NL' => array(),
'NO' => array(),
'PL' => array(),
'PT' => array(),
'SG' => array(),
'SK' => array(),
'SI' => array(),
'LK' => array(),
'SE' => array(),
'VN' => array(),
);
// Load only the state files the shop owner wants/needs.
$allowed = array_merge( $this->get_allowed_countries(), $this->get_shipping_countries() );
if ( ! empty( $allowed ) ) {
foreach ( $allowed as $code => $country ) {
if ( ! isset( $states[ $code ] ) && file_exists( WC()->plugin_path() . '/i18n/states/' . $code . '.php' ) ) {
include( WC()->plugin_path() . '/i18n/states/' . $code . '.php' );
}
}
}
$this->states = apply_filters( 'woocommerce_states', $states );
}
After modification it should work like:
/**
* Load the states.
*/
public function load_country_states() {
global $states;
// Load only the state files the shop owner wants/needs.
$allowed = array_merge( $this->get_allowed_countries(), $this->get_shipping_countries() );
if ( ! empty( $allowed ) ) {
foreach ( $allowed as $code => $country ) {
if ( ! isset( $states[ $code ] ) && file_exists( WC()->plugin_path() . '/i18n/states/' . $code . '.php' ) ) {
include( WC()->plugin_path() . '/i18n/states/' . $code . '.php' );
}
}
}
$this->states = apply_filters( 'woocommerce_states', $states );
}
Upvotes: 2
Views: 1701
Reputation:
I tried to read up more about this and came up with this solution that worked. We can use WordPress filter to add hack into specific events. I modified the code and it now works.
/**
* Load the states.
*/
function load_country_states_modified() {
global $states;
// Load only the state files the shop owner wants/needs.
$foobar = new WC_Countries; // correct
$allowed = array_merge( $foobar->get_allowed_countries(), $foobar->get_shipping_countries() );
if ( ! empty( $allowed ) ) {
foreach ( $allowed as $code => $country ) {
if ( ! isset( $states[ $code ] ) && file_exists( WC()->plugin_path() . '/i18n/states/' . $code . '.php' ) ) {
include( WC()->plugin_path() . '/i18n/states/' . $code . '.php' );
}
}
}
//$this->states = apply_filters( 'woocommerce_states', $states );
}
add_filter( 'woocommerce_states', 'load_country_states_modified' );
Upvotes: 0
Reputation: 1418
Actually you can't simply override a function. It's only possible if it's surrounded by a if ( ! function_exists() )
conditional. In your case it seems to be a class method and to override it (in plain PHP) you should extend the class and override the method. In your WordPress scenario it's simpler, because you can use a simple filter. Your code should be like:
public function so48005823_load_country_states( $states ) {
// make your magic here and
// don't forget to return the $states var
return $states;
}
add_filter( 'woocommerce_states', 'so48005823_load_country_states' );
Make sure to not simple copy/paste the code, because the $this
variable is only available inside the class scope. You can put this function into a simple plugin and it'll start working.
Hope it helps!
Upvotes: 1