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.

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?

share|improve this question
add comment

3 Answers

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.

share|improve this answer
add comment

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.

share|improve this answer
    
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 Sep 17 '13 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. –  cybnet Sep 17 '13 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 Sep 22 '13 at 8:58
    
Please, see my edited answer. –  cybnet Sep 22 '13 at 9:39
add comment

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.

share|improve this answer
    
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 Sep 17 '13 at 11:17
add comment

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.