Registering and using actions which return results in a Plugin class

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

Read More

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?

Related posts

3 comments

  1. 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.

  2. 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.

  3. 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.

Comments are closed.