I am building many custom shortcodes and to off load a lot of reusable code I created an abstract base class for all my shortcodes classes to extend.
However when I try to use a reference to $this when inside add_shortcode() function I receive this error:
Fatal error: Using $this when not in object context in...
However outside of the add_shortcode() function (in other class methods) my child class is able to use $this predictably referencing itself and its parent class.
Here is a simplified version of my child shortcode class and parent abstract class
Parent Class
abstract class ABS_Shortcode {
protected $order;
public function __construct() {
$this->order = '';
}
public function set_order_prop($value) {
$this->order = $value;
}
public function get_order_prop() {
return $this->order;
}
protected function setup_default_options() {
//Setups up defaults not important for example. But does get called correctly from child class
}
}
Child Class
class WC_Product_Categories extends ABS_Shortcode {
protected $shortcode_base = 'wc_product_categories';
public function __construct() {
parent::__construct();
// Call to method in parent class works fine
$this->setup_default_options();
// Child method works fine
$this->map_shortcode();
// Have to use __CLASS__ instead of $this here to not throw an error. Not sure why
add_shortcode( $this->shortcode_base, array( __CLASS__, "build_shortcode") );
}
protected function map_shortcode() {
// Code to handle building shortcode attributes, not necessary for example
}
public function build_shortcode($atts, $content = null) {
extract( shortcode_atts (
// Setup defaults
array(
'category' => '',
'posts_per_page' => '',
'orderby' => '',
'order' => '',
'items_per_row' => '',
'hide_empty' => '',
), $atts) );
//Call to parent class property or method throws error when using $this
//Fatal error: Using $this when not in object context in...
$this->order = 'ASC';
$this->set_order_prop('ASC');
//Call using parent:: works to call parent method.
//But inside parent class when using $this throws original error
//Fatal error: Using $this when not in object context in...
parent::set_order_prop('ASC');
// Try calling parent class property
// Fatal error: Access to undeclared static property: ABS_VC_Shortcode::$order
parent::$order;
}
}
// Create class
$wc_categories = new WC_Product_Categories();
All these errors disappear when not called from inside the shortcode function (build_shortcode), $this behaves correctly either referencing the child or parent class properties and methods.
I am wondering why the reference to $this throws errors when using the add_shortcode() function. And how can I get around this?
thanks
extract
, it encourages bad code and prevents automated tools and IDEs from reading codeadd_{action, shortcode}
functions in the constructor, to make it easier to test (see for example gmazzap's great answer here). I think the Codex example on how to use shortcodes in a class is probably confusing for many, because it's not correct, it's missing thestatic
keyword.static
keyword. Yes, seperate it with aninit()
method, for example. @George