pm_email_notify.module

  1. 1 pm_email_notify/pm_email_notify.module
  2. 7-1 pm_email_notify/pm_email_notify.module
  3. 7-2 pm_email_notify/pm_email_notify.module
  4. 6-2 pm_email_notify/pm_email_notify.module

Notifies users about new Private Messages via Email.

File

pm_email_notify/pm_email_notify.module
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. * Checks 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. * @return bool
  81. * The effective setting for this user.
  82. */
  83. function _pm_email_notify_only_user($uid) {
  84. // Either check the setting for this user or the global default.
  85. $keys = array(
  86. 'user' => array($uid),
  87. 'global' => array(0),
  88. );
  89. return privatemsg_get_setting('email_notify_only_user', $keys);
  90. }
  91. /**
  92. * Checks if a message author wants his email address as a sender.
  93. *
  94. * @param $uid
  95. * The author's user ID.
  96. *
  97. * @return bool
  98. * Whether or not to use the author's email address.
  99. */
  100. function _pm_email_notify_show_sender($uid) {
  101. // Either check the setting for this user or the global default.
  102. $keys = array(
  103. 'user' => array($uid),
  104. 'global' => array(0),
  105. );
  106. return privatemsg_get_setting('show_sender_mail', $keys);
  107. }
  108. /**
  109. * Retrieve notification setting of a user and check if they should receive
  110. * an e-mail notification for a message.
  111. *
  112. * Note: This function tries to return as quickly as possible, to avoid extra
  113. * processing in batch executions.
  114. *
  115. * @param $uid
  116. * User uid
  117. * @param $message
  118. * Message.
  119. *
  120. * @return bool
  121. * Whether or not to notify the user in question.
  122. */
  123. function _pm_email_notify_send_check($uid, $message) {
  124. static $notifications = array();
  125. $mid = $message->mid;
  126. $thread_id = $message->thread_id;
  127. $level = _pm_email_notify_user_level($uid);
  128. // If the user has notifications disabled, we can skip the rest.
  129. if ($level == PM_EMAIL_NOTIFY_LEVEL_DISABLED) {
  130. return FALSE;
  131. }
  132. // If the user has all notifications enabled, we can skip the rest.
  133. if ($level == PM_EMAIL_NOTIFY_LEVEL_ALL) {
  134. return TRUE;
  135. }
  136. // Cache the result set in case this method is executed in batched operation
  137. // which will perform many unnecessary repeated processing.
  138. if (!isset($notifications[$uid][$mid])) {
  139. // Prime the setting to false.
  140. $notifications[$uid][$mid] = FALSE;
  141. if ($level == PM_EMAIL_NOTIFY_LEVEL_THREAD) {
  142. // Is this the origin of a thread?
  143. $notifications[$uid][$mid] = ($mid == $thread_id);
  144. }
  145. elseif ($level == PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE) {
  146. // If this is the first message of a thread, always send a notification.
  147. if ($mid == $thread_id) {
  148. $notifications[$uid][$mid] = TRUE;
  149. } else {
  150. // Check if this user has more than a single unread message
  151. // in that thread. If yes, they already got a notification.
  152. // They always have at least one unread message because they just
  153. // received one.
  154. $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();
  155. $notifications[$uid][$mid] = $unread_count == 1;
  156. }
  157. }
  158. }
  159. return $notifications[$uid][$mid];
  160. }
  161. /**
  162. * Implements hook_privatemsg_message_insert().
  163. */
  164. function pm_email_notify_privatemsg_message_insert($message) {
  165. foreach ($message->recipients as $recipient) {
  166. pm_email_notify_send_mail($recipient, $message);
  167. }
  168. }
  169. /**
  170. * Implements hook_privatemsg_message_recipient_changed().
  171. *
  172. * Notifies users who were added to a message about new Private Messages
  173. * via Email.
  174. */
  175. function pm_email_notify_privatemsg_message_recipient_changed($mid, $thread_id, $recipient_id, $type, $added) {
  176. $types = array('user');
  177. // Only send mail if the recipient was added.
  178. if ($added) {
  179. if ($message = privatemsg_message_load($mid)) {
  180. // Check if we should send an email to 'hidden' recipients.
  181. if (!_pm_email_notify_only_user($recipient_id)) {
  182. $types[] = 'hidden';
  183. }
  184. if (in_array($type, $types) && _pm_email_notify_send_check($recipient_id, $message) && ($recipient = user_load($recipient_id))) {
  185. pm_email_notify_send_mail($recipient, $message);
  186. }
  187. }
  188. }
  189. }
  190. /**
  191. * Send a pm notification email to a recipient.
  192. */
  193. function pm_email_notify_send_mail($recipient, $message) {
  194. // Check if the recipient enabled email notifications.
  195. if (isset($recipient->uid) && !empty($recipient->mail) && _pm_email_notify_send_check($recipient->uid, $message)) {
  196. // Send them a new pm notification email if they did.
  197. $params['recipient'] = $recipient;
  198. $params['message'] = $message;
  199. if (_pm_email_notify_show_sender($message->author->uid)) {
  200. // User author's email as a sender.
  201. $from = $message->author->mail;
  202. }
  203. else {
  204. // Token replacements for email from address.
  205. $data = array(
  206. 'privatemsg_message' => $params['message'],
  207. 'privatemsg_recipient' => $params['recipient'],
  208. );
  209. $options = array(
  210. 'language' => user_preferred_language($params['recipient']),
  211. // Don't sanitize output since this is used in an email, not a browser.
  212. 'sanitize' => FALSE,
  213. // Custom token to avoid custom token handling.
  214. 'privatemsg-display-invalid' => FALSE,
  215. );
  216. $from = trim(token_replace(variable_get('pm_email_notify_from', ''), $data, $options));
  217. }
  218. drupal_mail('pm_email_notify', 'notice', $recipient->mail, user_preferred_language($recipient), $params, !empty($from) ? $from : NULL);
  219. }
  220. }
  221. /**
  222. * Retrieves the default text for body and subject texts.
  223. *
  224. * @param $key
  225. * Defines with string to return, either subject or body.
  226. *
  227. * @return
  228. * The default text for the given key.
  229. */
  230. function _pm_email_notify_source_text($key) {
  231. $text = variable_get('pm_email_notify_' . $key, FALSE);
  232. if (empty($text)) {
  233. switch ($key) {
  234. case 'subject':
  235. $text = 'New private message at [site:name].';
  236. break;
  237. case 'body':
  238. $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]";
  239. break;
  240. }
  241. }
  242. return $text;
  243. }
  244. /**
  245. * Returns body or subject strings.
  246. *
  247. * @param $key
  248. * Defines which string to return, either subject or body.
  249. * @param $language
  250. * Optionally define the language to translate into. Defaults to the
  251. * active language.
  252. * @return
  253. * The translated text.
  254. */
  255. function pm_email_notify_text($key, $language = NULL) {
  256. $text = _pm_email_notify_source_text($key);
  257. $function = 'i18n_string_translate';
  258. if (function_exists($function)) {
  259. $translated = $function('pm_email_notify:mail:mail:' . $key, $text, array('langcode' => isset($language) ? $language->language : NULL));
  260. return $translated;
  261. }
  262. return $text;
  263. }
  264. /**
  265. * Implements hook_mail().
  266. */
  267. function pm_email_notify_mail($key, &$message, $params) {
  268. switch ($key) {
  269. case 'notice':
  270. $data = array(
  271. 'privatemsg_message' => $params['message'],
  272. 'privatemsg_recipient' => $params['recipient'],
  273. );
  274. $options = array(
  275. 'language' => user_preferred_language($params['recipient']),
  276. // Don't sanitize output since this is used in an email, not a browser.
  277. 'sanitize' => FALSE,
  278. // Custom token to avoid custom token handling.
  279. 'privatemsg-display-invalid' => FALSE,
  280. );
  281. $message['subject'] = trim(token_replace(pm_email_notify_text('subject', $options['language']), $data, $options));
  282. $message['body'][] = trim(token_replace(pm_email_notify_text('body', $options['language']), $data, $options));
  283. break;
  284. }
  285. }
  286. /**
  287. * Implements hook_form_FORM_ID_alter().
  288. */
  289. function pm_email_notify_form_user_profile_form_alter(&$form, &$form_state) {
  290. if ($form['#user_category'] == 'account') {
  291. if (privatemsg_user_access('write privatemsg')) {
  292. $form['privatemsg']['pm_show_sender_mail'] = array(
  293. '#type' => 'checkbox',
  294. '#title' => t('Show my email address'),
  295. '#description' => t('Use my private email address as a sender for notification mails to users I have sent private messages to. If unchecked, the notification will be sent by a generic account.'),
  296. '#default_value' => _pm_email_notify_show_sender($form['#user']->uid),
  297. '#access' => privatemsg_user_access('write privatemsg'),
  298. );
  299. }
  300. if (privatemsg_user_access('read privatemsg')) {
  301. if (privatemsg_user_access('set privatemsg e-mail notification level')) {
  302. $form['privatemsg']['pm_email_notify_level'] = array(
  303. '#type' => 'radios',
  304. '#title' => t('Send me an e-mail notification...'),
  305. '#options' => array(
  306. PM_EMAIL_NOTIFY_LEVEL_DISABLED => t('Never.'),
  307. PM_EMAIL_NOTIFY_LEVEL_THREAD => t('Only for a new conversation'),
  308. PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE => t("Only once for a conversation until I've read the messages"),
  309. PM_EMAIL_NOTIFY_LEVEL_ALL => t('Every time I receive a message'),
  310. ),
  311. '#default_value' => _pm_email_notify_user_level($form['#user']->uid),
  312. );
  313. }
  314. else {
  315. // If the user does not have permissions to customize the notification
  316. // level, allow him to opt out of email notifications if they are not
  317. // disabled by default.
  318. $is_enabled = _pm_email_notify_user_level();
  319. $form['privatemsg']['pm_email_notify_level'] = array(
  320. '#type' => 'checkbox',
  321. '#title' => t('Receive email notification for incoming private messages'),
  322. '#return_value' => PM_EMAIL_NOTIFY_LEVEL_DEFAULT,
  323. '#default_value' => $is_enabled ? PM_EMAIL_NOTIFY_LEVEL_DEFAULT : PM_EMAIL_NOTIFY_LEVEL_DISABLED,
  324. '#access' => (bool)$is_enabled,
  325. );
  326. }
  327. $form['privatemsg']['pm_email_only_user'] = array(
  328. '#type' => 'checkbox',
  329. '#title' => t("Don't send me e-mail notifications for mass messages."),
  330. '#default_value' => _pm_email_notify_only_user($form['#user']->uid),
  331. '#access' => privatemsg_user_access('change privatemsg e-mail notification for indirect messages'),
  332. );
  333. }
  334. }
  335. }
  336. /**
  337. * Implements hook_user_update().
  338. */
  339. function pm_email_notify_user_update(&$edit, $account, $category) {
  340. if (isset($edit['pm_email_notify_level'])) {
  341. privatemsg_set_setting('user', $account->uid, 'email_notify_level', $edit['pm_email_notify_level']);
  342. unset($edit['pm_email_notify_level']);
  343. }
  344. if (isset($edit['pm_email_only_user'])) {
  345. privatemsg_set_setting('user', $account->uid, 'email_notify_only_user', $edit['pm_email_only_user']);
  346. unset($edit['pm_email_only_user']);
  347. }
  348. if (isset($edit['pm_show_sender_mail'])) {
  349. privatemsg_set_setting('user', $account->uid, 'show_sender_mail', $edit['pm_show_sender_mail']);
  350. unset($edit['pm_show_sender_mail']);
  351. }
  352. }
  353. /**
  354. * Implements hook_user_delete().
  355. */
  356. function pm_email_notify_user_delete($account) {
  357. privatemsg_del_setting('user', $account->uid, 'email_notify_level');
  358. privatemsg_del_setting('user', $account->uid, 'email_notify_only_user');
  359. privatemsg_del_setting('user', $account->uid, 'show_sender_mail');
  360. }
  361. /**
  362. * Implements hook_form_FORM_ID_alter().
  363. */
  364. function pm_email_notify_form_privatemsg_admin_settings_alter(&$form, &$form_state) {
  365. $form['pm_email_notify'] = array(
  366. '#type' => 'fieldset',
  367. '#title' => t('E-mail notify'),
  368. '#group' => 'settings',
  369. '#weight' => 22,
  370. );
  371. $form['pm_email_notify']['privatemsg_setting_email_notify_level'] = array(
  372. '#type' => 'radios',
  373. '#title' => t('Default e-mail notification level'),
  374. '#options' => array(
  375. PM_EMAIL_NOTIFY_LEVEL_DISABLED => t('Never send a notification'),
  376. PM_EMAIL_NOTIFY_LEVEL_THREAD => t('Only send a notification when a new discussion thread is created'),
  377. 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."),
  378. PM_EMAIL_NOTIFY_LEVEL_ALL => t('Always send a notification'),
  379. ),
  380. '#default_value' => variable_get('privatemsg_setting_email_notify_level', PM_EMAIL_NOTIFY_LEVEL_ALL),
  381. '#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.'),
  382. '#weight' => 0,
  383. );
  384. $form['pm_email_notify']['privatemsg_setting_email_notify_only_user'] = array(
  385. '#type' => 'checkbox',
  386. '#title' => t('Only send e-mail notifications to individual users who are addressed directly'),
  387. '#default_value' => variable_get('privatemsg_setting_email_only_user', FALSE),
  388. '#weight' => 1,
  389. );
  390. $form['pm_email_notify']['pm_email_notify_desc'] = array(
  391. '#type' => 'item',
  392. '#title' => t('Customize the email messages sent to users upon receipt of a new private message.'),
  393. '#weight' => 2,
  394. );
  395. $form['pm_email_notify']['pm_email_notify_from'] = array(
  396. '#type' => 'textfield',
  397. '#title' => t('From e-mail address for notifications'),
  398. '#default_value' => variable_get('pm_email_notify_from',''),
  399. '#weight' => 3,
  400. '#description' => t('This is the e-mail address that notifications will come from. Leave blank to use the site default.'),
  401. );
  402. $form['pm_email_notify']['privatemsg_setting_show_sender_mail'] = array(
  403. '#type' => 'checkbox',
  404. '#title' => t("Use sender's email address"),
  405. '#description' => t("Use the sender's private email address instead of a generic sender for notification mails. This is the site default setting; users may override it individually."),
  406. '#default_value' => variable_get('privatemsg_setting_show_sender_mail', FALSE),
  407. '#weight' => 3,
  408. );
  409. $form['pm_email_notify']['pm_email_notify_subject'] = array(
  410. '#type' => 'textfield',
  411. '#title' => t('Subject of notification messages'),
  412. '#default_value' => variable_get('pm_email_notify_subject', _pm_email_notify_source_text('subject')),
  413. '#weight' => 4,
  414. );
  415. $form['pm_email_notify']['pm_email_notify_body'] = array(
  416. '#type' => 'textarea',
  417. '#title' => t('Body of notification messages'),
  418. '#default_value' => variable_get('pm_email_notify_body', _pm_email_notify_source_text('body')),
  419. '#weight' => 5,
  420. );
  421. if (module_exists('token')) {
  422. $form['pm_email_notify']['token'] = array(
  423. '#type' => 'fieldset',
  424. '#title' => t('Token browser'),
  425. '#weight' => -1,
  426. '#weight' => 6,
  427. );
  428. $form['pm_email_notify']['token']['browser'] = array(
  429. '#theme' => 'token_tree',
  430. '#token_types' => array('privatemsg_message'),
  431. );
  432. }
  433. else {
  434. $form['pm_email_notify']['tokens'] = array(
  435. '#type' => 'item',
  436. '#value' => t('Available variables are: !author, !author_uid, !pm_subject, !pm_body, !thread, !site, !login_url, !uri, !uri_brief, !message (URL) and !settings (URL).'),
  437. '#weight' => 6,
  438. );
  439. }
  440. if (module_exists('i18n_string')) {
  441. $form['#submit'][] = 'pm_email_notify_admin_settings_update_strings';
  442. }
  443. }
  444. /**
  445. * Form submit callback to update the translation string sources.
  446. */
  447. function pm_email_notify_admin_settings_update_strings($form, &$form_state) {
  448. i18n_string_update('pm_email_notify:mail:mail:subject', $form_state['values']['pm_email_notify_subject']);
  449. i18n_string_update('pm_email_notify:mail:mail:body', $form_state['values']['pm_email_notify_body']);
  450. }
  451. /**
  452. * Implements hook_i18n_string_info().
  453. */
  454. function pm_email_notify_i18n_string_info() {
  455. return array(
  456. 'pm_email_notify' => array(
  457. 'title' => t('Privatemsg Email Notification'),
  458. 'format' => FALSE,
  459. 'list' => TRUE,
  460. ),
  461. );
  462. }
  463. /**
  464. * Refresh callback to update the string translation sources.
  465. */
  466. function pm_email_notify_i18n_string_list($group) {
  467. if ($group == 'pm_email_notify' || $group == 'all') {
  468. $strings['pm_email_notify']['mail']['mail']['subject'] = _pm_email_notify_source_text('subject');
  469. $strings['pm_email_notify']['mail']['mail']['body'] = _pm_email_notify_source_text('body');
  470. return $strings;
  471. }
  472. }

