print_mail.module 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  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_block_info().
  108. */
  109. function print_mail_block_info() {
  110. $block['print_mail-top']['info'] = t('Most emailed');
  111. $block['print_mail-top']['cache'] = DRUPAL_CACHE_GLOBAL;
  112. return $block;
  113. }
  114. /**
  115. * Implements hook_block_view().
  116. */
  117. function print_mail_block_view($delta = 0) {
  118. $block = array();
  119. switch ($delta) {
  120. case 'print_mail-top':
  121. $block['subject'] = t('Most emailed');
  122. $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)
  123. ->fetchAll();
  124. if (count($result)) {
  125. $items = array();
  126. foreach ($result as $obj) {
  127. $items[] = l(_print_get_title($obj->path), $obj->path);
  128. }
  129. $block['content'] = theme('item_list', array('items' => $items, 'type' => 'ul'));
  130. }
  131. break;
  132. }
  133. return $block;
  134. }
  135. /**
  136. * Implements hook_node_delete().
  137. */
  138. function print_mail_node_delete($node) {
  139. db_delete('print_mail_page_counter')
  140. ->condition('path', 'node/' . $node->nid)
  141. ->execute();
  142. }
  143. /**
  144. * Implements hook_cron_queue_info().
  145. */
  146. function print_mail_cron_queue_info() {
  147. $queues['print_mail_send'] = array(
  148. 'worker callback' => 'print_mail_send',
  149. 'time' => 60,
  150. );
  151. return $queues;
  152. }
  153. /**
  154. * Worker callback for print_mail_cron_queue_info()
  155. *
  156. * @param array $data
  157. * An associative array containing:
  158. * - module: A module name to invoke hook_mail() on.
  159. * - key: A key to identify the e-mail sent.
  160. * - to: The e-mail address or addresses where the message will be sent to.
  161. * - language: Language object to use to compose the e-mail.
  162. * - params: Optional parameters to build the e-mail.
  163. * - from: Sets From to this value, if given.
  164. * These are the input arguments of the drupal_mail() function.
  165. */
  166. function print_mail_send($data) {
  167. drupal_mail($data['module'], $data['key'], $data['to'], $data['language'], $data['params'], $data['from']);
  168. }
  169. /**
  170. * Implements hook_mail().
  171. */
  172. function print_mail_mail($key, &$message, $params) {
  173. $message['subject'] = $params['subject'];
  174. if (isset($params['from'])) {
  175. $message['headers']['Reply-To'] = $params['from'];
  176. }
  177. $sendlink_plain = '';
  178. $sendlink_html = '';
  179. switch ($key) {
  180. case 'sendpage':
  181. $message['body'][] = check_plain($params['body']);
  182. $message['headers']['Content-Type'] = 'text/html; charset=utf-8';
  183. break;
  184. case 'sendlink':
  185. // Generate plain-text and html versions of message with link.
  186. $sendlink_plain = theme('print_mail_sendlink_plain', $params);
  187. $sendlink_html = theme('print_mail_sendlink_html', $params);
  188. // Send HTML-only version if MIME library not present.
  189. if (!class_exists('Mail_mime')) {
  190. $message['body'][] = check_plain($sendlink_html);
  191. $message['headers']['Content-Type'] = 'text/html; charset=utf-8';
  192. break;
  193. }
  194. // No break on purpose.
  195. case 'plain-attachment':
  196. case 'inline-attachment':
  197. // Configure new MIME object.
  198. $mime = new Mail_mime("\n");
  199. $mime_params['html_encoding'] = '7bit';
  200. $mime_params['html_charset'] = 'utf-8';
  201. $mime_params['text_charset'] = 'utf-8';
  202. // Pass message contents into MIME object.
  203. switch ($key) {
  204. case 'sendlink':
  205. $mime->setTxtBody($sendlink_plain);
  206. $mime->setHTMLBody($sendlink_html);
  207. break;
  208. case 'inline-attachment':
  209. $mime->setHTMLBody($params['body']);
  210. // No break on purpose.
  211. case 'plain-attachment':
  212. $mime->setTxtBody($params['message']);
  213. $mime->addAttachment($params['body'], 'text/html', 'Attachment.html', FALSE);
  214. break;
  215. }
  216. // Store MIME message output in message array.
  217. $message['body'][] = check_plain($mime->get($mime_params));
  218. $message['headers'] = $mime->headers($message['headers']);
  219. // Strip special characters from Content-Type header. Required to prevent
  220. // mime_header_encode() from disrupting Content-Type header.
  221. $message['headers']['Content-Type'] = preg_replace('/[^\x20-\x7E]/', '', $message['headers']['Content-Type']);
  222. break;
  223. }
  224. }
  225. /**
  226. * Access callback to check a combination of user_acess() and page access.
  227. *
  228. * @param string $permission
  229. * Permission required to view the page.
  230. *
  231. * @return bool
  232. * TRUE if the user has permission to view the page, FALSE otherwise
  233. */
  234. function _print_mail_access($permission) {
  235. $link = print_mail_print_link();
  236. $page_access = TRUE;
  237. $parts = explode('/', $_GET['q']);
  238. if ($parts[0] == $link['path']) {
  239. if (count($parts) > 1) {
  240. unset($parts[0]);
  241. $path = implode('/', $parts);
  242. if (ctype_digit($parts[1])) {
  243. if (drupal_lookup_path('source', $path)) {
  244. // This is a numeric alias.
  245. $path = drupal_get_normal_path($path);
  246. }
  247. else {
  248. // Normal nid.
  249. $path = 'node/' . $path;
  250. }
  251. }
  252. else {
  253. $path = drupal_get_normal_path($path);
  254. }
  255. // If the destination page is not accessible, don't show the form.
  256. if (!($router_item = menu_get_item($path)) || (!$router_item['access'])) {
  257. $page_access = FALSE;
  258. }
  259. }
  260. }
  261. return (user_access($permission) && $page_access);
  262. }
  263. /**
  264. * Auxiliary function to display a formatted send by email link.
  265. *
  266. * Function made available so that developers may call this function from
  267. * their defined pages/blocks.
  268. *
  269. * @param string $path
  270. * path to be used in the link. If not specified, the current URL is used.
  271. * @param object $node
  272. * node object, to be used in checking node access. If the path argument is
  273. * not provided, the path used will be node/nid.
  274. * @param string $location
  275. * Where in the page where the link is being inserted ('link', 'corner',
  276. * 'block', 'help').
  277. *
  278. * @return string
  279. * string with the HTML link to the printer-friendly page
  280. *
  281. * @ingroup print_api
  282. */
  283. function print_mail_insert_link($path = NULL, $node = NULL, $location = '') {
  284. if (function_exists('print_ui_insert_link')) {
  285. return print_ui_insert_link(print_mail_print_link(),
  286. array('path' => $path, 'node' => $node, 'location' => $location));
  287. }
  288. else {
  289. return FALSE;
  290. }
  291. }
  292. /**
  293. * Check if the link to send by email is allowed depending on the settings.
  294. *
  295. * @param array $args
  296. * Array containing the possible parameters:
  297. * view_mode, node, type, path.
  298. *
  299. * @return bool
  300. * FALSE if not allowed, TRUE otherwise.
  301. */
  302. function print_mail_link_allowed($args) {
  303. return (user_access('access send by email'));
  304. }
  305. /**
  306. * Implements hook_nollom_form_list().
  307. */
  308. function print_mail_mollom_form_list() {
  309. $forms['print_mail_form'] = array(
  310. 'title' => t('Send by email form'),
  311. 'entity' => 'print_mail',
  312. );
  313. return $forms;
  314. }
  315. /**
  316. * Implemenents hook_mollom_form_info().
  317. */
  318. function print_mail_mollom_form_info($form_id) {
  319. $form_info = array();
  320. switch ($form_id) {
  321. case 'print_mail_form':
  322. $form_info = array(
  323. 'elements' => array(
  324. 'fld_from_addr' => t('Sender email'),
  325. 'fld_from_name' => t('Sender name'),
  326. 'txt_to' => t('Recipients'),
  327. 'fld_subject' => t('Subject'),
  328. 'fld_title' => t('Page to be sent'),
  329. 'txt_message' => t('Your message'),
  330. ),
  331. 'mapping' => array(
  332. 'post_title' => 'fld_title',
  333. 'author_name' => 'fld_from_name',
  334. 'author_mail' => 'fld_from_addr',
  335. ),
  336. );
  337. break;
  338. }
  339. return $form_info;
  340. }
  341. /**
  342. * Implements hook_views_api().
  343. */
  344. function print_mail_views_api() {
  345. return array(
  346. 'api' => 2.0,
  347. 'path' => drupal_get_path('module', 'print_mail'),
  348. );
  349. }
  350. /**
  351. * Implements hook_rules_action_info().
  352. *
  353. * @ingroup rules
  354. */
  355. function print_mail_rules_action_info() {
  356. return array(
  357. 'print_mail_action_submit' => array(
  358. 'label' => t('Send node as HTML formatted email'),
  359. 'group' => t('Send by email'),
  360. 'parameter' => array(
  361. 'from' => array('type' => 'text', 'label' => t('From email adress')),
  362. 'from_name' => array('type' => 'text', 'label' => t('From name')),
  363. 'to' => array('type' => 'text', 'label' => t('Send email to')),
  364. 'subject' => array('type' => 'text', 'label' => t('Subject')),
  365. 'message' => array(
  366. 'type' => 'text',
  367. 'label' => t('Message'),
  368. 'description' => t('The message that should be displayed (optional).'),
  369. 'optional' => TRUE,
  370. ),
  371. 'node' => array('type' => 'node', 'label' => t('Content')),
  372. ),
  373. ),
  374. );
  375. }
  376. /**
  377. * Action handler for the print_mail_action_submit.
  378. *
  379. * @ingroup rules
  380. */
  381. function print_mail_action_submit($from, $from_name, $to, $subject, $message, $node) {
  382. module_load_include('inc', 'print_mail', 'print_mail');
  383. $form_state['values'] = array(
  384. 'path' => 'node/' . $node->nid,
  385. 'query' => NULL,
  386. 'cid' => NULL,
  387. 'title' => $node->title,
  388. 'fld_from_addr' => $from,
  389. 'fld_from_name' => $from_name,
  390. 'txt_to' => array('addrs' => $to),
  391. 'fld_subject' => $subject,
  392. 'txt_message' => $message,
  393. 'chk_teaser' => FALSE,
  394. );
  395. print_mail_form_submit(NULL, $form_state);
  396. }