contact_attach.module in Contact Attach 5
Same filename and directory in other branches
This is the main code file for the Contact attach module. This module gives users the ability of attaching one or more files to e-mails sent using the site-wide contact form.
File
contact_attach.moduleView source
<?php
/**
* @file
* This is the main code file for the Contact attach module. This module
* gives users the ability of attaching one or more files to e-mails sent
* using the site-wide contact form.
*/
/**
* Implementation of hook_help().
*/
function contact_attach_help($section = '') {
$output = '';
switch ($section) {
case 'admin/settings/contact_attach':
$output = t('This module gives users the ability of attaching one or more files to e-mails sent using the site-wide contact form.');
break;
}
return $output;
}
// End of contact_attach_help().
/**
* Implementation of hook_perm().
*/
function contact_attach_perm() {
if (module_exists('og_contact')) {
$allowed_permissions = array(
'send attachments with site-wide contact form',
'send attachments with user contact form',
'send attachments with og contact form',
);
}
else {
$allowed_permissions = array(
'send attachments with site-wide contact form',
'send attachments with user contact form',
);
}
return $allowed_permissions;
}
// End of contact_attach_perm().
/**
* Implementation of hook_menu().
*/
function contact_attach_menu($may_cache) {
$items = array();
$items[] = array(
'path' => 'admin/settings/contact_attach',
'title' => t('Contact attach'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'contact_attach_admin_settings',
),
'access' => user_access('administer site configuration'),
'description' => t('Configure the Contact attach module.'),
);
return $items;
}
// End of contact_attach_menu().
/**
* Administration settings form.
*
* @return
* The completed form definition.
*/
function contact_attach_admin_settings() {
$form = array();
$form['contact_attach_number'] = array(
'#type' => 'textfield',
'#title' => t('Number of attachments'),
'#default_value' => variable_get('contact_attach_number', '3'),
'#size' => 10,
'#description' => t('The number of attachments to allow on the contact form.'),
);
return system_settings_form($form);
}
// End of contact_attach_admin_settings().
/**
* Implementation of hook_form_alter().
*/
function contact_attach_form_alter($form_id, &$form) {
if ($form_id == 'contact_mail_user' && user_access('send attachments with user contact form') || $form_id == 'contact_mail_page' && user_access('send attachments with site-wide contact form') || $form_id == 'og_contact_mail_page' && user_access('send attachments with og contact form')) {
for ($i = 1; $i <= variable_get('contact_attach_number', '3'); $i++) {
$form['contact_attach_' . $i] = array(
'#type' => 'file',
'#title' => t('Attachment #!number', array(
'!number' => $i,
)),
'#weight' => $i,
);
}
// We do not allow anonymous users to send themselves a copy because it
// can be abused to spam people.
global $user;
if ($user->uid) {
$form['copy'] = array(
'#type' => 'checkbox',
'#title' => t('Send yourself a copy.'),
'#weight' => $i,
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send e-mail'),
'#weight' => $i + 1,
);
$form['#attributes']['enctype'] = 'multipart/form-data';
switch ($form_id) {
case 'contact_mail_user':
$form['#validate'] = array(
'contact_attach_contact_mail_user_validate' => array(),
);
$form['#submit'] = array(
'contact_attach_contact_mail_user_submit' => array(),
);
break;
case 'contact_mail_page':
$form['#validate'] = array(
'contact_attach_contact_mail_page_validate' => array(),
);
$form['#submit'] = array(
'contact_attach_contact_mail_page_submit' => array(),
);
break;
case 'og_contact_mail_page':
$form['#validate'] = array(
'contact_attach_og_contact_mail_page_validate' => array(),
);
$form['#submit'] = array(
'contact_attach_og_contact_mail_page_submit' => array(),
);
break;
}
}
}
// End of contact_attach_form_alter().
/**
* Override contact_mail_user_validate().
*
* @param form_id
* A unique string identifying the form.
* @param form_values
* The contents of the form fields.
*/
function contact_attach_contact_mail_user_validate($form_id, $form_values) {
_contact_attach_upload_validate($form_id, $form_values);
}
// End of contact_attach_contact_mail_user_validate().
/**
* Override contact_mail_user_submit().
*
* @param form_id
* A unique string identifying the form.
* @param form_values
* The contents of the form fields.
* @return
* The profile page to go to.
*/
function contact_attach_contact_mail_user_submit($form_id, $form_values) {
global $user;
$account = user_load(array(
'uid' => arg(1),
'status' => 1,
));
// Compose the body:
$message[] = "{$account->name},";
$message[] = t("!name (!name-url) has sent you a message via your contact form (!form-url) at !site.", array(
'!name' => $user->name,
'!name-url' => url("user/{$user->uid}", NULL, NULL, TRUE),
'!form-url' => url($_GET['q'], NULL, NULL, TRUE),
'!site' => variable_get('site_name', 'Drupal'),
));
$message[] = t("If you don't want to receive such e-mails, you can change your settings at !url.", array(
'!url' => url("user/{$account->uid}", NULL, NULL, TRUE),
));
$message[] = t('Message:');
$message[] = $form_values['message'];
// Tidy up the body:
foreach ($message as $key => $value) {
$message[$key] = wordwrap($value);
}
// Prepare all fields:
$to = $account->mail;
$from = $user->mail;
// Format the subject:
$subject = '[' . variable_get('site_name', 'Drupal') . '] ' . $form_values['subject'];
// Attachment processing begins here.
$return_message = _contact_attach_process_attachments($message);
if (!empty($return_message)) {
$headers = $return_message['headers'];
$body = $return_message['body'];
}
else {
$headers = array();
// Prepare the body:
$body = implode("\n\n", $message);
}
// Send the e-mail:
drupal_mail('contact-user-mail', $to, $subject, $body, $from, $headers);
// Send a copy if requested:
if ($form_values['copy']) {
drupal_mail('contact-user-copy', $from, $subject, $body, $from, $headers);
}
// Log the operation:
flood_register_event('contact');
watchdog('mail', t('%name-from sent %name-to an e-mail.', array(
'%name-from' => $user->name,
'%name-to' => $account->name,
)));
// Set a status message:
drupal_set_message(t('The message has been sent.'));
// Jump to the user's profile page:
return "user/{$account->uid}";
}
// End of contact_attach_contact_mail_user_submit().
/**
* Override contact_mail_page_validate().
*
* @param form_id
* A unique string identifying the form.
* @param form_values
* The contents of the form fields.
*/
function contact_attach_contact_mail_page_validate($form_id, $form_values) {
if (!$form_values['cid']) {
form_set_error('category', t('You must select a valid category.'));
}
if (!valid_email_address($form_values['mail'])) {
form_set_error('mail', t('You must enter a valid e-mail address.'));
}
_contact_attach_upload_validate($form_id, $form_values);
}
// End of contact_attach_contact_mail_page_validate().
/**
* Override contact_mail_page_submit().
*
* @param form_id
* A unique string identifying the form.
* @param form_values
* The contents of the form fields.
* @return
* An empty string.
*/
function contact_attach_contact_mail_page_submit($form_id, $form_values) {
// E-mail address of the sender: as the form field is a text field,
// all instances of \r and \n have been automatically stripped from it.
$from = $form_values['mail'];
// Compose the body:
$message[] = t("!name sent a message using the contact form at !form.", array(
'!name' => $form_values['name'],
'!form' => url($_GET['q'], NULL, NULL, TRUE),
));
$message[] = $form_values['message'];
// Tidy up the body:
foreach ($message as $key => $value) {
$message[$key] = wordwrap($value);
}
// Load the category information:
$contact = db_fetch_object(db_query("SELECT * FROM {contact} WHERE cid = %d", $form_values['cid']));
// Format the category:
$subject = t('[!category] !subject', array(
'!category' => $contact->category,
'!subject' => $form_values['subject'],
));
// Attachment processing begins here.
$return_message = _contact_attach_process_attachments($message);
if (!empty($return_message)) {
$headers = $return_message['headers'];
$body = $return_message['body'];
}
else {
$headers = array();
// Prepare the body:
$body = implode("\n\n", $message);
}
// Send the e-mail to the recipients:
drupal_mail('contact-page-mail', $contact->recipients, $subject, $body, $from, $headers);
// If the user requests it, send a copy.
if ($form_values['copy']) {
drupal_mail('contact-page-copy', $from, $subject, $body, $from, $headers);
}
// Send an auto-reply if necessary:
if ($contact->reply) {
drupal_mail('contact-page-autoreply', $from, $subject, wordwrap($contact->reply), $contact->recipients);
}
// Log the operation:
flood_register_event('contact');
watchdog('mail', t('%name-from sent an e-mail regarding %category.', array(
'%name-from' => $form_values['name'] . " <{$from}>",
'%category' => $contact->category,
)));
// Update user:
drupal_set_message(t('Your message has been sent.'));
// Jump to home page rather than back to contact page to avoid contradictory messages if flood control has been activated.
return '';
}
// End of contact_attach_contact_mail_page_submit().
/**
* Override og_contact_mail_page_validate().
*
* @param form_id
* A unique string identifying the form.
* @param form_values
* The contents of the form fields.
*/
function contact_attach_og_contact_mail_page_validate($form_id, $form_values) {
if (!valid_email_address($form_values['mail'])) {
form_set_error('mail', t('You must enter a valid e-mail address.'));
}
_contact_attach_upload_validate($form_id, $form_values);
}
// End of contact_attach_og_contact_mail_page_validate().
/**
* Override og_contact_mail_page_submit().
*
* @param form_id
* A unique string identifying the form.
* @param form_values
* The contents of the form fields.
* @return
* The group page to go to.
*/
function contact_attach_og_contact_mail_page_submit($form_id, $form_values) {
$name = og_contact_get_group_name($form_values['gid']);
// E-mail address of the sender: as the form field is a text field,
// all instances of \r and \n have been automatically stripped from it.
$from = $form_values['mail'];
// Compose the body:
$message[] = t("!name sent a message using the contact form at !form.", array(
'!name' => $form_values['name'],
'!form' => url($_GET['q'], NULL, NULL, TRUE),
));
$message[] = $form_values['message'];
// Tidy up the body:
foreach ($message as $key => $value) {
$message[$key] = wordwrap($value);
}
// Load the group information:
$group = db_fetch_object(db_query("SELECT * FROM {og_contact} WHERE gid = %d", $form_values['gid']));
// Format the category:
$subject = $form_values['subject'];
// Attachment processing begins here.
$return_message = _contact_attach_process_attachments($message);
if (!empty($return_message)) {
$headers = $return_message['headers'];
$body = $return_message['body'];
}
else {
$headers = array();
// Prepare the body:
$body = implode("\n\n", $message);
}
// Send the e-mail to the recipients:
$recipients = og_contact_get_recipients($form_values['gid']);
drupal_mail('og-contact-page-mail', $recipients, $subject, $body, $from, $headers);
// If the user requests it, send a copy.
if ($form_values['copy']) {
drupal_mail('og-contact-page-copy', $from, $subject, $body, $from, $headers);
}
// Send an auto-reply if necessary:
if ($group->reply) {
drupal_mail('og-contact-page-autoreply', $from, $subject, wordwrap(check_plain($contact->reply)), $contact->recipients);
}
// Log the operation:
flood_register_event('og-contact');
watchdog('mail', t('%name-from sent an e-mail regarding %category.', array(
'%name-from' => $form_values['name'] . " <{$from}>",
'%category' => $name,
)));
// Update user:
drupal_set_message(t('Your message has been sent.'));
// Jump to group page rather than back to contact page to avoid
// contradictory messages if flood control has been activated.
return 'node/' . $group->gid;
}
// End of contact_attach_og_contact_mail_page_submit().
/**
* Check for attachments and process them, if one or more exists.
*
* @param message
* The message, as it exists so far.
* @return
* The message, including processed attachment(s).
*/
function _contact_attach_process_attachments($message) {
// Set an initial value.
$return_message = array();
// Loop through each possible attachment.
for ($i = 1; $i <= variable_get('contact_attach_number', '3'); $i++) {
if ($file = file_check_upload('contact_attach_' . $i)) {
// Check to see if the attachment exists.
if ($file->filesize > 0) {
// An attachment exists, so save it to an array for later processing.
$files[] = $file;
}
}
}
// If the array cantains something, we have one or more attachments to
// process. If it does not contain anything, we send back an empty $body,
// indicating no attachments exist.
if (!empty($files)) {
$boundary_id = md5(uniqid(time()));
$headers['Content-Type'] = 'multipart/mixed; boundary="' . $boundary_id . '"';
$body = "\n--{$boundary_id}\n";
$body .= "Content-Type: text/plain; charset=UTF-8; format=flowed;\n\n";
// sets the mime type
// Prepare the body:
$body .= implode("\n\n", $message);
$body .= "\n\n\n";
// Add the attachments.
// Loop through each possible attachment.
for ($i = 0; $i < count($files); $i++) {
// Process the attachment.
$body .= "--{$boundary_id}\n";
$body .= _contact_attach_add_attachment($files[$i]);
$body .= "\n\n";
}
$body .= "--{$boundary_id}--\n\n";
$return_message['headers'] = $headers;
$return_message['body'] = $body;
}
return $return_message;
}
// End of _contact_attach_process_attachments().
/**
* Add an attachment to the message body.
*
* @param file
* An attachment to add to the message.
* @return
* The processed attachment, ready for appending to the message.
*/
function _contact_attach_add_attachment($file) {
$attachment = "Content-Type: " . $file->filemime . "; name=\"" . basename($file->filename) . "\"\n";
$attachment .= "Content-Transfer-Encoding: base64\n";
$attachment .= "Content-Disposition: attachment; filename=\"" . basename($file->filename) . "\"\n\n";
if (file_exists($file->filepath)) {
$attachment .= chunk_split(base64_encode(file_get_contents($file->filepath)));
}
else {
$attachment .= chunk_split(base64_encode(file_get_contents(file_directory_temp() . '/' . $file->filename)));
}
return $attachment;
}
// End of _contact_attach_add_attachment().
/**
* Validate the attachment(s).
*
* @param form_id
* A unique string identifying the form.
* @param form_values
* The contents of the form fields.
*/
function _contact_attach_upload_validate($form_id, $form_values) {
// Accumulator for disk space quotas.
$filesize = 0;
// Loop through each possible attachment.
for ($i = 1; $i <= variable_get('contact_attach_number', '3'); $i++) {
if ($file = file_check_upload('contact_attach_' . $i)) {
// Check to see if an attachment exists.
if ($file->filesize > 0) {
global $user;
// Bypass validation for uid = 1.
if ($user->uid != 1) {
// Update filesize accumulator.
$filesize += $file->filesize;
$error = array();
// Validate file against all users roles.
// Only denies an upload when all roles prevent it.
foreach ($user->roles as $rid => $name) {
$extensions = variable_get("upload_extensions_{$rid}", variable_get('upload_extensions_default', 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp'));
$uploadsize = variable_get("upload_uploadsize_{$rid}", variable_get('upload_uploadsize_default', 1)) * 1024 * 1024;
$usersize = variable_get("upload_usersize_{$rid}", variable_get('upload_usersize_default', 1)) * 1024 * 1024;
$regex = '/\\.(' . ereg_replace(' +', '|', preg_quote($extensions)) . ')$/i';
if (!preg_match($regex, $file->filename)) {
$error['extension']++;
}
if ($uploadsize && $file->filesize > $uploadsize) {
$error['uploadsize']++;
}
if ($usersize && $filesize > $usersize) {
$error['usersize']++;
}
}
$user_roles = count($user->roles);
if ($error['extension'] == $user_roles) {
form_set_error('contact_attach_' . $i, t('The selected file %name can not be attached to this post, because it is only possible to attach files with the following extensions: %files-allowed.', array(
'%name' => $file->filename,
'%files-allowed' => $extensions,
)));
}
elseif ($error['uploadsize'] == $user_roles) {
form_set_error('contact_attach_' . $i, t('The selected file %name can not be attached to this post, because it exceeded the maximum filesize of %maxsize.', array(
'%name' => $file->filename,
'%maxsize' => format_size($uploadsize),
)));
}
elseif ($error['usersize'] == $user_roles) {
form_set_error('contact_attach_' . $i, t('The selected file %name can not be attached to this post, because the maximum file size of %quota per upload has been reached.', array(
'%name' => $file->filename,
'%quota' => format_size($usersize),
)));
}
elseif (drupal_strlen($_FILES['files']['name']['contact_attach_' . $i]) > 255) {
form_set_error('contact_attach_' . $i, t('The selected file %name can not be attached to this post, because the filename is too long.', array(
'%name' => $file->filename,
)));
}
}
}
}
}
}
// End of _contact_attach_upload_validate().