1

I have a plugin class which contains a function spektrix_list_events()

class SpektrixPlugin {

    public function __construct(){

        add_action( 'init', array ( $this, 'init' ));
    }

    public function init()
    {
        add_action( 'spektrix_list_events', array ( $this, 'spektrix_list_events' ));
    }

    public function spektrix_list_events($getPrices = FALSE) {
        $api = new SpektrixApiClient();
        return $api->getAllEvents($getPrices);

    }
}

$SpektrixEvents = new SpektrixPlugin;
add_action('init', array($SpektrixEvents, 'init'));

In a template file, I want to be able to call do_action('spektrix_list_events') but can't seem to get this working. I've tried following the advice here

Additional question - is using add_action() the recommended way to do this?

UPDATE:

The method is in fact being called but no results are returned. So how should one call a plugin class method which returns some output for display?

3 Answers 3

2

Some actions hooks need to be fired on specific events. Try this code:

class SpektrixPlugin {

    public function __construct(){
        add_action('init', array(&$this, 'init'));
    }

    public function spektrix_list_events($getPrices = FALSE) {
        $api = new SpektrixApiClient();
        return $api->getAllEvents($getPrices);
    }

    public function init(){
        add_action( 'spektrix_list_events', array ( $this, 'spektrix_list_events' ));
    }

 }

 $SpektrixEvents = new SpektrixPlugin();

I've tested this code and it works:

class SpektrixPlugin {

    public function __construct(){
        add_action('init', array(&$this, 'init'));
    }

    public function spektrix_list_events() {
        echo 'test';
    }

    public function init(){
        add_action( 'spektrix_list_events', array ( $this, 'spektrix_list_events' ));
    }

 }

 $SpektrixEvents = new SpektrixPlugin();

 //this print 'test', so it works.
 do_action('spektrix_list_events');

But .... I've been reading the Wordpress documentation about do_action() and it says clearly that do_action() will call the function/method but it won't return anything. Quoteing Wordpress about do_action():

This function works similar to apply_filters() with the exception that nothing is returned and only the functions or methods are called.

So, you should check the apply_filters() function which works in a similar way that do_action() but can return the value returned by the called method or look for another implementation. do_action() is not suitable to return values.

An example usgin apply_filters:

class SpektrixPlugin {

    public function __construct(){
        add_action('init', array(&$this, 'init'));
    }

    public function spektrix_list_events() {
        $myvar = "Hey, I'm works";
        return $myvar;
    }

    public function init(){
        add_filter( 'spektrix_list_events', array ( $this, 'spektrix_list_events' ));
    }

 }

 $SpektrixEvents = new SpektrixPlugin;

 $test = apply_filters('spektrix_list_events','');
 var_dump($test);

Anyway, I think that this approach used to get data is no the appropiate. Although apply_filters() will work to get a value, as in the above example, the function is specially designed to filter a value, not to get one. I think the best you can do is have a get method in your class used to get the value you want, then you can apply filters to that value or do actions with it.

4
  • Thanks. However, when I do do_action('spektrix_list_events') in a template, nothing is returned. The docs seem to bear this out. codex.wordpress.org/Function_Reference/do_action. So whats the best way to call a plugin function if you need to return something? I was previously just using the object directly in the template e.g. $SpektrixPlugin->doMyMethod()
    – codecowboy
    Commented Sep 17, 2013 at 11:12
  • See my edited answer. It works. So it has to be the call to $api->getAllEvents($getPrices); what returns nothing or maybe you need to echo the returning data.
    – cybmeta
    Commented Sep 17, 2013 at 11:29
  • It does work but only for echoing a value, not returning an array of values. I don't want to echo anything out in my plugin. The data I'm returning is also not wordpress post data but data from a third-party API.
    – codecowboy
    Commented Sep 22, 2013 at 8:58
  • Please, see my edited answer.
    – cybmeta
    Commented Sep 22, 2013 at 9:39
1

When working with classes and action, is a good practise, give an easy way to remove the action.

Using something like add_action( 'init', array ( $this, 'init' )); removing this action, can be done, but is far from easy.

Another thing to consider, is that if you plain to use a plugin from theme, is a good idea insert some custom filters and actions hooks to customize the behavior of your plugin form themes.

So, in your case you can do something like this

add_action('init', 'initSpektrixPlugin');

function initSpektrixPlugin() {
  // if the class isn't in the main plugin file, you can require class file here, e.g.:
  // require_once( plugin_dir_path(__FILE__) . 'inc/SpektrixPlugin.class.php' );
  SpektrixPlugin::init();
}

After that, the class can be something like this:

class SpektrixPlugin {

    protected static $events = array();

    public static function init()
    {
        add_action( 'spektrix_list_events', array ( __CLASS__, 'printEvents' ) );
    }

    protected static function getEvents( $getPrices = false )
    {
        $cached = self::getCachedEvents( $getPrices );
        if ( $cached ) 
           // last 'true' param means we are returning cached result
           return apply_filters('spektrix_events', $cached, $getPrices, true);
        // requiring the api client class from here, you include it
        // only if you don't already have cached results
        require_once( plugin_dir_path(__FILE__) . 'SpektrixApiClient.php' );
        $api = new SpektrixApiClient();
        $events = self::setCachedEvents( $api->getAllEvents($getPrices), $getPrices);
        // a custom action to customize behavior from theme
        do_action('spektrix_events_getted', $events, $getPrices);
        // return events after a custom filter, to customize behavior from theme
        // last 'false' param means we are returning not cached result
        return apply_filters('spektrix_events', $events, $getPrices, false);
    }

    protected static function getCachedEvents( $getPrices = false )
    {
      $key = $getPrices ? 1 : 0;
      if ( isset( self::$events[$key] ) ) return self::$events[$key];
      return false;
    }

    protected static function setCachedEvents( $events, $getPrices = false )
    {
      $key = $getPrices ? 1 : 0;
      self::$events[$key] = $events;
      return $events; 
    }

    public static function printEvents( $getPrices = false )
    {
        $events = self::getEvents( $getPrices );

        // debug
        echo '<pre>';
        print_r($events);
        echo '</pre><br />';
        // end debug

        // print here your events..
        // I don't know if it's a string, an object, an array...
    }

}

And in your template file use just

<?php do_action('spektrix_list_events'); ?>

or

<?php do_action('spektrix_list_events', true); // getPrices = true ?>

Code is rough and untested, but should give you a direction to start.

-1

If you want any function to work juhst hook it to your appropriate needs.I think in your case you want to execute function spektrix_list_events(). It is in class so use array in hooking add_action('appropriate hook',array('SpektrixPlugin','spektrix_list_events')); Hope this will help.

1
  • I was already doing this and the linked question already had this information FYI. The problem seems to be that running do_action('spektrix_list_events') does not return any results.
    – codecowboy
    Commented Sep 17, 2013 at 11:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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