pm_email_notify.module

Tracking 7.x-2.x branch
  1. drupal
    1. 7 contributions/privatemsg/pm_email_notify/pm_email_notify.module

Notifies users about new Private Messages via Email.

Functions & methods

NameDescription
pm_email_notify_admin_settings_update_stringsForm submit callback to update the translation string sources.
pm_email_notify_form_privatemsg_admin_settings_alterImplements hook_form_FORM_ID_alter().
pm_email_notify_form_user_profile_form_alterImplements hook_form_FORM_ID_alter().
pm_email_notify_i18n_string_infoImplements hook_i18n_string_info().
pm_email_notify_i18n_string_listRefresh callback to update the string translation sources.
pm_email_notify_mailImplements hook_mail().
pm_email_notify_permissionImplements hook_perm().
pm_email_notify_privatemsg_message_insertImplements hook_privatemsg_message_insert().
pm_email_notify_privatemsg_message_recipient_changedImplements hook_privatemsg_message_recipient_changed().
pm_email_notify_send_mailSend a pm notification email to a recipient.
pm_email_notify_textReturn (if enabled, translated) body/subject strings.
pm_email_notify_user_deleteImplements hook_user_delete().
pm_email_notify_user_updateImplements hook_user_update().
_pm_email_notify_only_userCheck if a user should only be notified when addressed directly.
_pm_email_notify_send_checkRetrieve notification setting of a user and check if they should receive an e-mail notification for a message.
_pm_email_notify_source_textGet the default text for body and subject texts.
_pm_email_notify_user_levelRetrieve notification level of a user.

Constants

NameDescription
PM_EMAIL_NOTIFY_LEVEL_ALLEnable e-mail notifications for all messages.
PM_EMAIL_NOTIFY_LEVEL_DEFAULTEnable e-mail notifications and use the global default.
PM_EMAIL_NOTIFY_LEVEL_DISABLEDDisable e-mail notifications.
PM_EMAIL_NOTIFY_LEVEL_THREADEnable e-mail notifications only for new threads.
PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCEEnable e-mail notifications only once until a user visits a threads.

File

