Application Plugins

Application plugins are PHP classes that can be written to add specialized functionality to CollectiveAccess. Custom user interfaces, menu items, and screens are all added to a system with application plugins.

Each application plugin has its own directory in app/plugins which contains all of the code, views, graphics and configuration required for operation. At a minimum, every plugin has a plugin class. This class, a subclass of BaseApplicationPlugin, defines methods that “hook” various events that may occur during a user request. Plugin classes need only implement methods for the hooks they are interested in. Every time a user request is processed by CollectiveAccess and hookable events triggered, each plugin implementing a method for a given hook will be called.

Information will be passed to your methods by the application plugin interface. The scope and format of this information varies by hook and is described in detail below.

All plugins have access to the current request object, and by extension, request parameters and the application configuration file via an inherited getRequest() method.

Usage

Application plugins are particularly useful for:

  • Adding custom menus

  • Adding completely custom screens with individual controllers, views and database tables

  • Modifying, verifying, or otherwise intercepting data being edited, saved or deleted

  • Modifying the behavior of the CollectiveAccess user interface in specific ways

Note

Other application plugins exist to to add support for new media formats, add custom search functionality, implement new attribute types (including attributes that leverage web services), generate custom item identifiers, or support alternative file and media storage (eg. cloud storage, external repositories).

Layout

Every plugin has a directory located in app/plugins. The name of this directory should be the name of the plugin (for example mediaImporter). Within this directory, create a file with the name of the plugin and the suffix ‘Plugin.php’ This file should contain a PHP class with the plugin’s name suffixed with ‘Plugin’.

The plugin can have its own controllers, views, graphics and configuration. These are located in directories within the plugin directory, with the following layout (following our ‘mediaImporter’ example):

  • app/plugins/mediaImporter

  • app/plugins/mediaImporter/mediaImporterPlugin.php [plugin class]

  • app/plugins/mediaImporter/conf [directory containing plugin’s configuration file(s); most plugins define at least one configuration file]

  • app/plugins/mediaImporter/controllers [directory containing plugin’s controllers; only needed if the plugin generates a full user interface]

  • app/plugins/mediaImporter/views [directory containing views for the plugin’s controllers; only needed if the plugin generates a full user interface]

  • app/plugins/mediaImporter/graphics [directory containing graphic elements; only needed if the plugin generates a full user interface]

The Plugin Class

Besides implementing a method for each hook the plugin needs to use, a checkStatus() method must also be defined. This returns information about the plugin, and determines whether it is available for use or not. The return value for checkStatus() is an array with four keys:

  • Description: a description of the plugin

  • Errors: an array of text error messages relating to the initialization of the plugin. This should be an empty array if there are no errors. If the plugin is not available the reason why should be expressed in the errors array.

  • Warnings: an array of text warning messages relating to the initialization of the plugin. Should be a list of warnings about anything that will limit the functionality of the plugin. Should be an empty array if there are no warnings.

  • Available: set to true if the plugin is loaded and available for use, false if it cannot load for some reason.

If initialization of the plugin fails, or for some reason the plugin should not be available in the current context (eg. the user does not have privileges to use the plugin, or some requirement for running is not met) then you must return false for the available value.

The plugin must also set the $description property, inherited from the base plugin class. This should be set to a short description of the plugin, displayed to the system administrator.

If the plugin needs to load its own configuration files or do other initialization, include a constructor in your class. The constructor is passed an absolute file path to the plugin’s directory, which is needed to load plugin-specific configuration files (or anything else in the plugin directory).

Hooks

The following hooks can be used by the plugin by defining a method in the plugin class. To do so, use the hook name prefixed with “hook.”

If your plugin needs to run every time a user edits an item, define a method in the class like this:

public function hookEditItem($pa_params) {
     $item_id = $pa_params['id'];  // The parameter passed to EditItem is a key'ed array of values (see below for details)
     $table_num = $pa_params['table_num'];

     // ... more code here ...
}

