You are here

webform_email_reply.module in Webform Email Reply 7

Same filename and directory in other branches
  1. 8 webform_email_reply.module
  2. 7.2 webform_email_reply.module

This module provides a way for users to reply to webform submissions within the CMS.

File

webform_email_reply.module
View source
<?php

/**
 * @file
 * This module provides a way for users to reply to webform submissions within
 * the CMS.
 */

/**
 * Implements hook_help().
 */
function webform_email_reply_help($path) {
  $return_value = NULL;
  switch ($path) {
    case "admin/help#webform_email_reply":
      $return_value = "<p>" . t("This module provides a way for users to reply to webform submissions within the CMS.") . '<br />';
      $return_value .= t("Permissions can be set to allow users to reply to all webform submissions or only those on a node the user has created.") . '<p>';
      $return_value .= "<p>" . t("All emails sent are stored in the database and can be viewed from the submission.") . '</p>';
      break;
  }
  return $return_value;
}

/**
 * Implements hook_webform_submission_actions().
 */
function webform_email_reply_webform_submission_actions($node, $submission) {
  $actions = array();
  if (webform_email_reply_access($node, $submission)) {
    $actions['reply'] = array(
      'title' => t('Email reply'),
      'href' => 'node/' . $node->nid . '/submission/' . $submission->sid . '/reply',
      'query' => drupal_get_destination(),
    );

    // Only display link if there are replies.
    $replies = webform_email_reply_get_replies($node->nid, $submission->sid);
    if ($replies) {

      // Get number of replies.
      $count = count($replies);
      $actions['previous_replies'] = array(
        'title' => format_plural($count, '1 previous reply', '@count previous replies'),
        'href' => 'node/' . $node->nid . '/submission/' . $submission->sid . '/reply/previous',
        'query' => drupal_get_destination(),
      );
    }
  }
  return $actions;
}

/**
 * Implements hook_menu().
 */
