• Home
  • Consultancy
  • Contact
  • Plugin settings on Elgg 1

    June 20th, 2008 by Marcus Povey

    Whew, well it’s been a monumentally busy development week on the new Elgg 1.0 codebase. The whole team has been working hard putting things together, and I’ve written so much cool stuff its hard to know where to begin.

    Much of the really cool stuff I’ve been working on has been under the hood (XML-RPC, PAM, API etc), but I’ll start with giving a brief summary of what I was working on today – plugin administration.

    As with Elgg Classic, Elgg 1 supports plugins modules. However, these modules can be turned on and off by the administrator (in much the same way as wordpress plugins can be). They can also have settings edited.

    There are two things as a plugin writer to do to take full advantage of this:

    Manifests

    Manifests tell Elgg a little bit about your plugin. Your plugin will still work without them, but I highly recommend you use them.

    Simply create a file called manifest.xml in your plugin’s top level directory that looks something like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <plugin_manifest>
    <field key="author" value="Marcus Povey" />
    <field key="version" value="1.0" />
    <field key="description" value="My first plugin!" />
    <field key="website" value="http://www.marcus-povey.co.uk/" />
    <field key="copyright" value="(C) MyCorp 2008" />
    <field key="licence" value="GNU Public License version 2" />
    </plugin_manifest>

    Per-plugin settings

    These let you provide some admin controlled configuration options for your plugin. Adding these is relatively simple.

    1. Create a file in your plugin’s view folder called settings/PLUGINNAME/edit.php, where PLUGINNAME is the name of your plugin’s directory in the mod hierarchy.
    2. Fill this file with the form elements you want to display together with internationalised text labels. Note: you don’t need to add a save button or the form, this will be handled by the framework.
    3. Set the name attribute in your form components to param[VARNAME] where VARNAME is the name of the variable. These will be saved as metadata attached to a plugin entity. So, if your variable is called param[myparameter] your entity (which is also passed to this view as $vars['entity']) will be called $vars['entity']->myparameter.

    Here is an example of this view:

    <p>
    <?php echo elgg_echo('myplugin:settings:limit'); ?>

    <select name="params[limit]">
    <option value="5" <?php if ($vars['entity']->limit == 5) echo " selected=\"yes\" "; ?>>5</option>
    <option value="8" <?php if ((!$vars['entity']->limit) || ($vars['entity']->limit == 8)) echo " selected=\"yes\" "; ?>>8</option>
    <option value="12" <?php if ($vars['entity']->limit == 12) echo " selected=\"yes\" "; ?>>12</option>
    <option value="15" <?php if ($vars['entity']->limit == 15) echo " selected=\"yes\" "; ?>>15</option>
    </select>
    </p>

    Fun! fun!

    Adding to the River in an Elgg 1 plugin

    June 9th, 2008 by Marcus Povey

    In Elgg 1, we will finally have native support for a River – that is, a stream of short updates of what you and your friends are up to on your profile.

    Here is a short post explaining how you as a plugin writer could add river reporting to your code!

    Events

    The key to how the river works is the Elgg 1 events system and the system log.

    The system log will listen to events and some events pass an object. If the object implements the Loggable interface it will automatically be included in the system log.

    The view

    In order for things to appear in the river you need to provide a view. This view should be /river/CLASSNAME/EVENT, where CLASSNAME is the class you’re interested in and EVENT is the event.

    For example, if you want to output create events for all ElggObjects then you would need to create a file called create.php in a directory /river/ElggObject/create.php.

    This file will be passed a number of variables via $vars.

    • $vars['performed_by'] : An ElggUser object of the user that performed the action.
    • $vars['log_entry'] : The system log row (which includes the event).
    • $vars['object'] : The subject of the event.

    You can use this information to put together a very customisable view, don’t forget to internationalise your strings!

    Introducing the Elgg 1 Query object

    June 4th, 2008 by Marcus Povey

    Elgg 1 is introducing a new (to elgg at least) way of executing arbitrary database queries. Basically, SQL is abstracted away into a class that can be used to construct multiple different types of query through a defined interface.

    This provides two main advantages:

    1. The application programmer does not have to write the SQL themselves.
    2. It becomes considerably easier to change database back ends later down the line.

    In addition, we can add free stuff like access controls etc.

    From the documentation:

    Query provides a framework to construct complex queries in a safer environment.

    The usage of this class depends on the type of query you are executing, but the basic idea is to construct a query out of pluggable classes.

    Once constructed SQL can be generated using the toString method, this should happen automatically if you pass the Query object to get_data or similar.

    To construct a query, create a new Query() object and begin populating it with the various classes that define the various aspects of the query.

    Notes:

    • You do not have to specify things in any particular order, provided you specify all required components.
    • With database tables you do not have to specify your db prefix, this will be added automatically.
    • When constructing your query keep an eye on the error log – any problems will get spit out here. Note also that __toString won’t let you throw Exceptions (!!!) so these are caught and echoed to the log instead.

    Here is an example of a select statement:

    // Construct the query
    $query = new Query();

    // Say which table we're interested in
    $query->addTable(new TableQueryComponent("entities"));

    // What fields are we interested in
    $query->addSelectField(new SelectFieldQueryComponent("entities","*"));

    // Add access control (Default access control uses default fields on entities table.
    // Note that it will error without something specified here!
    $query->setAccessControl(new AccessControlQueryComponent());

    // Set a limit and offset, may be omitted.
    $query->setLimitAndOffset(new LimitOffsetQueryComponent(10,0));

    // Specify the order, may be omitted
    $query->setOrder(new OrderQueryComponent("entities", "subtype", "desc"));

    // Construct a where query
    //
    // This demonstrates a WhereSet which lets you have sub wheres, a
    // WhereStatic which lets you compare a table field against a value and a
    // Where which lets you compare a table/field with another table/field.
    $query->addWhere(
    new WhereSetQueryComponent(
    array(
    new WhereStaticQueryComponent("entities", "subtype","=", 1),
    new WhereQueryComponent("entities","subtype","=", "entities", "subtype")
    )
    )
    );

    get_data($query);

    Constructing a query out of classes in this way provides a lot of scope for expanding the functionality within a common framework, as well as providing a structured way of constructing complicated database queries.

    However, if it looks too complicated, you can use about 99% of Query‘s functionality by using the subclass SimpleQuery, which provides methods for performing much of the standard functionality.

    All content is © Copyright Marcus Povey 2008-2010 and released under a Creative Commons licence unless otherwise stated.

    Creative Commons License