Note that some hooks require you to return a value, while others do not. Use care when writing plugins that modify standard user interface elements such as menu bars; errors in the values the plugin returns for hooks such as RenderMenuBar can make the system unusable.

If the plugin returns an array, the contents of that array will be merged with the array that was passed, effectively incorporating any changes. There is one significant exception: if you return an empty the plugin manager will immediately return the null value to the caller and abort processing. Other plugins that may respond to the hook will not be called. This allows the plugin to “short circuit” a call to a hook. Returning any non-array value from the plugin is ignored by the plugin manager. In those cases, the plugin manager will return the parameters passed into the hook unchanged.

Below are several tables with Hooks, descriptions of Hooks, and Hook parameters.

Editing (Providence editors)

These hooks are triggered by specific actions in the Providence object, entity, place, etc. editors.

Hook Name

Description

Parameters

EditItem

Triggered when any bundle-able item (ca_objects, ca_entities), are opened for editing in Providence

Param 1: an array with the following keys: -id = the row_id of the item being edited -table_num: the table number for the type of item being edited -table_name: the name of the table for the type of item being edited -instance: an instance of the model corresponding to the item being edited, loaded with the current row

BeforeSaveItem

Triggered just before any bundle-able item (ca_objects, ca_entities, et. al.) is saved in Providence. The new values from the form are not applied at this time. To modify data before saving it to the database use BeforeBundleInsert and BeforeBundleUpdate.

Param 1: an array with the following keys: id = the row_id of the item being edited table_num: the table number for the type of item being edited table_name: the name of the table for the type of item being edited instance: an instance of the model corresponding to the item being saved, loaded with the current row

SaveItem

Triggered after any bundle-able item (ca_objects, ca_entities, et. al.) is saved in Providence.

Param 1: an array with the following keys: id = the row_id of the item being edited table_num: the table number for the type of item being edited table_name: the name of the table for the type of item being edited instance: an instance of the model corresponding to the item being saved, loaded with the current row

BeforeDuplicateItem

Triggered just before any bundle-able item (ca_objects, ca_entities, et. al.) is duplicated in Providence. This hook gives your plug-in the opportunity to make modifications to the item being duplicated prior to it being committed to the database.

Param 1: an array with the following keys: id = the row_id of the item being duplicated table_num : the table number for the type of item being duplicated table_name : the name of the table for the type of item being duplicated instance : an instance of the model corresponding to the item being duplicated, loaded with the current row

DuplicateItem

Triggered after any bundle-able item (ca_objects, ca_entities, et. al.) is duplicated in Providence.

Param 1: an array with the following keys: id = the row_id of the item being duplicated table_num : the table number for the type of item being duplicated table_name : the name of the table for the type of item being duplicated instance : an instance of the model corresponding to the item being duplicated, loaded with the current row duplicate : an instance of the model corresponding to the newly created duplicate

DeleteItem

Triggered when any bundle-able item (ca_objects, ca_entities, et. al.) are deleted by the Providence editor.

Param 1: an array with the following keys: id = the row_id of the item being edited table_num : the table number for the type of item being edited table_name : the name of the table for the type of item being edited instance : an instance of the model corresponding to the item being deleted, loaded with the current row

Labelable Models (API-level calls)

These hooks are called when your code invokes addLabel(), editLabel() or deleteLabel() on a model inheriting from LabelableBaseModelWithAttributes.

Hook Name

Description

Parameters

BeforeLabelInsert

Triggered before label is inserted when addLabel() is called. This hook gives you the opportunity to modify a label before it is recorded in the database.

Param 1: an array with the following keys: id = the row_id of the item being edited. This is not the label_id! This is the primary key of the row to which the label is associated. table_num : the table number for the type of item being edited. This is not the number of the label table. It is the name of the table to which the label is associated. table_name : the name of the table for the type of item being edited. This is the name of the table associated with the label, not the label table itself. instance : an instance of the model corresponding to the item being saved, loaded with the current row label_instance : an instance of the model corresponding to the label being added, loaded with the label being created. Any changes you need to make to the label before it is written to the database should made to this model.

