Search:

# CWIS Developers Documentation

# Implementing CWIS Plugins

Plugins are a way of modifying existing functionality or adding new functionality to your CWIS installation, without having to modify the CWIS code itself. They are written in PHP and, once placed in the correct location, are loaded and run automatically by CWIS at the appropriate time.

If you want to just change the look and feel of your CWIS site, then you're probably better off creating a new interface, rather than a plugin. If you want to add a specific feature or modify a specific bit of CWIS functionality, then a plugin may be the right choice.

## Names, Files, and Locations

The first step in creating a plugin is to think about what the plugin is supposed to do, and then use that to choose an (ideally unique) base name for your plugin. A base name should begin with a letter and contain only letters and (if appropriate) numbers. The first letter is usually upper-case. If the name contains multiple words, the first letter of each word is usually made upper-case, and all other letters lower-case. For example, if you were writing a plugin to add new CWIS users to a mailing list, you might give it the base name "ListSubscriber".

The base name is used for the name of the PHP file that will contain your plugin. So for our ListSubscriber plugin the plugin file name would be `ListSubscriber.php`.

Once you've created your plugin file, it should be placed in the `/local/plugin` directory in your CWIS installation.

## Classes and Attributes

Plugins in CWIS are implemented as PHP objects, with the plugin's base name as the class name. All plugins are descendents of the Plugin base class. The minimum a CWIS plugin must implement is its own version of the Plugin::Register() method, to set the basic plugin attributes:

    class ListSubscriber extends Plugin {

        function Register()
        {
            $this->Name = "State University Library Mailing List Subscription Plugin";
            $this->Version = "1.0";
            $this->Description = "This plugin will add new users to the StateLib "
                    ." mailing list when they verify their CWIS account, and remove"
                    ." them if their account is deleted.";
            $this->Author = "John Doe";
            $this->Url = "http://library.state.edu/cwisdev/listsubscriberplugin.html";
            $this->Email = "jdoe@state.edu";
            $this->Requires = array(
                    "CWISCore" => "1.9",
                    );
        }
    };

The only attributes that must be set are Plugin::$Name and Plugin::$Version, but assigning values to the others is strongly encouraged, particularly if you may be sharing your plugin with others. The Plugin::$Name attribute should contain a human-readable name for your plugin.

The Plugin::$Requires attribute is used to specify the minimum versions of other plugins that your plugin must have to run. The `CWISCore` plugin can be required to ensure that your plugin is running under at least the specified version of CWIS. Specific descriptions of the other attributes can be found in the documentation for the Plugin class.

## Events and Hooks

CWIS has built into it an event subsystem that provides a way of running some PHP code when certain occurrences happen. Plugins take advantage of this mechanism to accomplish their tasks by "hooking" parts of their code into appropriate events.

To hook into specific events, you'll add an implementation of the Plugin::HookEvents() method to your plugin class:

        function HookEvents()
        {
            return array(
                    "EVENT_USER_VERIFIED" => "AddUserToMailingList",
                    "EVENT_USER_DELETED" => "RemoveUserFromMailingList",
                    );
        }

This method is called when your plugin is loaded, and allows you specify methods of your plugin class to be run at specific times, depending on the event type. With CHAIN events, for example, you might modify data before it's saved or before it's displayed, or with a FIRST event like `EVENT_USER_AUTHENTICATION` you might connect CWIS to your own mechanism for authenticating user logins.

A list of the events currently available to hook onto can be found on the CWIS Event Callbacks page. This list will expand with each new version of CWIS, based on feedback from plugin authors about what other events they may want to hook onto. Plugins may also define their own events, for others to hook onto, by implementing a Plugin::DeclareEvents() method.

## Methods and Parameters

So you've come up with a base name for your plugin, you've created a PHP class with that base name and put it into a correspondingly-named file, and you've added a Plugin::HookEvents() method so that your code is called when the appropriate events occur. Now you need to implement that code to accomplish the actual work.

There are often values associated with an event that may be needed by plugins that want to hook into that event. For example, with the `EVENT_USER_AUTHENTICATION` event it's very useful to have the login name and password that the user entered. These values are passed to the hooked methods as parameters, according to the parameter list defined for that event.

So for our ListSubscriber plugin, the method in our `ListSubscriber` class to add a user might look something like this:

        function AddUserToMailingList($UserId)
        {
            $UserToAdd = new User($UserId);
            $MLMngr = new MyMailingListManager();
            if ($MLMngr->IsSubscribedToList($UserToAdd->Get("Email")) == FALSE)
            {
                $MLMngr->AddSubscriber($UserToAdd->Get("Name"),
                        $UserToAdd->Get("Email"));
            }
        }

The parameters sent by each event are listed and described on the CWIS Event Callbacks page. It's important to make sure the method you hook accepts the right list of parameters and returns the right values, so that the code that signalled the event and any other plugins hooked onto the event execute correctly.

## Configuration

Your plugin may have some configurable settings. If the settings are reasonably simple, you can allow people to change their values via the built-in plugin configuration interface (rather than having to write your own) by defining the configuration settings in Plugin::Register():

            $this->CfgSetup["SubConfirm"] = array(
                    "Type" => "Flag",
                    "Label" => "Subscription Confirmation",
                    "Help" => "This determines whether new subscribers will be required to confirm their mailing list subscription.",
                    "OnLabel" => "Yes",
                    "OffLabel" => "No",
                    );

(In the above example, `"SubConfirm"` is the name of the configuration setting.)

Configuration settings may be retrieved by calling Plugin::ConfigSetting(), and initial values should be set by calling this method in Plugin::Install():

        function Install()
        {
            $this->ConfigSetting("SubConfirm", TRUE);
        }

Plugin::ConfigSetting() can also be used to store and retrieve your own configuration values (i.e. ones not set via the built-in plugin configuration interface).

### Supported Configuration Setting Types

Type | Required | Optional | Notes
--- | --- | --- | ---
(all) | `Type`, `Label` | `Help` | The `Help` value is optional but highly recommended.
`Flag` | `OnLabel`, `OffLabel` | (none) | `Flag` setting values are `TRUE` for on and `FALSE` for off.
`Text` | (none) | `Size`, `MaxLength` | `Size` defaults to 40 and `MaxLength` to 80.
`Paragraph` | (none) | `Rows`, `Columns` | `Rows` defaults to 4 and `Columns` to 40.
`Number` | (none) | `MaxVal`, `Size`, `MaxLength` | Form field size is based on `MaxVal`, but may be overridden by specifying `Size` and/or `MaxLength`.
`Option` | `Options` | (none) | `Options` is an associative array, with configuration setting values for the array indexes and setting labels for the array values.
`MetadataField` | `FieldTypes` | (none) | `FieldTypes` should be constants from the MetadataSchema class logically ORed together (e.g. `MetadataSchema::MDFTYPE_TEXT | MetadataSchema::MDFTYPE_PARAGRAPH`). The stored value is the field ID.
`Heading` | `Label` | (none) | This is a psuedo-type, used for adding section headings to the configuration page. `Label` should contain the heading text.

## Further Reading

That covers the basics of how to implement a simple CWIS plugin. More advanced information can be found on the Advanced CWIS Plugin Implementation section and in the documentation for the base Plugin class.

If you have questions that aren't answered here, please sign up for the CWIS Users Discussion List and post them there. Other users may be able to provide help or insight, or may even already have a plugin available that already does what you need!