View source
  1. <?php
  2. /**
  3. * @file
  4. * Notifies users about new Private Messages via Email.
  5. */
  6. /**
  7. * Disable e-mail notifications.
  8. */
  9. define('PM_EMAIL_NOTIFY_LEVEL_DISABLED', 0);
  10. /**
  11. * Enable e-mail notifications only for new threads.
  12. */
  13. define('PM_EMAIL_NOTIFY_LEVEL_THREAD', 4);
  14. /**
  15. * Enable e-mail notifications only once until a user visits a threads.
  16. */
  17. define('PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE', 8);
  18. /**
  19. * Enable e-mail notifications for all messages.
  20. */
  21. define('PM_EMAIL_NOTIFY_LEVEL_ALL', 12);
  22. /**
  23. * Enable e-mail notifications and use the global default.
  24. *
  25. * A negative value will be ignored by the settings API.
  26. */
  27. define('PM_EMAIL_NOTIFY_LEVEL_DEFAULT', -1);
  28. /**
  29. * Implements hook_perm().
  30. */
  31. function pm_email_notify_permission() {
  32. return array(
  33. 'set privatemsg e-mail notification level' => array(
  34. 'title' => t('Set Privatemsg E-Mail notification level'),
  35. 'description' => t('Users with this permission may override the default e-mail notification level. Even without this permission, they can still opt-out (but not opt-in if disabled by default) of email notifications.'),
  36. ),
  37. 'change privatemsg e-mail notification for indirect messages' => array(
  38. 'title' => t('Change privatemsg e-mail notification for indirect messages'),
  39. 'description' => t('Users with this permission may override the default setting.'),
  40. )
  41. );
  42. }
  43. /**
  44. * Retrieve notification level of a user.
  45. *
  46. * This function retrieves user's pm notification level from database,
  47. * if user preference doesn't exist - it uses default value instead.
  48. *
  49. * @param $uid
  50. * User ID.
  51. *
  52. * @return
  53. * Returns a PM_EMAIL_NOTIFY_LEVEL_* constant indicating the notification
  54. * level of the requested user.
  55. */
  56. function _pm_email_notify_user_level($uid = NULL) {
  57. // Either check the setting for this user or the global default.
  58. if ($uid) {
  59. $keys = array(
  60. 'user' => array($uid),
  61. 'global' => array(0),
  62. );
  63. } else {
  64. $keys = array(
  65. 'global' => array(0),
  66. );
  67. }
  68. return privatemsg_get_setting('email_notify_level', $keys, PM_EMAIL_NOTIFY_LEVEL_ALL);
  69. }
  70. /**
  71. * Check if a user should only be notified when addressed directly.
  72. *
  73. * @param $uid
  74. * User ID.
  75. *
  76. * @param
  77. * TRUE if notifications should only be sent for directly addressed
  78. * recipients.
  79. */
  80. function _pm_email_notify_only_user($uid) {
  81. // Either check the setting for this user or the global default.
  82. $keys = array(
  83. 'user' => array($uid),
  84. 'global' => array(0),
  85. );
  86. return privatemsg_get_setting('email_notify_only_user', $keys);
  87. }
  88. /**
  89. * Retrieve notification setting of a user and check if they should receive
  90. * an e-mail notification for a message.
  91. *
  92. * Note: This function tries to return as quickly as possible, to avoid extra
  93. * processing in batch executions.
  94. *
  95. * @param $uid
  96. * User uid
  97. * @param $message
  98. * Message.
  99. */
  100. function _pm_email_notify_send_check($uid, $message) {
  101. static $notifications = array();
  102. $mid = $message->mid;
  103. $thread_id = $message->thread_id;
  104. $level = _pm_email_notify_user_level($uid);
  105. // If the user has notifications disabled, we can skip the rest.
  106. if ($level == PM_EMAIL_NOTIFY_LEVEL_DISABLED) {
  107. return FALSE;
  108. }
  109. // If the user has all notifications enabled, we can skip the rest.
  110. if ($level == PM_EMAIL_NOTIFY_LEVEL_ALL) {
  111. return TRUE;
  112. }
  113. // Cache the result set in case this method is executed in batched operation
  114. // which will perform many unnecessary repeated processing.
  115. if (!isset($notifications[$uid][$mid])) {
  116. // Prime the setting to false.
  117. $notifications[$uid][$mid] = FALSE;
  118. if ($level == PM_EMAIL_NOTIFY_LEVEL_THREAD) {
  119. // Is this the origin of a thread?
  120. $notifications[$uid][$mid] = ($mid == $thread_id);
  121. }
  122. elseif ($level == PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE) {
  123. // If this is the first message of a thread, always send a notification.
  124. if ($mid == $thread_id) {
  125. $notifications[$uid][$mid] = TRUE;
  126. } else {
  127. // Check if this user has more than a single unread message
  128. // in that thread. If yes, they already got a notification.
  129. // They always have at least one unread message because they just
  130. // received one.
  131. $unread_count = db_query("SELECT COUNT(*) FROM {pm_index} WHERE thread_id = :thread_id AND is_new = 1 AND recipient = :recipient AND type IN ('user', 'hidden')", array(':thread_id' => $thread_id, ':recipient' => $uid))->fetchField();
  132. $notifications[$uid][$mid] = $unread_count == 1;
  133. }
  134. }
  135. }
  136. return $notifications[$uid][$mid];
  137. }
  138. /**
  139. * Implements hook_privatemsg_message_insert().
  140. */
  141. function pm_email_notify_privatemsg_message_insert($message) {
  142. foreach ($message->recipients as $recipient) {
  143. pm_email_notify_send_mail($recipient, $message);
  144. }
  145. }
  146. /**
  147. * Implements hook_privatemsg_message_recipient_changed().
  148. *
  149. * Notifies users who were added to a message about new Private Messages
  150. * via Email.
  151. */
  152. function pm_email_notify_privatemsg_message_recipient_changed($mid, $thread_id, $recipient_id, $type, $added) {
  153. $types = array('user');
  154. // Only send mail if the recipient was added.
  155. if ($added) {
  156. if ($message = privatemsg_message_load($mid)) {
  157. // Check if we should send an email to 'hidden' recipients.
  158. if (!_pm_email_notify_only_user($recipient_id)) {
  159. $types[] = 'hidden';
  160. }
  161. if (in_array($type, $types) && _pm_email_notify_send_check($recipient_id, $message) && ($recipient = user_load($recipient_id))) {
  162. pm_email_notify_send_mail($recipient, $message);
  163. }
  164. }
  165. }
  166. }
  167. /**
  168. * Send a pm notification email to a recipient.
  169. */
  170. function pm_email_notify_send_mail($recipient, $message) {
  171. // check if recipient enabled email notifications
  172. if (isset($recipient->uid) && !empty($recipient->mail) && _pm_email_notify_send_check($recipient->uid, $message)) {
  173. // send them a new pm notification email if they did
  174. $params['recipient'] = $recipient;
  175. $params['message'] = $message;
  176. // token replace for email from address
  177. $data = array(
  178. 'privatemsg_message' => $params['message'],
  179. 'privatemsg_recipient' => $params['recipient'],
  180. );
  181. $options = array(
  182. 'language' => user_preferred_language($params['recipient']),
  183. // Don't sanitize output since this is used in an email, not a browser.
  184. 'sanitize' => FALSE,
  185. // Custom token to avoid custom token handling.
  186. 'privatemsg-display-invalid' => FALSE,
  187. );
  188. $from = trim(token_replace(variable_get('pm_email_notify_from', ''), $data, $options));
  189. drupal_mail('pm_email_notify', 'notice', $recipient->mail, user_preferred_language($recipient), $params, !empty($from) ? $from : NULL);
  190. }
  191. }
  192. /**
  193. * Get the default text for body and subject texts.
  194. *
  195. * @param $key
  196. * Defines with string to return, either subject or body.
  197. *
  198. * @return
  199. * The default text for the given key.
  200. */
  201. function _pm_email_notify_source_text($key) {
  202. $text = variable_get('pm_email_notify_' . $key, FALSE);
  203. if (empty($text)) {
  204. switch ($key) {
  205. case 'subject':
  206. $text = 'New private message at [site:name].';
  207. break;
  208. case 'body':
  209. $text = "Hi [privatemsg_message:recipient],\n\nThis is an automatic reminder from the site [site:name]. You have received a new private message from [privatemsg_message:author].\n\nTo read your message, follow this link:\n[privatemsg_message:url]\n\nIf you don't want to receive these emails again, change your preferences here:\n[privatemsg_message:recipient:edit-url]";
  210. break;
  211. }
  212. }
  213. return $text;
  214. }
  215. /**
  216. * Return (if enabled, translated) body/subject strings.
  217. *
  218. * @param $key
  219. * Defines with string to return, either subject or body.
  220. * @param $language
  221. * Optionally define into which language should be translated. Defaults to the
  222. * active language.
  223. * @return
  224. * Either the translated text or the source, depending on the $translate
  225. * flag.
  226. */
  227. function pm_email_notify_text($key, $language = NULL) {
  228. $text = _pm_email_notify_source_text($key);
  229. $function = 'i18n_string_translate';
  230. if (function_exists($function)) {
  231. $translated = $function('pm_email_notify:mail:mail:' . $key, $text, array('langcode' => isset($language) ? $language->language : NULL));
  232. return $translated;
  233. }
  234. return $text;
  235. }
  236. /**
  237. * Implements hook_mail().
  238. */
  239. function pm_email_notify_mail($key, &$message, $params) {
  240. switch ($key) {
  241. case 'notice':
  242. $data = array(
  243. 'privatemsg_message' => $params['message'],
  244. 'privatemsg_recipient' => $params['recipient'],
  245. );
  246. $options = array(
  247. 'language' => user_preferred_language($params['recipient']),
  248. // Don't sanitize output since this is used in an email, not a browser.
  249. 'sanitize' => FALSE,
  250. // Custom token to avoid custom token handling.
  251. 'privatemsg-display-invalid' => FALSE,
  252. );
  253. $message['subject'] = trim(token_replace(pm_email_notify_text('subject', $options['language']), $data, $options));
  254. $message['body'][] = trim(token_replace(pm_email_notify_text('body', $options['language']), $data, $options));
  255. break;
  256. }
  257. }
  258. /**
  259. * Implements hook_form_FORM_ID_alter().
  260. */
  261. function pm_email_notify_form_user_profile_form_alter(&$form, &$form_state) {
  262. if ($form['#user_category'] == 'account' && privatemsg_user_access('read privatemsg')) {
  263. if (privatemsg_user_access('set privatemsg e-mail notification level')) {
  264. $form['privatemsg']['pm_email_notify_level'] = array(
  265. '#type' => 'radios',
  266. '#title' => t('Send me an e-mail notification...'),
  267. '#options' => array(
  268. PM_EMAIL_NOTIFY_LEVEL_DISABLED => t('Never.'),
  269. PM_EMAIL_NOTIFY_LEVEL_THREAD => t('Only for a new conversation'),
  270. PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE => t("Only once for a conversation until I've read the messages"),
  271. PM_EMAIL_NOTIFY_LEVEL_ALL => t('Every time I receive a message'),
  272. ),
  273. '#default_value' => _pm_email_notify_user_level($form['#user']->uid),
  274. );
  275. }
  276. else {
  277. // If the user does not have permissions to customize the notification
  278. // level, allow him to opt out of email notifications if they are not
  279. // disabled by default.
  280. $is_enabled = _pm_email_notify_user_level();
  281. $form['privatemsg']['pm_email_notify_level'] = array(
  282. '#type' => 'checkbox',
  283. '#title' => t('Receive email notification for incoming private messages'),
  284. '#return_value' => PM_EMAIL_NOTIFY_LEVEL_DEFAULT,
  285. '#default_value' => $is_enabled ? PM_EMAIL_NOTIFY_LEVEL_DEFAULT : PM_EMAIL_NOTIFY_LEVEL_DISABLED,
  286. '#access' => (bool)$is_enabled,
  287. );
  288. }
  289. $form['privatemsg']['pm_email_only_user'] = array(
  290. '#type' => 'checkbox',
  291. '#title' => t("Don't send me e-mail notifications for mass messages."),
  292. '#default_value' => _pm_email_notify_only_user($form['#user']->uid),
  293. '#access' => privatemsg_user_access('change privatemsg e-mail notification for indirect messages'),
  294. );
  295. }
  296. }
  297. /**
  298. * Implements hook_user_update().
  299. */
  300. function pm_email_notify_user_update(&$edit, $account, $category) {
  301. if (isset($edit['pm_email_notify_level'])) {
  302. privatemsg_set_setting('user', $account->uid, 'email_notify_level', $edit['pm_email_notify_level']);
  303. unset($edit['pm_email_notify_level']);
  304. }
  305. if (isset($edit['pm_email_only_user'])) {
  306. privatemsg_set_setting('user', $account->uid, 'email_notify_only_user', $edit['pm_email_only_user']);
  307. unset($edit['pm_email_only_user']);
  308. }
  309. }
  310. /**
  311. * Implements hook_user_delete().
  312. */
  313. function pm_email_notify_user_delete($account) {
  314. privatemsg_del_setting('user', $account->uid, 'email_notify_level');
  315. privatemsg_del_setting('user', $account->uid, 'email_notify_only_user');
  316. }
  317. /**
  318. * Implements hook_form_FORM_ID_alter().
  319. */
  320. function pm_email_notify_form_privatemsg_admin_settings_alter(&$form, &$form_state) {
  321. $form['pm_email_notify'] = array(
  322. '#type' => 'fieldset',
  323. '#title' => t('E-mail notify'),
  324. '#group' => 'settings',
  325. '#weight' => 22,
  326. );
  327. $form['pm_email_notify']['privatemsg_setting_email_notify_level'] = array(
  328. '#type' => 'radios',
  329. '#title' => t('Default e-mail notification level'),
  330. '#options' => array(
  331. PM_EMAIL_NOTIFY_LEVEL_DISABLED => t('Never send a notification'),
  332. PM_EMAIL_NOTIFY_LEVEL_THREAD => t('Only send a notification when a new discussion thread is created'),
  333. PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE => t("Only send a notification when the user has not already received a notification since he last viewed a discussion thread."),
  334. PM_EMAIL_NOTIFY_LEVEL_ALL => t('Always send a notification'),
  335. ),
  336. '#default_value' => variable_get('privatemsg_setting_email_notify_level', PM_EMAIL_NOTIFY_LEVEL_ALL),
  337. '#description' => t('Choose when e-mail notifications will be sent by the system. Users with the appropriate permission may override this setting on the account edit page.'),
  338. '#weight' => 0,
  339. );
  340. $form['pm_email_notify']['privatemsg_setting_email_notify_only_user'] = array(
  341. '#type' => 'checkbox',
  342. '#title' => t('Only send e-mail notifications to individual users who are addressed directly'),
  343. '#default_value' => variable_get('privatemsg_setting_email_only_user', FALSE),
  344. '#weight' => 1,
  345. );
  346. $form['pm_email_notify']['pm_email_notify_desc'] = array(
  347. '#type' => 'item',
  348. '#title' => t('Customize the email messages sent to users upon receipt of a new private message.'),
  349. '#weight' => 2,
  350. );
  351. $form['pm_email_notify']['pm_email_notify_from'] = array(
  352. '#type' => 'textfield',
  353. '#title' => t('From e-mail address for notifications'),
  354. '#default_value' => variable_get('pm_email_notify_from',''),
  355. '#weight' => 3,
  356. '#description' => t('This is the e-mail address that notifications will come from. Leave blank to use the site default.'),
  357. );
  358. $form['pm_email_notify']['pm_email_notify_subject'] = array(
  359. '#type' => 'textfield',
  360. '#title' => t('Subject of notification messages'),
  361. '#default_value' => variable_get('pm_email_notify_subject', _pm_email_notify_source_text('subject')),
  362. '#weight' => 4,
  363. );
  364. $form['pm_email_notify']['pm_email_notify_body'] = array(
  365. '#type' => 'textarea',
  366. '#title' => t('Body of notification messages'),
  367. '#default_value' => variable_get('pm_email_notify_body', _pm_email_notify_source_text('body')),
  368. '#weight' => 5,
  369. );
  370. if (module_exists('token')) {
  371. $form['pm_email_notify']['token'] = array(
  372. '#type' => 'fieldset',
  373. '#title' => t('Token browser'),
  374. '#weight' => -1,
  375. '#weight' => 6,
  376. );
  377. $form['pm_email_notify']['token']['browser'] = array(
  378. '#theme' => 'token_tree',
  379. '#token_types' => array('privatemsg_message'),
  380. );
  381. }
  382. else {
  383. $form['pm_email_notify']['tokens'] = array(
  384. '#type' => 'item',
  385. '#value' => t('Available variables are: !author, !author_uid, !pm_subject, !pm_body, !thread, !site, !login_url, !uri, !uri_brief, !message (URL) and !settings (URL).'),
  386. '#weight' => 6,
  387. );
  388. }
  389. if (module_exists('i18n_string')) {
  390. $form['#submit'][] = 'pm_email_notify_admin_settings_update_strings';
  391. }
  392. }
  393. /**
  394. * Form submit callback to update the translation string sources.
  395. */
  396. function pm_email_notify_admin_settings_update_strings($form, &$form_state) {
  397. i18n_string_update('pm_email_notify:mail:mail:subject', $form_state['values']['pm_email_notify_subject']);
  398. i18n_string_update('pm_email_notify:mail:mail:body', $form_state['values']['pm_email_notify_body']);
  399. }
  400. /**
  401. * Implements hook_i18n_string_info().
  402. */
  403. function pm_email_notify_i18n_string_info() {
  404. return array(
  405. 'pm_email_notify' => array(
  406. 'title' => t('Privatemsg Email Notification'),
  407. 'format' => FALSE,
  408. 'list' => TRUE,
  409. ),
  410. );
  411. }
  412. /**
  413. * Refresh callback to update the string translation sources.
  414. */
  415. function pm_email_notify_i18n_string_list($group) {
  416. if ($group == 'pm_email_notify' || $group == 'all') {
  417. $strings['pm_email_notify']['mail']['mail']['subject'] = _pm_email_notify_source_text('subject');
  418. $strings['pm_email_notify']['mail']['mail']['body'] = _pm_email_notify_source_text('body');
  419. return $strings;
  420. }
  421. }