Elgg Plugin Tip: Make Your Display Queries Extensible With Plugin Hooks

If you’re building an Elgg plugin that executes queries to fetch entities/annotations/etc. for display, odds are someone else will one day need to alter your query, e.g. to change the LIMIT or ORDER BY clauses. Depending on where your query occurs, he/she may have to override a view, replace an action, replace a whole page handler, or have no choice but to alter your plugin code directly. There’s a better way.

Plugin hooks provide a very simple method of making values–including your query parameters–alterable by other plugins. (For WordPress coders, this tutorial sets up a system like the pre_get_posts filter.)

Most queries occur in Elgg core functions that accept an $options parameter array, e.g. elgg_list_entities. All you need to do is pass that value through a plugin hook:

// list items in a widget
$options = array( /* build options array */ );
$options = elgg_trigger_plugin_hook('myplugin:query', 'widget_listing', array(), $options);
echo elgg_list_entities($options);

Now another plugin can easily alter your elgg_list_entities() call by registering a handler for the [myplugin:query, wigdet_listing] hook, and inside it altering and returning the $returnvalue.

If it’s obvious that an extending plugin may need it, you may pass in some data via the third ($params) argument to elgg_trigger_plugin_hook.

But I don’t want to give full control…

If the output of your query is critical to the system (e.g. entities that will be altered), then you needn’t give any control, but to allow limited tinkering, you can just validate the output of the hook and only use the values you’re comfortable with.

For example, say you only want to allow altering LIMIT:

$suggested = elgg_trigger_plugin_hook('myplugin:query', 'widget_listing', array(), $options);
if (!empty($suggested['limit'])) {
    $options['limit'] = (int)$suggested['limit'];
}

For display-only queries, I wouldn’t worry about other plugins breaking your functionality; there are a million ways poorly-coded plugins can do this.

Leave a Reply