Newer
Older
<?php
// $Id$
/**
* @file
* Displays and processes the mail send form.
*
* This file is included by the print_mail module and includes the
* mail form display, validation and submit hooks.
*/
require_once(drupal_get_path('module', 'print') .'/print.pages.inc');
/**
* Menu callback for the send by e-mail form.
*
* @ingroup forms
*/
function print_mail_form($form_state) {
global $user;
$print_mail_hourly_threshold = variable_get('print_mail_hourly_threshold', PRINT_MAIL_HOURLY_THRESHOLD);
if ((!user_access('administer print')) && (!flood_is_allowed('print_mail', $print_mail_hourly_threshold))) {
$form['flood'] = array(
'#type' => 'markup',
'#value' => '<p>'. t('You cannot send more than %number messages per hour. Please try again later.', array('%number' => $print_mail_hourly_threshold)) .'</p>',
);
return $form;
}
$print_mail_teaser_default = variable_get('print_mail_teaser_default', PRINT_MAIL_TEASER_DEFAULT_DEFAULT);
$print_mail_teaser_choice = variable_get('print_mail_teaser_choice', PRINT_MAIL_TEASER_CHOICE_DEFAULT);
$form = array();
// Remove the printmail/ prefix
$path = explode('/', $_GET['q']);
unset($path[0]);
$path = implode('/', $path);
if (is_numeric($path)) {
$path = 'node/'. $path;
}
$cid = isset($_GET['comment']) ? (int)$_GET['comment'] : NULL;
$title = _print_get_title($path);
$nodepath = drupal_get_normal_path($path);
db_query("UPDATE {print_mail_page_counter} SET totalcount = totalcount + 1, timestamp = %d WHERE path = '%s'", time(), $nodepath);
// If we affected 0 rows, this is the first time viewing the node.
if (!db_affected_rows()) {
// We must create a new row to store counters for the new node.
db_query("INSERT INTO {print_mail_page_counter} (path, totalcount, timestamp) VALUES ('%s', 1, %d)", $nodepath, time());
}
$form['path'] = array('#type' => 'value', '#value' => $path);
$form['cid'] = array('#type' => 'value', '#value' => $cid);
$form['fld_from_addr'] = array(
'#type' => 'textfield',
'#title' => t('Your e-mail'),
'#size' => 62,
);
$form['fld_from_name'] = array(
'#type' => 'textfield',
'#title' => t('Your name'),
'#size' => 62,
);
$form['txt_to_addrs'] = array(
'#type' => 'textarea',
'#title' => t('Send to'),
'#rows' => 3,
'#resizable' => FALSE,
'#description' => t('Enter multiple addresses separated by commas and/or different lines.'),
);
$form['fld_subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#size' => 62,
);
$form['fld_title'] = array(
'#type' => 'item',
'#title' => t('Page to be sent'),
'#value' => l($title, $path, array('title' => t('View page')), NULL, NULL, FALSE, FALSE),
);
$form['txt_message'] = array(
'#type' => 'textarea',
'#title' => t('Your message'),
'#rows' => 6,
);
if ($print_mail_teaser_choice) {
$form['chk_teaser'] = array(
'#type' => 'checkbox',
'#title' => t('Send only the teaser'),
'#default_value' => $print_mail_teaser_default,
);
}
else {
$form['chk_teaser'] = array('#type' => 'value', '#value' => $print_mail_teaser_default);
}
$form['btn_submit'] = array(
'#name' => 'submit',
'#type' => 'submit',
'#value' => t('Send e-mail'),
);
$form['btn_clear'] = array(
'#value' => '<input type="reset" name="clear" value="'. t('Clear form') .'" class="form-submit" /> ',
);
$form['btn_cancel'] = array(
'#name' => 'cancel',
'#type' => 'submit',
'#value' => t('Cancel'),
);
if ($user->uid != 0) {
$user_name = $user->name;
$form['fld_from_addr']['#default_value'] = $user->mail;
$form['fld_from_addr']['#disabled'] = TRUE;
$form['fld_from_addr']['#value'] = $user->mail;
$form['fld_from_name']['#default_value'] = $user->name;
}
else {
$user_name = t('Someone');
}
$site_name = variable_get('site_name', t('an interesting site'));
João Ventura
committed
$print_mail_text_subject = variable_get('print_mail_text_subject', t('!user has sent you a message from !site'));
$form['fld_subject']['#default_value'] = t($print_mail_text_subject, array('!user' => $user_name, '!site' => $site_name, '!title' => $title));
$print_mail_text_content = variable_get('print_mail_text_content', '');
$form['txt_message']['#default_value'] = t($print_mail_text_content);
return $form;
}
/**
* Theme function for the send by-email form submission.
*
* Adds a class to the form labels. This class is used to place the label on
* the left of the input fields.
*
* @ingroup forms
*/
function theme_print_mail_form($form) {
drupal_add_css(drupal_get_path('module', 'print') .'/css/printlinks.css');
$content = '';
foreach (element_children($form) as $key) {
$tmp = drupal_render($form[$key]);
switch ($key) {
case 'fld_from_addr':
case 'fld_from_name':
case 'txt_to_addrs':
case 'fld_subject':
case 'fld_title':
$tmp = str_replace('<label', '<label class ="printmail-label"', $tmp);
break;
}
$content .= $tmp;
}
return $content;
}
/**
* Validate the send by-email form submission.
*
* @ingroup forms
*/
function print_mail_form_validate($form_id, $form_values, $form) {
if (array_key_exists('cancel', $form['#post'])) {
return;
}
$from_addr = trim($form_values['fld_from_addr']);
$test = user_validate_mail($from_addr);
if ($test) {
form_set_error('fld_from_addr', $test);
}
// All new-lines are replaced by commas
João Ventura
committed
$to_addrs = preg_replace('![\r|\n|,]+!', ',', $form_values['txt_to_addrs']);
// Create an array from the string
$to_array = explode(',', $to_addrs);
// Verify each element of the array
foreach ($to_array as $key => $address) {
$address = trim($address);
if (preg_match('/(.*?) <(.*)>/s', $address, $matches)) {
// Address is of the type User Name <user@domain.tld>
$test = user_validate_mail($matches[2]);
$to_array[$key] = trim($matches[1]) .' <'. $matches[2] .'>';
}
else {
// Address must be user@domain.tld
$test = user_validate_mail($address);
}
if ($test) {
form_set_error('txt_to_addrs', $test);
}
}
$print_mail_hourly_threshold = variable_get('print_mail_hourly_threshold', PRINT_MAIL_HOURLY_THRESHOLD);
if ((!user_access('administer print')) && (!flood_is_allowed('print_mail', $print_mail_hourly_threshold - count($to_array) + 1))) {
form_set_error('txt_to_addrs', t('You cannot send more than %number messages per hour. Please reduce the number of recipients.', array('%number' => $print_mail_hourly_threshold)));
}
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
// In all fields, prevent insertion of custom headers
foreach ($form_values as $key => $string) {
if ( (substr($key, 0, 4) == 'fld_') && ((strpos($string, "\n") !== FALSE) || (strpos($string, "\r") !== FALSE)) ) {
form_set_error($key, 'Found invalid character');
}
}
$subject = trim($form_values['fld_subject']);
if (empty($subject)) {
form_set_error('fld_subject', t('You must enter a subject.'));
}
$message = trim($form_values['txt_message']);
if (empty($message)) {
form_set_error('txt_message', t('You must enter a message.'));
}
form_set_value($form['fld_from_addr'], $from_addr);
form_set_value($form['fld_from_name'], trim($form_values['fld_from_name']));
// Re-create the string from the re-organized array
form_set_value($form['txt_to_addrs'], implode(', ', $to_array));
form_set_value($form['fld_subject'], $subject);
form_set_value($form['txt_message'], $message);
}
/**
* Process the send by-email form submission.
*
* @ingroup forms
*/
function print_mail_form_submit($form_id, $form_values) {
if (!array_key_exists('cancel', $form_values)) {
if (!empty($form_values['fld_from_name'])) {
$from = '"'. $form_values['fld_from_name'] .'" <'. $form_values['fld_from_addr'] .'>';
}
else {
$from = $form_values['fld_from_addr'];
}
$cid = isset($form_values['cid']) ? $form_values['cid'] : NULL;
$print_mail_text_message = variable_get('print_mail_text_message', t('Message from sender'));
$sender_message = $print_mail_text_message .':<br /><br /><em>'. nl2br(check_plain($form_values['txt_message'])) .'</em>';
$print = print_controller($form_values['path'], $cid, PRINT_MAIL_FORMAT, $form_values['chk_teaser'], $sender_message);
// Spaces in img URLs must be replaced with %20
$pattern = '!<(img\s[^>]*?)>!is';
$print['content'] = preg_replace_callback($pattern, '_print_mail_encode_urls', $print['content']);
if ($print !== FALSE) {
$params = array();
$params['subject'] = $form_values['fld_subject'];
$headers = array('Content-Type' => 'text/html; charset=utf-8');
$node = $print['node'];
ob_start();
include_once(_print_get_template(PRINT_MAIL_FORMAT, $print['type']));
$params['body'] = ob_get_contents();
ob_end_clean();
$params['body'] = drupal_final_markup($params['body']);
$ok = FALSE;
João Ventura
committed
if (function_exists('job_queue_add') && variable_get('print_mail_job_queue', PRINT_MAIL_JOB_QUEUE_DEFAULT)) {
$use_job_queue = TRUE;
$this_file = drupal_get_path('module', 'print_mail') .'/print_mail.inc';
}
else {
$use_job_queue = FALSE;
}
$addresses = explode(', ', $form_values['txt_to_addrs']);
foreach ($addresses as $to) {
// Call to hook_print_mail_before_send in order to know if the mail can be sent
// Handlers must return TRUE or FALSE
$can_send = module_invoke_all('print_mail_before_send', $node, $to, $from, $params);
if (!in_array(FALSE, $can_send)) {
João Ventura
committed
if ($use_job_queue) {
// Use job queue to send mails during cron runs
job_queue_add('drupal_mail', t('print_mail: From %from', array('%from' => $from)), array('print_mail_sendpage', $to, $params['subject'], $params['body'], $from, $headers), $this_file, TRUE);
}
else {
// Send mail immediately using Drupal's mail handler
$ret = drupal_mail('print_mail_sendpage', $to, $params['subject'], $params['body'], $from, $headers);
}
if ($ret || $use_job_queue) {
// Call to hook_print_mail_after_send in order to provide information to other modules
module_invoke_all('print_mail_after_send', $node, $to, $from, $params);
flood_register_event('print_mail');
$ok = TRUE;
}
}
}
if ($ok) {
watchdog('print_mail', t('%name [%from] sent %page to [%to]', array('%name' => $form_values['fld_from_name'], '%from' => $form_values['fld_from_addr'], '%page' => $form_values['path'], '%to' => $form_values['txt_to_addrs'])));
$site_name = variable_get('site_name', t('us'));
$print_mail_text_confirmation = variable_get('print_mail_text_confirmation', t('Thank you for spreading the word about !site.'));
drupal_set_message(t($print_mail_text_confirmation, array('!site' => $site_name)));
$nodepath = drupal_get_normal_path($form_values['path']);
db_query("UPDATE {print_mail_page_counter} SET sentcount = sentcount + %d, sent_timestamp = %d WHERE path = '%s'", count($addresses), time(), $nodepath);
return preg_replace('!^book/export/html/!', 'node/', $form_values['path']);
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/**
* Callback function for the preg_replace_callback replacing spaces with %20
*
* Replace spaces in URLs with %20
*
* @param $matches
* array with the matched tag patterns, usually <a...>+text+</a>
* @return
* tag with re-written URL
*/
function _print_mail_encode_urls($matches) {
// first, split the html into the different tag attributes
$pattern = '!\s*(\w+\s*=\s*"(?:\\\"|[^"])*")\s*|\s*(\w+\s*=\s*\'(?:\\\\\'|[^\'])*\')\s*|\s*(\w+\s*=\s*\w+)\s*|\s+!';
$attribs = preg_split($pattern, $matches[1], -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
foreach ($attribs as $key => $value) {
$attribs[$key] = preg_replace('!(\w)\s*=\s*(.*)!', '$1=$2', $value);
}
$size = count($attribs);
for ($i=1; $i < $size; $i++) {
// If the attribute is href or src, we may need to rewrite the URL in the value
if (preg_match('!^(?:href|src)\s*?=(.*)!i', $attribs[$i], $urls) > 0) {
$url = trim($urls[1], " \t\n\r\0\x0B\"'");
$new_url = str_replace(' ', '%20', $url);
$matches[1] = str_replace($url, $new_url, $matches[1]);
}
}
$ret = '<'. $matches[1] .'>';
if (count($matches) == 4) {
$ret .= $matches[2] . $matches[3];
}
return $ret;
}