AfterLabelInsert

Triggered after label is inserted when addLabel() is called. This hook lets your code run after a new label has been written to the database.

Param 1: an array with the following keys: id = the row_id of the item being edited. This is not the label_id! This is the primary key of the row to which the label is associated. table_num : the table number for the type of item being edited. This is not the number of the label table. It is the name of the table to which the label is associated. table_name : the name of the table for the type of item being edited. This is the name of the table associated with the label, not the label table itself. instance : an instance of the model corresponding to the item being saved, loaded with the current row label_instance : an instance of the model corresponding to the label being inserted, loaded with the new label information. This model will reflect the label as written.

BeforeLabelUpdate

Triggered before label is updated when editLabel() is called. This hook gives you the opportunity to modify a label before it is recorded in the database.

Param 1: an array with the following keys: id = the row_id of the item being edited. This is not the label_id! This is the primary key of the row to which the label is associated. table_num : the table number for the type of item being edited. This is not the number of the label table. It is the name of the table to which the label is associated. table_name : the name of the table for the type of item being edited. This is the name of the table associated with the label, not the label table itself. instance : an instance of the model corresponding to the item being saved, loaded with the current row label_instance : an instance of the model corresponding to the label being saved, loaded with the label being edited. Any changes you need to make to the label before it is written to the database should made to this model.

AfterLabelUpdate

Triggered after label is updated when editLabel() is called. This hook lets your code run after a label modification has been written to the database.

Param 1: an array with the following keys: id = the row_id of the item being edited. This is not the label_id! This is the primary key of the row to which the label is associated. table_num : the table number for the type of item being edited. This is not the number of the label table. It is the name of the table to which the label is associated. table_name : the name of the table for the type of item being edited. This is the name of the table associated with the label, not the label table itself. instance : an instance of the model corresponding to the item being saved, loaded with the current row label_instance : an instance of the model corresponding to the label being saved, loaded with the label being edited. This model will reflect any changes made to the label.

BeforeLabelDelete

Triggered before label is deleted when removeLabel() is called. This hook gives you the opportunity to note that a label is being deleted before the fact. It does not (currently) allow you to cancel the delete.

Param 1: an array with the following keys: id = the row_id of the item being edited. This is not the label_id! This is the primary key of the row to which the label is associated. table_num : the table number for the type of item being edited. This is not the number of the label table. It is the name of the table to which the label is associated. table_name : the name of the table for the type of item being edited. This is the name of the table associated with the label, not the label table itself. instance : an instance of the model corresponding to the item being saved, loaded with the current row label_instance : an instance of the model corresponding to the label being saved, loaded with the label being edited. Any changes you need to make to the label before it is written to the database should made to this model.

AfterLabelDelete

Triggered after label is deleted when removeLabel() is called.

Param 1: an array with the following keys: id = the row_id of the item being edited. This is not the label_id! This is the primary key of the row to which the label is associated. table_num : the table number for the type of item being edited. This is not the number of the label table. It is the name of the table to which the label is associated. table_name : the name of the table for the type of item being edited. This is the name of the table associated with the label, not the label table itself. instance : an instance of the model corresponding to the item being saved, loaded with the current row label_instance : an instance of the model corresponding to the label being saved, loaded with the label being edited. This model will reflect any changes made to the label.

Bundleable models (API-level calls)

These hooks are called when your code invokes insert() or update() on a model inheriting from BundleableLabelableBaseModelWithAttributes.

Hook Name

Description

Parameters

BundleBeforeInsert

Triggered before instance is inserted into the database when insert() is called. This hook gives you the opportunity to modify instance data before it is recorded in the database.

Param 1: an array with the following keys: id = null since no id is set before the insert. table_num : the table number for the type of item being edited. table_name : the name of the table for the type of item being edited. instance : an instance of the model corresponding to the item being inserted, loaded with the current row. You can alter the contents of this instance as needed.

AfterBundleInsert

Triggered after instance is inserted when insert() is called. This hook lets your code run after a new instance has been written to the database. The primary key id will be set to the value generated by the database.

