privatemsg.api.php

  1. 1 privatemsg.api.php
  2. 7-1 privatemsg.api.php
  3. 7-2 privatemsg.api.php
  4. 6-2 privatemsg.api.php

Privatemsg API Documentation

File

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

Functions

Namesort descending Description
hook_privatemsg_autocomplete_alter Allows to alter the found autocomplete suggestions.
hook_privatemsg_block_message Check if the author can send a message to the recipients.
hook_privatemsg_header_info Declare headers for message listings.
hook_privatemsg_header_info_alter Alter the defined header structure.
hook_privatemsg_message_flush Is called when a message is flushed.
hook_privatemsg_message_insert This hook is executed after the message has been saved.
hook_privatemsg_message_presave_alter Change the message before it is stored.
hook_privatemsg_message_recipient_changed This hook is invoked when a recipient is added to a message.
hook_privatemsg_message_status_changed Allows response to a status change.
hook_privatemsg_message_status_deleted Allows response to a deleted change.
hook_privatemsg_message_validate Validate a message before it is sent/saved in the database.
hook_privatemsg_message_view_alter Act on the $vars before a message is displayed.
hook_privatemsg_name_lookup Hook which allows to look up a user object.
hook_privatemsg_name_lookup_matches Allows to alter found recipient types for a given string.
hook_privatemsg_operation_executed Allows response to a successful operation.
hook_privatemsg_recipient_type_info This hook is used to tell privatemsg about the recipient types defined by a module. Each type consists of an array keyed by the internal recipient type name and the following keys must be defined.
hook_privatemsg_recipient_type_info_alter Allows to alter the defined recipient types.
hook_privatemsg_thread_operations Expose operations/actions which can be executed on threads.
hook_privatemsg_view_alter Add content to the view thread page.
hook_privatemsg_view_template List of possible templates.
hook_query_privatemsg_autocomplete_alter Query to search for autocomplete usernames.
hook_query_privatemsg_deleted_alter Alter the query that loads deleted messages to flush them.
hook_query_privatemsg_messages_alter Query definition to load messages of one or multiple threads.
hook_query_privatemsg_participants_alter Alter the query that loads the participants of a thread.
hook_query_privatemsg_sql_list_alter Display a list of threads.
hook_query_privatemsg_unread_count_alter Loads all unread messages of a user (only the count query is used).