2

I'm new to add-on development and have built a simple plugin to return an integer of the number of entries a user has posted in a certain channel.

I want to call this plugin a few times in an EE template. With the way it is set up now, does that mean the plugin will query the DB every time I call it?

If so, is there a better way to write this?

Thanks,

        <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');


            $plugin_info = array(
                'pi_name'       => 'Camper Count',
                'pi_version'    => '1.0',
                'pi_author'     => '',
                'pi_author_url' => '',
                'pi_description'=> 'Count the number of campers a logged in user has and return an integer.',
                'pi_usage'      => Camper_count::usage()
            );




            class Camper_count {

                /**
                 * Specific Vars for Channel and Status
                 * Since this will only be used to export from one channel
                 *
                 * @var array
                 * @access protected
                 **/
                protected $channel_id = 20; // The ID for the 'Campers' Channel
                protected $channel_entry_status = 'open';


                /**
                 * Return Data
                 **/
                public $return_data;

                /**
                 * Constructor
                 */
                public function __construct()
                {
                    $this->EE =& get_instance();

                    // Make the Query
                    $this->EE->db->from('exp_channel_titles');
                    $this->EE->db->where('channel_id', $this->channel_id);
                    $this->EE->db->where('status', $this->channel_entry_status);
                    $this->EE->db->where('author_id', $this->EE->session->userdata('member_id'));
                    //$this->EE->db->where('exp_channel_titles.entry_date >=', strtotime($config['date_filter_start']));
                    //$this->EE->db->where('exp_channel_titles.entry_date <=', strtotime($config['date_filter_end']));
                    $count = $this->EE->db->count_all_results();


                    /*
                     * Since the user will be registering a new camper, incrememnt the camper count up by 1.
                     * If there are no campers returned, then this is their first camper. Return 1.
                     */
                    if($count > 0)
                    {
                        $this->return_data = $count + 1;
                    }
                    else
                    {
                        $this->return_data = 1;
                    }
                }

                // ----------------------------------------------------------------

                /**
                 * Plugin Usage
                 */
                public static function usage()
                {
                    ob_start();
            ?>

            Returns an integer of the number of campers a logged in user has. {exp:camper_count}
            <?php
                    $buffer = ob_get_contents();
                    ob_end_clean();
                    return $buffer;
                }
            }


            /* End of file pi.camper_count.php */
            /* Location: /system/expressionengine/third_party/camper_count/pi.camper_count.php */
3

Use Session Caching.

http://ellislab.com/expressionengine/user-guide/development/usage/session.html#id4

You can initialise it first, but I've found it works fine with out this:

//###   Setup the page loading Cache   ###
if(!isset($this->EE->session->cache)) $this->EE->session->cache = array();
if(!isset($this->EE->session->cache[__CLASS__])) $this->EE->session->cache[__CLASS__] = array();

Then check if set before the DB call, and set afterwards...

if (isset($this->EE->session->cache[__CLASS__]['entry_count'])) {
    $count =  $this->EE->session->cache[__CLASS__]['entry_count'];
} else {
    // Make the Query
    $this->EE->db->from('exp_channel_titles');
    $this->EE->db->where('channel_id', $this->channel_id);
    $this->EE->db->where('status', $this->channel_entry_status);
    $this->EE->db->where('author_id', $this->EE->session->userdata('member_id'));
    $count = $this->EE->db->count_all_results();
    $this->EE->session->cache[__CLASS__]['entry_count'] = $count;
}

As you can read from the EE description (link above), this is a page loading cache - so only useful for single display of a single page. Therefore if there are multiple calls on the same page to this add-on/function then it will only call the database once. If there are other users or other pages the visitor uses, it will repeat the DB query for each.

Remember this is shared by all add-ons, so either use a unique identifier for the cache array, or use a multi-dimensional array and have the first element ideally identify your add-on, to avoid any overwriting of the cache area.

| improve this answer | |
  • Great tip, thanks. I also noticed that using this plugin several times in a template returned an odd-looking cache string unless I added a random parameter to the plugin tag. – mjr Mar 13 '13 at 20:09
0

Each instance of your plugin is isolated. It has no reference to the previous instance. So, yes, you're hitting the db each time.

You can see that preload_replace variables are parsed before plugin tags.

So you need some way to cache the first hit and use that value again, when you use your plugin in a template. I haven't used it (yet), but I'm guessing that's part of Stash's scope.

| improve this answer | |
  • Thanks, in looking into this further, EE's template parser automatically cached the return value of a plugin tag when the parameters and tag data are the same on subsequent calls. In my case, this was happening, but with many plugins it may not. – mjr Mar 13 '13 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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