Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Currently i am using the following generic flow for adding the shortcode for a plugin.

class MyPlugin {

    private $myvar;

    function baztag_func() {
        print $this->myvar;            
    }
}

add_shortcode( 'baztag', array('MyPlugin', 'baztag_func') );

Now when this class and it's method are called i get the following error.

Fatal error: Using $this when not in object context in ...

(Line no is where i have printed the $this->myvar)

Is this a problem on Wordpress's end or is there is something i'm doing wrong? It seems to be something really simple.

share|improve this question
    
off topic - make the function static. –  kaiser Sep 27 '12 at 15:21

3 Answers 3

up vote 13 down vote accepted

As the error says you need an instance of the class to use $this. There are at least three possibilities:

Make everything static

class My_Plugin
{
    private static $var = 'foo';

    static function foo()
    {
        return self::$var; // never echo or print in a shortcode!
    }
}
add_shortcode( 'baztag', array( 'My_Plugin', 'foo' ) );

But that’s not real OOP anymore, just namespacing.

Create a real object first

class My_Plugin
{
    private $var = 'foo';

    public function foo()
    {
        return $this->var; // never echo or print in a shortcode!
    }
}

$My_Plugin = new My_Plugin;

add_shortcode( 'baztag', array( $My_Plugin, 'foo' ) );

This … works. But you run into some obscure problems if anyone wants to replace the shortcode.

So add a method to provide the class instance:

final class My_Plugin
{
    private $var = 'foo';

    public function __construct()
    {
        add_filter( 'get_my_plugin_instance', [ $this, 'get_instance' ] );
    }

    public function get_instance()
    {
        return $this; // return the object
    }

    public function foo()
    {
        return $this->var; // never echo or print in a shortcode!
    }
}

add_shortcode( 'baztag', [ new My_Plugin, 'foo' ] );

Now, when someone wants to get the object instance, s/he just has to write:

$shortcode_handler = apply_filters( 'get_my_plugin_instance', NULL );

if ( is_a( $shortcode_handler, 'My_Plugin ' ) )
{
    // do something with that instance.
}

Old solution: create the object in your class

class My_Plugin
{
    private $var = 'foo';

    protected static $instance = NULL;

    public static function get_instance()
    {
        // create an object
        NULL === self::$instance and self::$instance = new self;

        return self::$instance; // return the object
    }

    public function foo()
    {
        return $this->var; // never echo or print in a shortcode!
    }
}

add_shortcode( 'baztag', array( My_Plugin::get_instance(), 'foo' ) );
share|improve this answer
    
thanx man ... thats priceless info since wordpress.org did not tell this much on their add_shortcode documentation page. I had figured out the solution but since you have ruled that out as a bad practice and you have a better solution so i mark this problem as solved:) –  hussain Aug 10 '12 at 7:49
    
I am really sorry to dig up this old question, but could you plase elaborate what this line does: NULL === self::$instance and self::$instance = new self;? I am a bit confused because === and and are used, but without if, if you know what I mean. –  Sven Jan 3 at 12:17
    
@Sven This is a check to prevent a second instance. It makes this class a Singleton … I wouldn’t do that nowadays. I will rewrite this answer. –  toscho Jan 3 at 12:18
    
Thanks for that! I think now I am on the right track, although it is astonishing how complicated it can be using WordPress & OOP ;-) –  Sven Jan 3 at 12:38
    
@Sven WordPress core is written pretty much as anti-OOP as possible. Even new code ignores all the things the rest of the PHP world has learned during the last ten years, dependency injection for example. So yes, OOP in WordPress plugins and themes is always hackish. :/ –  toscho Jan 3 at 12:42

Make sure that you make an instance of your class before using it unless you are sure it's supposed to be called statically. When you call a method statically, you don't use any instances and therefore it doesn't have access to any member variables or methods.

share|improve this answer

You can use like this, shortcode inside the Class

class stockData{


    function __construct() {
        add_shortcode( 'your_shortcode_name', array( $this, 'showData' ) );
        //add_action('login_enqueue_scripts', array( $this,'my_admin_head'));
    }

    function showData(){
        return '<h1>My shortcode content</h1>' ;
    }
}

$object=new stockData();

If you want access shortcode content from another class. You can do like this.

class my_PluginClass {

  public function __construct( $Object ) {

    $test = add_shortcode( 'your_shortcode_name', array( $Object, 'your_method_name' ) );

  }

}

class CustomHandlerClass{

  public function your_method_name( $atts, $content ) {
     return '<h1>My shortcode content</h1>' ;
  }
}

$Customobject  = new CustomHandlerClass();
$Plugin         = new my_PluginClass( $Customobject );
share|improve this answer
    
+1 Seems like a good/clean/understandable solution –  bestprogrammerintheworld Aug 13 at 19:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.