| 1 |
Developer documentation for notifications framework.
|
| 2 |
|
| 3 |
Overview
|
| 4 |
--------
|
| 5 |
The notifications module is just the main engine that handles events, queries subscribed users, queues notifications
|
| 6 |
and does the queue processing passing the right data for message composition and sending.
|
| 7 |
However, all the subscription and event types, and also messages and sending methods are provided by plug-in modules.
|
| 8 |
So the notifications module just processes the data ad sends it through the different stages not knowing anything
|
| 9 |
about specific subscription types or events or messaging methods.
|
| 10 |
|
| 11 |
Subscriptions handling
|
| 12 |
---------------------
|
| 13 |
For each individual subscription of a user to an object/object type/user there's a row in the 'notifications' table
|
| 14 |
The subscription conditions are stored in the 'notifications_field' table, which allows any number of
|
| 15 |
conditions for a given subscription, one row for each condition
|
| 16 |
I.e.
|
| 17 |
User a may be subscribed subscribed to
|
| 18 |
- Nodes of type x
|
| 19 |
- Posted by user y
|
| 20 |
- With taxonomy term t
|
| 21 |
Or User b may be subscribed to
|
| 22 |
- Nodes of type 'blog'
|
| 23 |
- Posted by user x
|
| 24 |
This last one would make a subscription to a user's blog.
|
| 25 |
|
| 26 |
All this may cause some overlap, having more than one notification for a user in response to the same event.
|
| 27 |
This should be resolved in the final message composition and sending steps, preventing a user being notified more than once for the same event.
|
| 28 |
I.e. a user may be subscribed to a given taxonomy term and also to a given node type, causing the same node post to produce
|
| 29 |
two notifications, one for the taxonomy term and one for the node type.
|
| 30 |
However, when the user wants immediate notifications for the first subscription but delayed ones for the second one -I.e. a daily message-
|
| 31 |
it seems ok to send the event notification in both messages. Thus this de-duping will be done only for messages in the sime time interval.
|
| 32 |
|
| 33 |
The UI for subscribing and unsubscribing is also provided by a plug-in module. There's the notifications_ui module which
|
| 34 |
handles simple node subscriptions but this one could be replaced by a different module if you want a different kind of UI.
|
| 35 |
|
| 36 |
The processing model
|
| 37 |
--------------------
|
| 38 |
How system events are processed and converted into final notifications to users
|
| 39 |
* An event is triggered
|
| 40 |
These events will be defined by plug-in modules and may respond to any Drupal action, like node posting, editing, comment posting...
|
| 41 |
A odule triggers an event, builds an array with the event parameters and calls notifications_event($event)
|
| 42 |
* The event is filled in and stored
|
| 43 |
The notifications module will add default parameters to the event and the event will be stored calling notifications_event_save($event)
|
| 44 |
* Processing and queueing
|
| 45 |
Then notifications_queue($event) will be called. This function will populate the notifications_queue table with a list of pending event notifications for specific users
|
| 46 |
To query the list of subscribed users, hook_notifications('query', $event) will be called, with the modules returning query conditions for the notifications table
|
| 47 |
All the queued notifications will be filled in with a single db query
|
| 48 |
* Queue processing on cron.
|
| 49 |
The notifications_queue table will be checked periodically, compiling pending notifications for each user
|
| 50 |
There are two kinds of notifications:
|
| 51 |
- Messages to send right away. When the 'delivery interval' is zero, each event produces a single message.
|
| 52 |
- Messages to be digested. When we have notifications to be delivered for a given interval, all the events corresponding to that interval will be compiled and digested in a single message
|
| 53 |
* Message composition
|
| 54 |
All the events, and other related objects for a message -nodes, comments..- will be fetched and passed to the message composition layer
|
| 55 |
This layer will fetch message templates from messaging system and will run them through token replacement using these objects
|
| 56 |
Note: The message templates may depend on the delivery method, so message templates are handled also by messaging system.
|
| 57 |
I.e. you may want longer notifications for emails but shorter one for SMS's
|
| 58 |
* Message delivery
|
| 59 |
The message array is passed to the messaging layer which will do the final formatting, depending on delivery method and send away the message to the user
|
| 60 |
For further information on messages, see the messaging framework
|
| 61 |
|
| 62 |
|
| 63 |
The notifications hook
|
| 64 |
----------------------
|
| 65 |
This hook must be implemented by modules defining event and subscription types
|
| 66 |
|
| 67 |
function hook_notifications($op, &$arg0 = NULL, $arg1 = NULL, $arg2 = NULL)
|
| 68 |
|
| 69 |
Depending on the first parameter, this function will have different parameters and return values
|
| 70 |
|
| 71 |
* 'names', Adds names to the subscription types for display
|
| 72 |
$arg1 will be a $subscriptions object.
|
| 73 |
It should populate the 'type_name' and the 'names' elements for subscriptions handled by the module
|
| 74 |
implementing it. A single subscription may join different conditions so we keep multiple names
|
| 75 |
in the 'names' element array.
|
| 76 |
|
| 77 |
Example:
|
| 78 |
$subs = &$arg0;
|
| 79 |
if ($subs->event_type == 'node') {
|
| 80 |
$subs->type_name = t('Content');
|
| 81 |
if (!empty($subs->fields['type'])) {
|
| 82 |
$subs->names['type'] = t('Content type: %type', array('%type' => node_get_types('name', $subs->fields['type'])));
|
| 83 |
}
|
| 84 |
if (!empty($subs->fields['author'])) {
|
| 85 |
$author = user_load(array('uid' => $subs->fields['author']));
|
| 86 |
$subs->names['author'] = t('Author: %name', array('%name' => $author->name));
|
| 87 |
}
|
| 88 |
}
|
| 89 |
|
| 90 |
* 'subscription types', Defines subscription types provided by this module
|
| 91 |
The return value will be an array of elements with the form:
|
| 92 |
'type name' => array(
|
| 93 |
'event_type' => type of event,
|
| 94 |
'title' => Name to display to the user,
|
| 95 |
'access' => Permission for using this subscription type,
|
| 96 |
'page' => Callback to display the user subscriptions page,
|
| 97 |
'fields' => Array of fields that define this subscription type. I.e. for node subscriptions,
|
| 98 |
)
|
| 99 |
|
| 100 |
Example:
|
| 101 |
$types['thread'] = array(
|
| 102 |
'event_type' => 'node',
|
| 103 |
'title' => t('Threads'),
|
| 104 |
'access' => 'subscribe to content',
|
| 105 |
'page' => 'notifications_content_page_thread',
|
| 106 |
'fields' => array('nid'),
|
| 107 |
);
|
| 108 |
|
| 109 |
* 'query', Returns query conditions for finding subscribed users
|
| 110 |
|
| 111 |
Example:
|
| 112 |
$query[] = array(
|
| 113 |
'fields' => array(
|
| 114 |
'nid' => $node->nid,
|
| 115 |
'type' => $node->type,
|
| 116 |
'author' => $node->uid,
|
| 117 |
),
|
| 118 |
);
|
| 119 |
|
| 120 |
- 'event types', Event types supported by this module
|
| 121 |
- 'event load', Add objects to the event for message composing
|
| 122 |
- 'node options', Returns subscription status and options for a node object
|
| 123 |
See
|
| 124 |
- notifications_content_notifications()
|
| 125 |
- notifications_taxonomy_notifications()
|