print_mail.module 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?php
  2. /**
  3. * @file
  4. * Displays Printer-friendly versions of Drupal pages.
  5. *
  6. * @ingroup print
  7. */
  8. define('PRINT_MAIL_HOURLY_THRESHOLD', 3);
  9. define('PRINT_MAIL_USE_REPLY_TO', TRUE);
  10. define('PRINT_MAIL_TEASER_DEFAULT_DEFAULT', 1);
  11. define('PRINT_MAIL_TEASER_CHOICE_DEFAULT', 0);
  12. define('PRINT_MAIL_SEND_OPTION_DEFAULT', 'sendpage');
  13. define('PRINT_MAIL_JOB_QUEUE_DEFAULT', 0);
  14. define('PRINT_MAIL_USER_RECIPIENTS_DEFAULT', 0);
  15. /**
  16. * Implements hook_print_link().
  17. */
  18. function print_mail_print_link() {
  19. return array(
  20. 'format' => 'mail',
  21. 'text' => t('Send by email'),
  22. 'description' => t('Send this page by email.'),
  23. 'path' => 'printmail',
  24. 'class' => 'print-mail',
  25. 'icon' => 'mail_icon.png',
  26. 'module' => 'print_mail',
  27. );
  28. }
  29. /**
  30. * Implements hook_permission().
  31. */
  32. function print_mail_permission() {
  33. return array(
  34. 'access send by email' => array(
  35. 'title' => t('Access the Send by email functionality'),
  36. 'description' => t('Provides the ability to send pages by email and the links to them in the original pages.'),
  37. ),
  38. 'send unlimited emails' => array(
  39. 'title' => t('Send unlimited emails'),
  40. 'description' => t("Overrides the built-in hourly threshold limits when sending emails. This permission should only be granted to trusted users, due to it's potential in enabling the use of your site as a source of email spam."),
  41. ),
  42. );
  43. }
  44. /**
  45. * Implements hook_theme().
  46. */
  47. function print_mail_theme() {
  48. return array(
  49. 'print_mail_form' => array(
  50. 'render element' => 'form',
  51. 'file' => 'print_mail.inc',
  52. ),
  53. 'print_mail_sendlink_html' => array(
  54. 'variables' => array('params' => NULL),
  55. 'file' => 'print_mail.inc',
  56. ),
  57. 'print_mail_sendlink_plain' => array(
  58. 'variables' => array('params' => NULL),
  59. 'file' => 'print_mail.inc',
  60. ),
  61. );
  62. }
  63. /**
  64. * Implements hook_menu().
  65. */
  66. function print_mail_menu() {
  67. $link = print_mail_print_link();
  68. $items = array();
  69. $items[$link['path']] = array(
  70. 'title' => 'Send by email',
  71. 'page callback' => 'drupal_get_form',
  72. 'page arguments' => array('print_mail_form'),
  73. 'access callback' => '_print_mail_access',
  74. 'access arguments' => array('access send by email'),
  75. 'type' => MENU_CALLBACK,
  76. 'file' => 'print_mail.inc',
  77. );
  78. $items[$link['path'] . '/' . $link['path']] = array(
  79. 'access callback' => FALSE,
  80. );
  81. $items['admin/config/user-interface/print/email'] = array(
  82. 'title' => 'email',
  83. 'description' => 'Configure the settings of the send by email functionality.',
  84. 'page callback' => 'drupal_get_form',
  85. 'page arguments' => array('print_mail_settings'),
  86. 'access arguments' => array('administer print'),
  87. 'weight' => 2,
  88. 'type' => MENU_LOCAL_TASK,
  89. 'file' => 'print_mail.admin.inc',
  90. );
  91. return $items;
  92. }
  93. /**
  94. * Implements hook_variable_info().
  95. */
  96. function print_mail_variable_info($options) {
  97. $link = print_mail_print_link();
  98. $variable['print_mail_link_text'] = array(
  99. 'title' => t('Send by email'),
  100. 'description' => t('Text used in the link to the send by email form.'),
  101. 'type' => 'string',
  102. 'default' => t($link['text']),
  103. );
  104. return $variable;
  105. }
  106. /**
  107. * Implements hook_requirements().
  108. */
  109. function print_mail_requirements($phase) {
  110. $requirements = array();
  111. $t = get_t();
  112. switch ($phase) {
  113. // At runtime, make sure that a PDF generation tool is selected
  114. case 'runtime':
  115. if (module_exists('mailsystem')) {
  116. $mail_system = mailsystem_get();
  117. if (($mail_system['default-system'] != 'DefaultMailSystem') && (!isset($mail_system['print_mail']) || ($mail_system['print_mail'] != 'DefaultMailSystem'))) {
  118. $requirements['print_mail_mailsystem'] = array(
  119. 'title' => $t('Printer, email and PDF versions - Send by email'),
  120. 'value' => $t('Incompatible Mail System setting detected'),
  121. 'description' => $t('The send by email module requires the use of the DefaultMailSystem, please configure it in the !url.', array('!url' => l($t('Mail System Settings page'), 'admin/config/system/mailsystem'))),
  122. 'severity' => REQUIREMENT_WARNING,
  123. );
  124. }
  125. }
  126. }
  127. return $requirements;
  128. }
  129. /**
  130. * Implements hook_block_info().
  131. */
  132. function print_mail_block_info() {
  133. $block['print_mail-top']['info'] = t('Most emailed');
  134. $block['print_mail-top']['cache'] = DRUPAL_CACHE_GLOBAL;
  135. return $block;
  136. }
  137. /**
  138. * Implements hook_block_view().
  139. */
  140. function print_mail_block_view($delta = 0) {
  141. switch ($delta) {
  142. case 'print_mail-top':
  143. $block['subject'] = t('Most emailed');
  144. $result = db_query_range("SELECT path FROM {print_mail_page_counter} LEFT JOIN {node} n ON path = CONCAT('node/', n.nid) WHERE status <> 0 OR status IS NULL ORDER BY sentcount DESC", 0, 3)
  145. ->fetchAll();
  146. if (count($result)) {
  147. $items = array();
  148. foreach ($result as $obj) {
  149. $items[] = l(_print_get_title($obj->path), $obj->path);
  150. }
  151. $block['content'] = theme('item_list', array('items' => $items, 'type' => 'ul'));
  152. }
  153. break;
  154. }
  155. return $block;
  156. }
  157. /**
  158. * Implements hook_node_delete().
  159. */
  160. function print_mail_node_delete($node) {
  161. db_delete('print_mail_page_counter')
  162. ->condition('path', 'node/' . $node->nid)
  163. ->execute();
  164. }
  165. /**
  166. * Implements hook_cron_queue_info().
  167. */
  168. function print_mail_cron_queue_info() {
  169. $queues['print_mail_send'] = array(
  170. 'worker callback' => 'print_mail_send',
  171. 'time' => 60,
  172. );
  173. return $queues;
  174. }
  175. /**
  176. * Worker callback for print_mail_cron_queue_info()
  177. *
  178. * @param array $data
  179. * An associative array containing:
  180. * - module: A module name to invoke hook_mail() on.
  181. * - key: A key to identify the e-mail sent.
  182. * - to: The e-mail address or addresses where the message will be sent to.
  183. * - language: Language object to use to compose the e-mail.
  184. * - params: Optional parameters to build the e-mail.
  185. * - from: Sets From to this value, if given.
  186. * These are the input arguments of the drupal_mail() function.
  187. */
  188. function print_mail_send($data) {
  189. drupal_mail($data['module'], $data['key'], $data['to'], $data['language'], $data['params'], $data['from']);
  190. }
  191. /**
  192. * Implements hook_mail().
  193. */
  194. function print_mail_mail($key, &$message, $params) {
  195. $message['subject'] = $params['subject'];
  196. if (isset($params['from'])) {
  197. $message['headers']['Reply-To'] = $params['from'];
  198. }
  199. switch ($key) {
  200. case 'sendpage':
  201. $message['body'][] = check_plain($params['body']);
  202. $message['headers']['Content-Type'] = 'text/html; charset=utf-8';
  203. break;
  204. case 'sendlink':
  205. // Generate plain-text and html versions of message with link
  206. $sendlink_plain = theme('print_mail_sendlink_plain', $params);
  207. $sendlink_html = theme('print_mail_sendlink_html', $params);
  208. // Send HTML-only version if MIME library not present
  209. if (!class_exists('Mail_mime')) {
  210. $message['body'][] = check_plain($sendlink_html);
  211. $message['headers']['Content-Type'] = 'text/html; charset=utf-8';
  212. break;
  213. }
  214. // no break on purpose
  215. case 'plain-attachment':
  216. case 'inline-attachment':
  217. // Configure new MIME object
  218. $mime = new Mail_mime("\n");
  219. $mime_params['html_encoding'] = '7bit';
  220. $mime_params['html_charset'] = 'utf-8';
  221. $mime_params['text_charset'] = 'utf-8';
  222. // Pass message contents into MIME object
  223. switch ($key) {
  224. case 'sendlink':
  225. $mime->setTxtBody($sendlink_plain);
  226. $mime->setHTMLBody($sendlink_html);
  227. break;
  228. case 'inline-attachment':
  229. $mime->setHTMLBody($params['body']);
  230. // no break on purpose
  231. case 'plain-attachment':
  232. $mime->setTxtBody($params['message']);
  233. $mime->addAttachment($params['body'], 'text/html', 'Attachment.html', FALSE);
  234. break;
  235. }
  236. // Store MIME message output in message array
  237. $message['body'][] = check_plain($mime->get($mime_params));
  238. $message['headers'] = $mime->headers($message['headers']);
  239. // Strip special characters from Content-Type header
  240. // Required to prevent mime_header_encode() from disrupting Content-Type header
  241. $message['headers']['Content-Type'] = preg_replace('/[^\x20-\x7E]/', '', $message['headers']['Content-Type']);
  242. break;
  243. }
  244. }
  245. /**
  246. * Access callback to check a combination of user_acess() and page access
  247. *
  248. * @param string $permission
  249. * permission required to view the page
  250. *
  251. * @return bool
  252. * TRUE if the user has permission to view the page, FALSE otherwise
  253. */
  254. function _print_mail_access($permission) {
  255. $link = print_mail_print_link();
  256. $page_access = TRUE;
  257. $parts = explode('/', $_GET['q']);
  258. if ($parts[0] == $link['path']) {
  259. if (count($parts) > 1) {
  260. unset($parts[0]);
  261. $path = implode('/', $parts);
  262. if (ctype_digit($parts[1])) {
  263. if (drupal_lookup_path('source', $path)) {
  264. // This is a numeric alias
  265. $path = drupal_get_normal_path($path);
  266. }
  267. else {
  268. // normal nid
  269. $path = 'node/' . $path;
  270. }
  271. }
  272. else {
  273. $path = drupal_get_normal_path($path);
  274. }
  275. // If the destination page is not accessible, don't show the form
  276. if (!($router_item = menu_get_item($path)) || (!$router_item['access'])) {
  277. $page_access = FALSE;
  278. }
  279. }
  280. }
  281. return (user_access($permission) && $page_access);
  282. }
  283. /**
  284. * Auxiliary function to display a formatted send by email link
  285. *
  286. * Function made available so that developers may call this function from
  287. * their defined pages/blocks.
  288. *
  289. * @param string $path
  290. * path to be used in the link. If not specified, the current URL is used.
  291. * @param object $node
  292. * node object, to be used in checking node access. If the path argument is
  293. * not provided, the path used will be node/nid.
  294. * @param string $location
  295. * where in the page where the link is being inserted ('link', 'corner',
  296. * 'block', 'help').
  297. *
  298. * @return string
  299. * string with the HTML link to the printer-friendly page
  300. *
  301. * @ingroup print_api
  302. */
  303. function print_mail_insert_link($path = NULL, $node = NULL, $location = '') {
  304. if (function_exists('print_ui_insert_link')) {
  305. return print_ui_insert_link(print_mail_print_link(), array('path' => $path, 'node' => $node, 'location' => $location));
  306. }
  307. else {
  308. return FALSE;
  309. }
  310. }
  311. /**
  312. * Check if the link to send by email is allowed depending on the settings
  313. *
  314. * @param array $args
  315. * array containing the possible parameters:
  316. * view_mode, node, type, path
  317. *
  318. * @return bool
  319. * FALSE if not allowed, TRUE otherwise
  320. */
  321. function print_mail_link_allowed($args) {
  322. return (user_access('access send by email'));
  323. }
  324. /**
  325. * Implements hook_nollom_form_list().
  326. */
  327. function print_mail_mollom_form_list() {
  328. $forms['print_mail_form'] = array(
  329. 'title' => t('Send by email form'),
  330. 'entity' => 'print_mail',
  331. );
  332. return $forms;
  333. }
  334. /**
  335. * Implemenents hook_mollom_form_info().
  336. */
  337. function print_mail_mollom_form_info($form_id) {
  338. switch ($form_id) {
  339. case 'print_mail_form':
  340. $form_info = array(
  341. 'elements' => array(
  342. 'fld_from_addr' => t('Sender email'),
  343. 'fld_from_name' => t('Sender name'),
  344. 'txt_to' => t('Recipients'),
  345. 'fld_subject' => t('Subject'),
  346. 'fld_title' => t('Page to be sent'),
  347. 'txt_message' => t('Your message'),
  348. ),
  349. 'mapping' => array(
  350. 'post_title' => 'fld_title',
  351. 'author_name' => 'fld_from_name',
  352. 'author_mail' => 'fld_from_addr',
  353. ),
  354. );
  355. break;
  356. }
  357. return $form_info;
  358. }
  359. /**
  360. * Implements hook_views_api().
  361. */
  362. function print_mail_views_api() {
  363. return array(
  364. 'api' => 2.0,
  365. 'path' => drupal_get_path('module', 'print_mail'),
  366. );
  367. }
  368. /**
  369. * Implements hook_rules_action_info().
  370. *
  371. * @ingroup rules
  372. */
  373. function print_mail_rules_action_info() {
  374. return array(
  375. 'print_mail_action_submit' => array(
  376. 'label' => t('Send node as HTML formatted email'),
  377. 'group' => t('Send by email'),
  378. 'parameter' => array(
  379. 'from' => array('type' => 'text', 'label' => t('From email adress')),
  380. 'from_name' => array('type' => 'text', 'label' => t('From name')),
  381. 'to' => array('type' => 'text', 'label' => t('Send email to')),
  382. 'subject' => array('type' => 'text', 'label' => t('Subject')),
  383. 'message' => array(
  384. 'type' => 'text',
  385. 'label' => t('Message'),
  386. 'description' => t('The message that should be displayed (optional).'),
  387. 'optional' => TRUE,
  388. ),
  389. 'node' => array('type' => 'node', 'label' => t('Content')),
  390. ),
  391. ),
  392. );
  393. }
  394. /**
  395. * Action handler for the print_mail_action_submit
  396. *
  397. * @ingroup rules
  398. */
  399. function print_mail_action_submit($from, $from_name, $to, $subject, $message, $node) {
  400. module_load_include('inc', 'print_mail', 'print_mail');
  401. $form_state['values'] = array(
  402. 'path' => 'node/' . $node->nid,
  403. 'query' => NULL,
  404. 'cid' => NULL,
  405. 'title' => $node->title,
  406. 'fld_from_addr' => $from,
  407. 'fld_from_name' => $from_name,
  408. 'txt_to' => array('addrs' => $to),
  409. 'fld_subject' => $subject,
  410. 'txt_message' => $message,
  411. 'chk_teaser' => FALSE,
  412. );
  413. print_mail_form_submit(NULL, $form_state);
  414. }