Functions

Namesort descending Description
pm_email_notify_admin_settings_update_strings Form submit callback to update the translation string sources.
pm_email_notify_form_privatemsg_admin_settings_alter Implements hook_form_FORM_ID_alter().
pm_email_notify_form_user_profile_form_alter Implements hook_form_FORM_ID_alter().
pm_email_notify_i18n_string_info Implements hook_i18n_string_info().
pm_email_notify_i18n_string_list Refresh callback to update the string translation sources.
pm_email_notify_mail Implements hook_mail().
pm_email_notify_permission Implements hook_perm().
pm_email_notify_privatemsg_message_insert Implements hook_privatemsg_message_insert().
pm_email_notify_privatemsg_message_recipient_changed Implements hook_privatemsg_message_recipient_changed().
pm_email_notify_send_mail Send a pm notification email to a recipient.
pm_email_notify_text Returns body or subject strings.
pm_email_notify_user_delete Implements hook_user_delete().
pm_email_notify_user_update Implements hook_user_update().
_pm_email_notify_only_user Checks if a user should only be notified when addressed directly.
_pm_email_notify_send_check Retrieve notification setting of a user and check if they should receive an e-mail notification for a message.
_pm_email_notify_show_sender Checks if a message author wants his email address as a sender.
_pm_email_notify_source_text Retrieves the default text for body and subject texts.
_pm_email_notify_user_level Retrieve notification level of a user.

Constants

Namesort descending Description
PM_EMAIL_NOTIFY_LEVEL_ALL Enable e-mail notifications for all messages.
PM_EMAIL_NOTIFY_LEVEL_DEFAULT Enable e-mail notifications and use the global default.
PM_EMAIL_NOTIFY_LEVEL_DISABLED Disable e-mail notifications.
PM_EMAIL_NOTIFY_LEVEL_THREAD Enable e-mail notifications only for new threads.
PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE Enable e-mail notifications only once until a user visits a threads.