Projet

Général

Profil

Paste
Télécharger (18,1 ko) Statistiques
| Branche: | Révision:

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
 */