function webform_email_reply_menu() {
  $items = array();
  $items['node/%webform_menu/submission/%webform_menu_submission/reply'] = array(
    'title' => 'Reply to submission',
    'load arguments' => array(
      1,
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'webform_email_reply_form',
      1,
      3,
    ),
    'access callback' => 'webform_email_reply_access',
    'access arguments' => array(
      1,
      3,
    ),
    'weight' => 2,
    'type' => MENU_LOCAL_TASK,
  );
  $items['node/%webform_menu/submission/%webform_menu_submission/reply/previous'] = array(
    'title' => 'Previous replies to submission',
    'load arguments' => array(
      1,
    ),
    'page callback' => 'webform_email_reply_previous',
    'page arguments' => array(
      1,
      3,
    ),
    'access callback' => 'webform_email_reply_access',
    'access arguments' => array(
      1,
      3,
    ),
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}

/**
 * Implements hook_theme().
 */
function webform_email_reply_theme() {
  $node = NULL;
  $submissions = array();
  $replies = array();
  return array(
    'webform_replies_table' => array(
      'variables' => array(
        'node' => $node,
        'submissions' => $submissions,
        'replies' => $replies,
      ),
    ),
  );
}

/**
 * Implements hook_permission().
 */
function webform_email_reply_permission() {
  return array(
    'send email replies to all webforms' => array(
      'title' => t('View and send email replies to all webforms'),
      'description' => t('Allows user to view and send emails in reply to any webform. Generally an administrative permission.'),
    ),
    'send email replies to own webforms' => array(
      'title' => t('View and send email replies to own webforms'),
      'description' => t('Allows user to view and send emails in reply to a webform the author has created. Generally an administrative permission.'),
    ),
  );
}

/**
 * A function to check if a user hass access to email reply to a webform.
 *
 * @param object $node
 *   The node for which this webform was submitted.
 * @param object $submission
 *   The submission to email reply to.
 */
function webform_email_reply_access($node, $submission) {
  global $user;
  $reply_all = user_access('send email replies to all webforms', $user);
  $reply_own = isset($submission) && user_access('send email replies to own webforms', $user) && ($user->uid && $user->uid == $node->uid);
  return $reply_all || $reply_own;
}

/**
 * Form to send an email reply.
 *
 * @param object $node
 *   The node for which this webform was submitted.
 * @param object $submission
 *   The submission to email reply to (from webform_submitted_data).
 */
function webform_email_reply_form($form, $form_state, $node, $submission) {
  global $user;
  webform_set_breadcrumb($node, $submission);

  // Set the correct page title.
  drupal_set_title(t('Reply to @title', array(
    '@title' => webform_submission_title($node, $submission),
  )));

  // Check text format access for the current user.
  $full = filter_access(filter_format_load('full_html'));
  $filtered = filter_access(filter_format_load('filtered_html'));
  if ($full) {
    $format = 'full_html';
  }
  elseif ($filtered) {
    $format = 'filtered_html';
  }
  else {
    $format = 'plain_text';
  }

  // Grab a default email, if one exists.
  $default_email_reply_from = webform_email_reply_get_default_from_option($node->nid);
  if ($default_email_reply_from === "1") {
    $default_from_email = $user->mail;
  }
  else {
    $default_from_email = variable_get('site_mail', '');
  }

  // Grab a default email, if one exists.
  $default_email_reply = webform_email_reply_get_default($node->nid);
  if ($default_email_reply) {

    // Quick check here to see what version of webform
    if (isset($submission->data[$default_email_reply]['value'])) {

      // Webform 7.x-3.x
      $values = $submission->data[$default_email_reply]['value'];
    }
    else {

      // Webform 7.x-4.x
      $values = $submission->data[$default_email_reply];
    }

    // Ever going to be multiple? Just in case.
    $default_to_email = implode(',', $values);
  }
  else {
    $default_to_email = NULL;
  }

  // Keep the NID and SID in the same location as the webform_client_form().
  // This helps mollom identify the same fields when deleting a submission.
  $form['#tree'] = TRUE;
  $form['details']['nid'] = array(
    '#type' => 'value',
    '#value' => $node->nid,
  );
  $form['details']['sid'] = array(
    '#type' => 'value',
    '#value' => $submission->sid,
  );
  $form['details']['from_address'] = array(
    '#type' => 'textfield',
    '#title' => t('From'),
    '#default_value' => $default_from_email,
    '#description' => t('The email address to send from.'),
    '#required' => TRUE,
  );
  $form['details']['email'] = array(
    '#type' => 'textfield',
    '#title' => t('Email'),
    '#default_value' => $default_to_email,
    '#description' => t('The email address(es) to send to. Multiple emails should be separated by a comma, with no spaces.'),
    '#required' => TRUE,
  );
  $form['details']['subject'] = array(
    '#type' => 'textfield',
    '#title' => t('Subject'),
    '#default_value' => t('RE: @title', array(
      '@title' => strip_tags($node->title),
    )),
    '#required' => TRUE,
  );
  $form['details']['message'] = array(
    '#type' => 'textarea',
    '#title' => t('Message'),
    '#required' => TRUE,
    '#format' => $format,
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Send'),
  );

  // For different webform module versions
  $submission_array = webform_submission_render($node, $submission, NULL, 'html');
  if (isset($submission_array['#node'])) {

    // Hasn't been rendered yet (webform 7.x-4.x), let's do that.
    $submission_array = drupal_render($submission_array);
  }
  $form['submission'] = array(
    '#markup' => '<p><h2>' . t('Submission') . '</h2>' . $submission_array . '</p>',
  );
  return $form;
}

/**
 * Validation of email reply.
 *
 * @param array $form
 *   The new form array.
 * @param array $form_state
 *   The current form state.
 */
function webform_email_reply_form_validate($form, &$form_state) {
  $from_email = $form_state['values']['details']['from_address'];
  if (!valid_email_address($from_email)) {
    form_set_error('details][from_address', t('The from email address, @email, is not valid. Please enter a valid email address.', array(
      '@email' => $from_email,
    )));
  }
  $valid_email = explode(',', $form_state['values']['details']['email']);
  foreach ($valid_email as $email) {
    if (!valid_email_address($email)) {
      form_set_error('details][email', t('The email address, @email, is not valid. Please enter a valid email address.', array(
        '@email' => $email,
      )));
    }
  }
}

/**
 * Confirmation of email reply.
 *
 * @param array $form
 *   The new form array.
 * @param array $form_state
 *   The current form state.
 */
function webform_email_reply_form_submit($form, &$form_state) {
  $nid = $form_state['values']['details']['nid'];
  $sid = $form_state['values']['details']['sid'];
  $emails = explode(',', $form_state['values']['details']['email']);
  $body = $form_state['values']['details']['message'];
  $subject = $form_state['values']['details']['subject'];
  $params = array(
    'body' => $body,
    'subject' => $subject,
  );
  $from_address = $form_state['values']['details']['from_address'];

  // Send each emails individually.
  foreach ($emails as $email) {
    if (drupal_mail('webform_email_reply', 'message_key', $email, language_default(), $params, $from_address, TRUE)) {
      drupal_set_message(t('Reply email sent to @email, from @from_address.', array(
        '@email' => $email,
        '@from_address' => $from_address,
      )));

      // Insert the values into the database.
      webform_email_reply_insert($form_state['values']['details']);
    }
    else {
      drupal_set_message(t('There was an error sending the email to @email, please contact the site admin.', array(
        '@email' => $email,
      )));
    }
  }
  $form_state['redirect'] = 'node/' . $nid . '/submission/' . $sid;
}

/**
 * Implements hook_mail().
 */
function webform_email_reply_mail($key, &$message, $params) {
  if (isset($params['subject'])) {
    $message['subject'] = $params['subject'];
  }
  if (isset($params['body'])) {
    $message['body'][] = $params['body'];
  }
  if (isset($params['headers']) && is_array($params['headers'])) {
    $message['headers'] += $params['headers'];
  }
}

/**
 * Function to insert the email into the database.
 *
 * @param array $data
 *   The values to insert into the database.
 */
function webform_email_reply_insert(array $data) {

  // Need the user replying to the submission.
  global $user;

  // Simple insert.
  db_insert('webform_email_reply')
    ->fields(array(
    'sid' => $data['sid'],
    'nid' => $data['nid'],
    'uid' => $user->uid,
    'from_address' => $data['from_address'],
    'replied' => time(),
    'message' => $data['message'],
  ))
    ->execute();
}

/**
 * Check to see if a reply exists already for a submission.
 *
 * @param string $nid
 *   The node id of the webform
 * @param string $sid
 *   The submission id
 */
function webform_email_reply_get_replies($nid, $sid) {
  $previous_replies =& drupal_static(__FUNCTION__ . $nid . "_" . $sid);
  if (!isset($previous_replies)) {

    // Simple db query to get all the emails replies.
    $results = db_select('webform_email_reply', 'r')
      ->fields('r')
      ->condition('r.nid', $nid)
      ->condition('r.sid', $sid)
      ->addTag('node_access')
      ->execute()
      ->fetchAll();
    $previous_replies = $results;
  }

  // Return what's found.
  return $previous_replies;
}

/**
 * Return a table of the email replies to a submission.
 *
 * @param object $node
 *   The node of the submission
 * @param object $submissions
 *   The submission
 *
 * @return string
 *   The table of email replies to return
 */
function webform_email_reply_previous($node, $submissions) {

  // Set the header.
  $header = array(
    array(
      'data' => t('#'),
      'field' => 'eid',
      'sort' => 'desc',
    ),
    array(
      'data' => t('Sent by'),
    ),
    array(
      'data' => t('Sent at'),
      'field' => 'replied',
    ),
    array(
      'data' => t('Message'),
    ),
  );

  // Get the submissions.
  $replies = webform_email_reply_get_replies($node->nid, $submissions->sid);
  foreach ($replies as $reply) {

    // @TODO full user load each time, better way of doing this?
    $user = user_load($reply->uid);
    $rows[] = array(
      $reply->eid,
      theme('username', array(
        'account' => $user,
      )) . '<br>' . $reply->from_address,
      format_date($reply->replied, 'short'),
      check_plain($reply->message),
    );
  }
  $output = theme('table', array(
    'header' => $header,
    'rows' => $rows,
  ));
  return $output;
}

/**
 * Implements hook_form_alter().
 */
function webform_email_reply_form_alter(&$form, $form_state, $form_id) {
  global $user;
  if ($user->uid == '1' && $form_id == 'webform_configure_form') {

    // Get the node id.
    $nid = $form['nid']['#value'];

    // Set the select list to choose the default email.
    $options = array(
      '0' => 'No default',
    );

    // Get the email components.
    $results = db_select('webform_component', 'wc')
      ->fields('wc', array(
      'cid',
      'name',
    ))
      ->condition('wc.nid', $nid)
      ->condition('wc.type', 'email')
      ->addTag('node_access')
      ->execute()
      ->fetchAll();

    // Add to the options list.
    if ($results) {
      foreach ($results as $result) {
        $options[$result->cid] = $result->name;
      }
    }

    // Now we have the options, set a default.
    $default = webform_email_reply_get_default($nid);

    // Start Email Reply form.
    $form['default_email_reply'] = array(
      '#type' => 'fieldset',
      '#title' => t('Default reply emails'),
      '#collapsible' => TRUE,
      '#collapsed' => FALSE,
      '#weight' => -2,
    );
    $form['default_email_reply']['from_option'] = array(
      '#type' => 'select',
      '#title' => t('Select a from email'),
      '#validated' => TRUE,
      '#options' => array(
        0 => t('Site Default Email: @mail', array(
          '@mail' => variable_get('site_mail', ''),
        )),
        1 => t("The current user's email who replies. (e.g. @mail)", array(
          '@mail' => $user->mail,
        )),
      ),
      '#default_value' => webform_email_reply_get_default_from_option($nid),
      '#description' => t('Select an email field to set as the default "From" address when replying to a submission.'),
    );
    $form['default_email_reply']['default_email'] = array(
      '#type' => 'select',
      '#title' => t('Select an email'),
      '#validated' => TRUE,
      '#options' => $options,
      '#default_value' => $default,
      '#description' => t('Select an email field to set as the default "To" address when replying to a submission.'),
    );
    $form['#submit'][] = 'webform_email_reply_default_submit';

    // End Email Reply Form.
  }
}

/**
 * Submit handler for webform_email_reply_form_alter().
 *
 * This saves the selected email to be used as the default to reply to.
 */
function webform_email_reply_default_submit($form, &$form_state) {

  // Get the needed values.
  $nid = $form_state['values']['nid'];
  $cid = $form_state['values']['default_email'];
  $from_option = $form_state['values']['from_option'];
  db_merge('webform_email_reply_emails')
    ->key(array(
    'nid' => $nid,
  ))
    ->fields(array(
    'nid' => $nid,
    'cid' => $cid,
    'from_option' => $from_option,
  ))
    ->execute();
}

/**
 * Get the default reply address for a webform.
 *
 * @param string $nid
 *   The node id of the webform
 */
function webform_email_reply_get_default($nid) {
  $result =& drupal_static(__FUNCTION__ . $nid . "_default");
  if (!isset($result)) {

    // Simple db query to get the default email.
    $result = db_select('webform_email_reply_emails', 'e')
      ->fields('e', array(
      'cid',
    ))
      ->condition('e.nid', $nid)
      ->addTag('node_access')
      ->execute()
      ->fetchField();
  }

  // Return what's found.
  return $result;
}

/**
 * Get the default reply from address for a webform.
 *
 * @param int $nid
 *   The node id of the webform.
 *
 * @return int
 *   The email address option.
 */
function webform_email_reply_get_default_from_option($nid) {
  $result =& drupal_static(__FUNCTION__ . $nid . '_default');
  if (!isset($result)) {
    $result = db_select('webform_email_reply_emails', 'e')
      ->fields('e', array(
      'from_option',
    ))
      ->condition('e.nid', $nid)
      ->addTag('node_access')
      ->execute()
      ->fetchField();
  }
  return $result;
}

Functions

Namesort descending Description
webform_email_reply_access A function to check if a user hass access to email reply to a webform.
webform_email_reply_default_submit Submit handler for webform_email_reply_form_alter().
webform_email_reply_form Form to send an email reply.
webform_email_reply_form_alter Implements hook_form_alter().
webform_email_reply_form_submit Confirmation of email reply.
webform_email_reply_form_validate Validation of email reply.
webform_email_reply_get_default Get the default reply address for a webform.
webform_email_reply_get_default_from_option Get the default reply from address for a webform.
webform_email_reply_get_replies Check to see if a reply exists already for a submission.
webform_email_reply_help Implements hook_help().
webform_email_reply_insert Function to insert the email into the database.
webform_email_reply_mail Implements hook_mail().
webform_email_reply_menu Implements hook_menu().
webform_email_reply_permission Implements hook_permission().
webform_email_reply_previous Return a table of the email replies to a submission.
webform_email_reply_theme Implements hook_theme().
webform_email_reply_webform_submission_actions Implements hook_webform_submission_actions().