root / htmltest / sites / all / modules / privatemsg / privatemsg.api.php @ a5572547
1 |
<?php
|
---|---|
2 |
|
3 |
/**
|
4 |
* @file
|
5 |
* Privatemsg API Documentation
|
6 |
*/
|
7 |
|
8 |
/**
|
9 |
* @mainpage Privatemsg API Documentation
|
10 |
* This is the API documentation of Privatemsg.
|
11 |
*
|
12 |
* - Topics:
|
13 |
* - @link api API functions @endlink
|
14 |
* - @link sql Query builder and related hooks @endlink
|
15 |
* - @link message_hooks Message hooks @endlink
|
16 |
* - @link generic_hooks Generic hooks @endlink
|
17 |
* - @link theming Theming @endlink
|
18 |
* - @link types Types of recipients @endlink
|
19 |
*/
|
20 |
|
21 |
/**
|
22 |
* @defgroup sql Query Builder
|
23 |
*
|
24 |
* Query builder and related hooks
|
25 |
*
|
26 |
* Privatemsg uses SelectQuery combined with custom tags to allow to customize
|
27 |
* almost all SELECT queries. For more information about SelectQuery, see
|
28 |
* http://drupal.org/developing/api/database and http://drupal.org/node/310075.
|
29 |
*
|
30 |
* Arguments to a given query is stored in the metadata, with numerical keys
|
31 |
* (arg_%d) according to the position of the argument.
|
32 |
*
|
33 |
*/
|
34 |
|
35 |
/**
|
36 |
* @addtogroup sql
|
37 |
* @{
|
38 |
*/
|
39 |
|
40 |
/**
|
41 |
* Query to search for autocomplete usernames.
|
42 |
*
|
43 |
* @param $query
|
44 |
* Query object
|
45 |
*
|
46 |
* @see privatemsg_sql_autocomplete()
|
47 |
* @see hook_query_alter()
|
48 |
*/
|
49 |
function hook_query_privatemsg_autocomplete_alter($query) { |
50 |
global $user; |
51 |
|
52 |
$search = $query->getMetaData('arg_1'); |
53 |
$names = $query->getMetaData('arg_2'); |
54 |
|
55 |
// For example, add a join on a table where the user connections are stored
|
56 |
// and specify that only users connected with the current user should be
|
57 |
// loaded.
|
58 |
$query->innerJoin('my_table', 'm', 'm.user1 = u.uid AND m.user2 = :user2', array(':user2' => $user->uid)); |
59 |
} |
60 |
|
61 |
/**
|
62 |
* Display a list of threads.
|
63 |
*
|
64 |
* @param $query
|
65 |
* Query object
|
66 |
*
|
67 |
* @see privatemsg_sql_list()
|
68 |
* @see hook_query_alter()
|
69 |
*/
|
70 |
function hook_query_privatemsg_sql_list_alter($query) { |
71 |
$account = $query->getMetaData('arg_1'); |
72 |
} |
73 |
|
74 |
/**
|
75 |
* Query definition to load messages of one or multiple threads.
|
76 |
*
|
77 |
* @param $query
|
78 |
* Query object
|
79 |
*
|
80 |
* @see privatemsg_sql_messages()
|
81 |
* @see hook_query_alter()
|
82 |
*/
|
83 |
function hook_query_privatemsg_messages_alter($query) { |
84 |
$threads = $query->getMetaData('arg_1'); |
85 |
$account = $query->getMetaData('arg_2'); |
86 |
$load_all = $query->getMetaData('arg_3'); |
87 |
} |
88 |
|
89 |
/**
|
90 |
* Alter the query that loads the participants of a thread.
|
91 |
*
|
92 |
* @param $query
|
93 |
* Query object
|
94 |
*
|
95 |
* @see privatemsg_sql_participants()
|
96 |
* @see hook_query_alter()
|
97 |
*/
|
98 |
function hook_query_privatemsg_participants_alter($query) { |
99 |
$thread_id = $query->getMetaData('arg_1'); |
100 |
$account = $query->getMetaData('arg_2'); |
101 |
} |
102 |
|
103 |
/**
|
104 |
* Loads all unread messages of a user (only the count query is used).
|
105 |
*
|
106 |
* @param $query
|
107 |
* Query object
|
108 |
*
|
109 |
* @see privatemsg_sql_unread_count()
|
110 |
* @see hook_query_alter()
|
111 |
*/
|
112 |
function hook_query_privatemsg_unread_count_alter($query) { |
113 |
$account = $query->getMetaData('arg_1'); |
114 |
} |
115 |
|
116 |
/**
|
117 |
* Alter the query that loads deleted messages to flush them.
|
118 |
*
|
119 |
* @param $query
|
120 |
* Query object
|
121 |
*
|
122 |
* @see privatemsg_sql_deleted()
|
123 |
* @see hook_query_alter()
|
124 |
*/
|
125 |
function hook_query_privatemsg_deleted_alter($query) { |
126 |
$days = $query->getMetaData('arg_1'); |
127 |
$max = $query->getMetaData('arg_2'); |
128 |
} |
129 |
|
130 |
/**
|
131 |
* @}
|
132 |
*/
|
133 |
|
134 |
/**
|
135 |
* @defgroup api API functions
|
136 |
*
|
137 |
* There are two different functions to send messages.
|
138 |
* Either by starting a @link privatemsg_new_thread new thread @endlink
|
139 |
* or @link privatemsg_reply reply @endlink to an existing thread.
|
140 |
*
|
141 |
* There is also a function which returns a link to the privatemsg new message
|
142 |
* form with the recipient pre-filled if the user is allowed to.
|
143 |
* privatemsg_get_link().
|
144 |
*/
|
145 |
|
146 |
/**
|
147 |
* @defgroup message_hooks Message hooks
|
148 |
* All message-level hooks look like hook_privatemsg_message_op,
|
149 |
* where op is one of the following:
|
150 |
* - @link hook_privatemsg_message_load load @endlink: Called when a full
|
151 |
* message is loaded similiar to nodeapi_load, new values can be returned and
|
152 |
* will be added to $message, parameter: $message
|
153 |
* - @link hook_privatemsg_message_validate validate @endlink: Validation,
|
154 |
* before the message is sent/saved. Return validation errors as array,
|
155 |
* parameter: $message, $form = FALSE
|
156 |
* - @link hook_privatemsg_message_presave_alter presave_alter @endlink: Last
|
157 |
* changes to $message before the message is saved, parameter: $message
|
158 |
* - @link hook_privatemsg_message_insert insert @endlink: message has been
|
159 |
* saved, $message has been updated with the mid and thread_id,
|
160 |
* parameter: $message
|
161 |
* - @link hook_privatemsg_message_delete delete @endlink: the message is
|
162 |
* going to be deleted, parameter: $message
|
163 |
* - @link hook_privatemsg_message_view_alter view_alter @endlink: the message
|
164 |
* is going to be displayed, parameter: $vars
|
165 |
* - @link hook_privatemsg_message_recipient_change recipient changed @endlink:
|
166 |
* a recipient is added or removed from/to a message.
|
167 |
*
|
168 |
* In hooks with _alter suffix, $message is by reference.
|
169 |
*
|
170 |
* $message is an array, with all the relevant information about the message.
|
171 |
* The information in there can be changed/extended by modules, but looks
|
172 |
* typically like this:
|
173 |
* @code
|
174 |
* array (
|
175 |
* 'mid' => 3517, // message id, identifies a message
|
176 |
* 'author' => 27, // author id
|
177 |
* 'subject' => 'raclebugav', // Message subject
|
178 |
* 'body' => 'bla bla', // Body of the message
|
179 |
* 'timestamp' => 351287003, // unix timestamp, creation time
|
180 |
* 'is_new' => 0, // If the message has been read by the user
|
181 |
* 'thread_id' => 3341, // thread id, this is actually the mid from the first
|
182 |
* message of the thread
|
183 |
* )
|
184 |
* @endcode
|
185 |
*/
|
186 |
|
187 |
/**
|
188 |
* @addtogroup message_hooks
|
189 |
* @{
|
190 |
*/
|
191 |
|
192 |
/**
|
193 |
* Is called when a message is flushed.
|
194 |
*
|
195 |
* The message will be deleted from the database, remove any related data here.
|
196 |
*
|
197 |
* @param $message
|
198 |
* Message array
|
199 |
*/
|
200 |
function hook_privatemsg_message_flush($message) { |
201 |
|
202 |
} |
203 |
|
204 |
/**
|
205 |
* Validate a message before it is sent/saved in the database.
|
206 |
*
|
207 |
* Validation errors can be returned, either as a string or as array when there
|
208 |
* are multiple errors. If the $form flag is set, errors should be reported
|
209 |
* with form_set_error instead.
|
210 |
*
|
211 |
* @todo adapt api return value changes
|
212 |
*
|
213 |
* @param $message
|
214 |
* Message array
|
215 |
*/
|
216 |
function hook_privatemsg_message_validate($message, $form = FALSE) { |
217 |
global $_privatemsg_invalid_recipients; |
218 |
$_privatemsg_invalid_recipients = array(); |
219 |
|
220 |
$errors = array(); |
221 |
|
222 |
foreach ($message->recipients as $recipient) { |
223 |
if ($recipient->name == 'blocked user') { |
224 |
$_privatemsg_invalid_recipients[] = $recipient->uid; |
225 |
$errors[] = t('%name has chosen to not recieve any more messages from you.', array('%name' => privatemsg_recipient_format($recipient, array('plain' => TRUE)))); |
226 |
} |
227 |
} |
228 |
} |
229 |
|
230 |
/**
|
231 |
* Change the message before it is stored.
|
232 |
*
|
233 |
* Alter the message, for example remove recipients that have been detected as
|
234 |
* invalid or forbidden in the validate hook.
|
235 |
*
|
236 |
* @param $message
|
237 |
* Message array
|
238 |
*/
|
239 |
function hook_privatemsg_message_presave_alter(&$message) { |
240 |
// delete recipients which have been marked as invalid
|
241 |
global $_privatemsg_invalid_recipients; |
242 |
foreach ($_privatemsg_invalid_recipients as $invalid) { |
243 |
unset($message->recipients[$invalid]); |
244 |
} |
245 |
} |
246 |
/**
|
247 |
* Act on the $vars before a message is displayed.
|
248 |
*
|
249 |
* This is called in the preprocess hook of the privatemsg-view template.
|
250 |
* The $message data is available in $vars['message'].
|
251 |
*
|
252 |
* @param $var
|
253 |
* Template variables
|
254 |
*/
|
255 |
function hook_privatemsg_message_view_alter(&$vars) { |
256 |
// add a link to each message
|
257 |
$vars['message_links'][] = array('title' => t('My link'), 'href' => '/path/to/my/action/' . $vars['message']['mid']); |
258 |
} |
259 |
|
260 |
/**
|
261 |
* This hook is executed after the message has been saved.
|
262 |
*
|
263 |
* $message is updated with mid and thread id. Use this hook to store data,
|
264 |
* that needs to point to the saved message for example attachments.
|
265 |
*
|
266 |
* @param $message
|
267 |
* Message array
|
268 |
*/
|
269 |
function hook_privatemsg_message_insert($message) { |
270 |
_mymodule_save_data($message->mid);
|
271 |
} |
272 |
|
273 |
/**
|
274 |
* This hook is invoked when a recipient is added to a message.
|
275 |
*
|
276 |
* Since the hook might be invoked hundreds of times during batch or cron, only
|
277 |
* ids are passed and not complete user/message objects.
|
278 |
*
|
279 |
* @param $mid
|
280 |
* Id of the message.
|
281 |
* @param $thread_id
|
282 |
* Id of the thread the message belongs to.
|
283 |
* @param $recipient
|
284 |
* Recipient id, a user id if type is user or hidden.
|
285 |
* @param $type
|
286 |
* Type of the recipient.
|
287 |
* @param $added
|
288 |
* TRUE if the recipient is added, FALSE if he is removed.
|
289 |
*/
|
290 |
function hook_privatemsg_message_recipient_changed($mid, $thread_id, $recipient, $type, $added) { |
291 |
if ($added && ($type == 'user' || $type == 'hidden')) { |
292 |
privatemsg_filter_add_tags(array($thread_id), variable_get('privatemsg_filter_inbox_tag', ''), (object)array('uid' => $recipient)); |
293 |
} |
294 |
} |
295 |
|
296 |
/**
|
297 |
* @}
|
298 |
*/
|
299 |
|
300 |
/**
|
301 |
* @defgroup generic_hooks Generic Hooks
|
302 |
* @{
|
303 |
*
|
304 |
* Some generic hooks that can't be categorized.
|
305 |
*/
|
306 |
|
307 |
/**
|
308 |
* Check if the author can send a message to the recipients.
|
309 |
*
|
310 |
* This can be used to limit who can write whom based on other modules and/or
|
311 |
* settings.
|
312 |
*
|
313 |
* @param $author
|
314 |
* Author of the message to be sent
|
315 |
* @param $recipients
|
316 |
* Recipient of the message
|
317 |
* @param $context
|
318 |
* Additional information. Can contain the thread_id to indicate that this is
|
319 |
* a reply on an existing thread.
|
320 |
* @return
|
321 |
* An indexed array of arrays with the keys recipient ({type}_{key}) and
|
322 |
* message (The reason why the recipient has been blocked).
|
323 |
*/
|
324 |
function hook_privatemsg_block_message($author, $recipients, $context = array()) { |
325 |
$blocked = array(); |
326 |
foreach ($recipients as $recipient_id => $recipient) { |
327 |
// Deny/block if the recipient type is role and the account does not have
|
328 |
// the necessary permission.
|
329 |
if ($recipient->type == 'role' && $recipient->recipient == 2) { |
330 |
$blocked[] = array( |
331 |
'recipient' => $recipient_id, |
332 |
'message' => t('Not allowed to write private messages to the role authenticated user'), |
333 |
); |
334 |
} |
335 |
} |
336 |
return $blocked; |
337 |
} |
338 |
/**
|
339 |
* Add content to the view thread page.
|
340 |
*
|
341 |
* @param $content
|
342 |
* Render-able array, contains the thread object in #thread.
|
343 |
*/
|
344 |
function hook_privatemsg_view_alter($content) { |
345 |
if (privatemsg_user_access('tag private messages')) { |
346 |
$content['tags'] = privatemsg_filter_show_tags($content['#thread']['thread_id'], !empty($_GET['show_tags_form'])); |
347 |
} |
348 |
} |
349 |
|
350 |
/**
|
351 |
* List of possible templates.
|
352 |
*/
|
353 |
function hook_privatemsg_view_template() { |
354 |
|
355 |
} |
356 |
|
357 |
/**
|
358 |
* Expose operations/actions which can be executed on threads.
|
359 |
*
|
360 |
* Return an array of operations to privatemsg, the key of each operation is the
|
361 |
* operation key or name.
|
362 |
*
|
363 |
* @see _privatemsg_action_form()
|
364 |
* @see privatemsg_list_submit()
|
365 |
*/
|
366 |
function hook_privatemsg_thread_operations() { |
367 |
return array( |
368 |
'operation key' => array( |
369 |
'label' => 'Label of the operation. Only use this if the operation |
370 |
should be displayed automatically in the action form',
|
371 |
'callback' => 'privatemsg_thread_change_status', // Function callback that will be executed. |
372 |
'callback arguments' => array('status' => PRIVATEMSG_READ), // Additional arguments to above function |
373 |
'undo callback' => 'privatemsg_thread_change_status', // Provide a function which can "undo" the operation. Optional. |
374 |
'undo callback arguments' => array('status' => PRIVATEMSG_UNREAD), // Additional arguments to above function. |
375 |
), |
376 |
); |
377 |
} |
378 |
|
379 |
/**
|
380 |
* Allows response to a status change.
|
381 |
*
|
382 |
* @param $pmid
|
383 |
* Message id.
|
384 |
* @param $status
|
385 |
* Either PRIVATEMSG_READ or PRIVATEMSG_UNREAD.
|
386 |
* @param $account
|
387 |
* User object, defaults to the current user.
|
388 |
*
|
389 |
* @see privatemsg_message_change_status()
|
390 |
*/
|
391 |
function hook_privatemsg_message_status_changed($pmid, $status, $account) { |
392 |
|
393 |
} |
394 |
|
395 |
/**
|
396 |
* @}
|
397 |
*/
|
398 |
|
399 |
/**
|
400 |
* @defgroup types Types of recipients
|
401 |
*
|
402 |
* It is possible to define other types of recipients than the usual single
|
403 |
* user. These types are defined through a hook and a few callbacks and are
|
404 |
* stored in the {pm_index} table for each recipient entry.
|
405 |
*
|
406 |
* Because of that, only the combination of type and recipient (was uid in older
|
407 |
* versions) defines a unique recipient.
|
408 |
*
|
409 |
* This feature is usually used to define groups of recipients. Privatemsg
|
410 |
* comes with the privatemsg_roles sub-module, which allows to send messages to
|
411 |
* all members of a specific group.
|
412 |
*
|
413 |
* When sending a new message with a recipient type other than user, Privatemsg
|
414 |
* only inserts a single entry for that recipient type. However, when looking
|
415 |
* for messages for a user, Privatemsg only looks for recipient types user and
|
416 |
* hidden. To fill the gap, Privatemsg defines three ways how a non-user
|
417 |
* type is converted to hidden recipient entries.
|
418 |
*
|
419 |
* - For small recipient types (by default <100 recipients, configurable), the
|
420 |
* entries are added directly after saving the original private message.
|
421 |
* - When sending messages through the UI, bigger recipient types are handled
|
422 |
* with batch API.
|
423 |
* - For messages sent by the API, the hidden recipients are generated during
|
424 |
* cron runs.
|
425 |
*
|
426 |
* Once all hidden recipients are added, the original recipient type is marked
|
427 |
* as read so Privatemsg knows that he has been processed.
|
428 |
*
|
429 |
* Privatemsg defines the following types:
|
430 |
*
|
431 |
* - user: This is the default recipient type which is used for a single user.
|
432 |
* - hidden: Used to add internal recipient entries for other recipient types.
|
433 |
* - role: The sub-module privatemsg_roles defines an additional type called
|
434 |
* role. This allows to send messages to all members of a role.
|
435 |
*
|
436 |
* To implement a new type, the following hooks need to be implemented. Note
|
437 |
* that most of these hooks can also be used alone for other functionality than
|
438 |
* defining recipient types.
|
439 |
*
|
440 |
* - hook_privatemsg_recipient_type_info() - Tell Privatemsg about your
|
441 |
* recipient type(s).
|
442 |
* - hook_privatemsg_name_lookup() - Convert a string to an
|
443 |
* recipient object
|
444 |
*
|
445 |
* Additionally, there is also a hook_privatemsg_recipient_type_info_alter() that
|
446 |
* allows to alter recipient type definitions.
|
447 |
*/
|
448 |
|
449 |
/**
|
450 |
* @addtogroup types
|
451 |
* @{
|
452 |
*/
|
453 |
|
454 |
|
455 |
/**
|
456 |
* This hook is used to tell privatemsg about the recipient types defined by a
|
457 |
* module. Each type consists of an array keyed by the internal recipient type
|
458 |
* name and the following keys must be defined.
|
459 |
*
|
460 |
* * name: Translated name of the recipient type.
|
461 |
* * description: A short description of how to send messages to to that
|
462 |
* recipient type. This is displayed below the To: field when sending a
|
463 |
* message.
|
464 |
* * load: A callback function that can load recipients based on their id,
|
465 |
* example: privatemsg_roles_load_multiple().
|
466 |
* * format: Theme function to format the recipient before displaying. Must be
|
467 |
* defined with hook_theme(), example: theme_privatemsg_roles_format().
|
468 |
* * autocomplete: Function callback to return possible autocomplete matches,
|
469 |
* example: privatemsg_roles_autocomplete().
|
470 |
* * generate recipients: Function callback to return user ids which belong to a
|
471 |
* recipient type, example: privatemsg_roles_load_recipients().
|
472 |
* * max: Function callback to return the highest user id of a recipient type,
|
473 |
* example: privatemsg_roles_count_recipients().
|
474 |
* * write access: Optionally define a permission which controls write access
|
475 |
* to that recipient type.
|
476 |
* * write callback: Optionally define a callback function that returns an
|
477 |
* access decision (allow = TRUE, deny = FALSE) for whether the current user
|
478 |
* can write to recipients of the given recipient type.
|
479 |
* * view access: Optionally define a permission which controls if the user is
|
480 |
* able to see the recipient when he is looking at a thread.
|
481 |
* * view callback: Optionally define a callback function that returns an
|
482 |
* access decision (allow = TRUE, deny = FALSE) for whether the current user
|
483 |
* can see recipients of the given recipient type.
|
484 |
*/
|
485 |
function hook_privatemsg_recipient_type_info() { |
486 |
return array( |
487 |
'role' => array( |
488 |
'name' => t('Role'), |
489 |
'description' => t('Enter the name of a role to write a message to all users which have that role. Example: authenticated user.'), |
490 |
'load' => 'privatemsg_roles_load_multiple', |
491 |
'format' => 'privatemsg_roles_format', |
492 |
'autocomplete' => 'privatemsg_roles_autocomplete', |
493 |
'generate recipients' => 'privatemsg_roles_load_recipients', |
494 |
'count' => 'privatemsg_roles_count_recipients', |
495 |
'write callback' => 'privatemsg_roles_write_access', |
496 |
'view access' => 'view roles recipients', |
497 |
), |
498 |
); |
499 |
} |
500 |
|
501 |
/**
|
502 |
* Hook which allows to look up a user object.
|
503 |
*
|
504 |
* You can try to look up a user object based on the information passed to the
|
505 |
* hook. The first hook that successfully looks up a specific string wins.
|
506 |
*
|
507 |
* Therefore, it is important to only return something if you can actually look
|
508 |
* up the string.
|
509 |
*/
|
510 |
function hook_privatemsg_name_lookup($string) { |
511 |
$result = db_query("SELECT *, rid AS recipient FROM {role} WHERE name = '%s'", trim($string)); |
512 |
if ($role = db_fetch_object($result)) { |
513 |
$role->type = 'role'; |
514 |
return $role; |
515 |
} |
516 |
} |
517 |
|
518 |
/**
|
519 |
* Allows to alter the defined recipient types.
|
520 |
*
|
521 |
* @param $types
|
522 |
* Array with the recipient types.
|
523 |
*
|
524 |
* @see hook_privatemsg_recipient_type_info()
|
525 |
*/
|
526 |
function hook_privatemsg_recipient_type_info_alter(&$types) { |
527 |
|
528 |
} |
529 |
|
530 |
/**
|
531 |
* Allows to alter the found autocomplete suggestions.
|
532 |
*
|
533 |
* @param $matches
|
534 |
* Array of matching recipient objects.
|
535 |
* @param $names
|
536 |
* Array of names that are already in the list.
|
537 |
* @param $fragment
|
538 |
* Fragment that is currently searched for.
|
539 |
*/
|
540 |
function hook_privatemsg_autocomplete_alter(&$matches, $names, $fragment) { |
541 |
// Remove all types other than user if accessed through
|
542 |
// messages/user/autocomplete.
|
543 |
if (arg(1) == 'user') { |
544 |
foreach ($matches as $id => $match) { |
545 |
if ($match->type != 'user') { |
546 |
unset($matches[$id]); |
547 |
} |
548 |
} |
549 |
} |
550 |
} |
551 |
|
552 |
/**
|
553 |
* Allows to alter found recipient types for a given string.
|
554 |
*
|
555 |
* @param $matches
|
556 |
* Array of matching recipient objects.
|
557 |
* @param $string
|
558 |
* String representation of the recipient.
|
559 |
*/
|
560 |
function hook_privatemsg_name_lookup_matches(&$matches, $string) { |
561 |
|
562 |
} |
563 |
|
564 |
/**
|
565 |
* Allows response to a successful operation.
|
566 |
*
|
567 |
* @param $operation
|
568 |
* The operation that was executed.
|
569 |
* @param $threads
|
570 |
* An array which contains the thread ids on which the operation
|
571 |
* has been executed.
|
572 |
* @param $account
|
573 |
* An user account object if an other user than the currently logged in is
|
574 |
* affected.
|
575 |
*
|
576 |
* @see privatemsg_operation_execute()
|
577 |
* @see hook_privatemsg_thread_operations()
|
578 |
*/
|
579 |
function hook_privatemsg_operation_executed($operation, $threads, $account = NULL) { |
580 |
|
581 |
} |
582 |
|
583 |
/**
|
584 |
* @}
|
585 |
*/
|