Param 1: an array with the following keys: id = the newly issues row_id of the item that has just been inserted. table_num : the table number for the type of item being edited. table_name : the name of the table for the type of item being edited. instance : an instance of the model corresponding to the item being saved, loaded with the current row

BeforeBundleUpdate

Triggered before bundle is updated when update() is called. This hook gives you the opportunity to modify the instance before it is recorded in the database.

Param 1: an array with the following keys: id = the row_id of the item being edited. table_num : the table number for the type of item being edited. table_name : the name of the table for the type of item being edited. . instance : an instance of the model corresponding to the item being saved, loaded with the current row. You can alter the contents of this instance as needed.

AfterBundleUpdate

Triggered after instance is updated when editLabel() is called. This hook lets your code run after an instance modification has been written to the database.

Param 1: an array with the following keys: id = the row_id of the item being edited. table_num : the table number for the type of item being edited. table_name : the name of the table for the type of item being edited. instance : an instance of the model corresponding to the item being saved, loaded with the current row

Authorization

Hook Name

Description

Parameters

GetRoleActionList

Triggered when Providence is generating a list of user actions. This hooks gives your plug-in the ability to add its own user actions to the list. These actions will appear in the user roles configuration screens alongside Providence’s standard actions and function identically. You can test whether a user has privileges for your custom actions at run-time and vary the behavior of your plug-in accordingly.

Param 1: user actions array (structure is as defined in the user_actions.conf configuration file; you should modify this array and then return it in your hook. The format of your modifications should conform to the layout of a standard user action entry in user_actions.conf.

Task Queue

Hook Name

Description

Parameters

RegisterTaskQueuePluginDirectories

Triggered when task queue is initialized. This hook given your plug-in the opportunity to insert its own task queue plugin directories into the list of paths the TaskQueue class looks in to load task handler plugins. This is useful when you need to post tasks onto the task queue that use a handler specific to your application plugin. Rather than putting part of your plugin - the task handler - in the main plugins directory at app/lib/core/Plugins/TaskQueueHandlers, you can keep them in a directory of your choosing within the your plug-in directory.

Param 1: an array with the following keys: handler_plugin_directories : the array of plugin directories. Your plugin should add its own directory paths to this array. instance : the current TaskQueue instance

User Login Editor

Hook Name

Description

Parameters

BeforeUserSaveData

Triggered just before primary user information (user name, password, email, name) are saved.

Param 1: an array with the following keys: user_id : the user_id of the user being edited. instance : An instance of the ca_users model for the user being edited.

AfterUserSaveData

Triggered just after primary user information (user name, password, email, name) are saved.

Param 1: an array with the following keys: user_id : the user_id of the user being edited. instance : An instance of the ca_users model for the user being edited.

BeforeUserSavePrefs

Triggered just before user preferences are saved.

Param 1: an array with the following keys: user_id : the user_id of the user being edited. instance : An instance of the ca_users model for the user being edited.

AfterUserSavePrefs

Triggered just after user preferences are saved.

Param 1: an array with the following keys: user_id : the user_id of the user being edited. instance : An instance of the ca_users model for the user being edited. modified_prefs: An array with keys set to the codes of preferences that have been modified by the save. Array values are true for each key.

Periodic Tasks

Hook Name

Description

Parameters

hookPeriodicTask

Triggered every time periodic tasks need to be run. This typically happens in conjunction with processing of the task queue by a Unix-style CRON job running the support/utils/processTaskQueue.php utility script, but can be triggered elsewhere. Your method implementing this hook should do whatever it needs, pulling data from configuration files, the network, filesystem, Etc. No parameters are passed by the application to your plugin via this hook.

Note that there is no guarantee that invocations of your method will be evenly spaced or have a set minimum or maximum interval between invocations. If you need to restrict how often your method runs you will have to adjust the frequency with which periodic tasks are run (typically by modifying the CRON job that started the run) or implement logic in your plugin to keep track of invocations. None

None