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. |
Link Generation¶
Available from CollectiveAccess Version 1.4.
Hook Name |
Description |
Parameters |
---|---|---|
CanHandleGetAsLinkTarget |
Sets ‘acceptsTarget’ key in returned param array if the link target can be handled by the plugin |
Param 1: an array with the following keys: target : A link target as set in the returnAsLinkTarget option in get(). Your plugin should only set the ‘acceptsTarget’ key in the param array with true for targets it recognizes. |
GetAsLink |
Returns an HTML link to a specific record in a specific table as defined in the passed parameters. This allows the plugin to automatically generate links to itself or elsewhere when using the “returnAsLink” option in get() |
Param 1: an array with the following keys: target : A link target as set in the returnAsLinkTarget option in get(). request : The current request (an RequestHTTP object). content : Link text to display. table : The table that the link should point to. id : The primary key in the table that the link should point to. classname : A CSS class to apply to the link. additionalParameters : Any array of additional parameters to append to the link. Array keys are parameter names and array values are parameter values. May be null if there are no parameters set. options : An array of options. These are the same options that can be passed to the caEditorUrl() and caDetailUrl() helpers. May be null if there are no options set. |
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 |