Commit 696a4574 authored by theo lem's avatar theo lem
Browse files

Updated webform_confirm_email to 2.14 and fixed the broken email problem.

parent 5ec609b4
......@@ -8,9 +8,8 @@ dependencies[] = webform (>=7.x-4.16)
stylesheets[all][] = webform_confirm_email.css
; Information added by Drupal.org packaging script on 2017-10-31
version = "7.x-2.11"
; Information added by Drupal.org packaging script on 2019-10-29
version = "7.x-2.14"
core = "7.x"
project = "webform_confirm_email"
datestamp = "1509463987"
datestamp = "1572344887"
......@@ -7,11 +7,14 @@
* Implements hook_schema().
*/
function webform_confirm_email_schema() {
$schema = array();
$schema['webform_confirm_email_code'] = array(
'description' => 'Table for storing email confirmation codes.',
'fields' => array(
$schema['webform_confirm_email_queued_emails'] = array(
'description' => 'Emails waiting for a submission to be confirmed',
'fields' => array(
'id' => array(
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'nid' => array(
'description' => 'The node ID of a webform submission to be confirmed.',
'type' => 'int',
......@@ -24,52 +27,23 @@ function webform_confirm_email_schema() {
'unsigned' => TRUE,
'not null' => TRUE,
),
'eid' => array(
'description' => 'The e-mail ID of a webform submission to be confirmed.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'code' => array(
'description' => 'The hash code used for the confirmation link of a webform submission to be confirmed.',
'type' => 'char',
'length' => 32,
'not null' => TRUE,
'email' => array(
'description' => 'The confirmation email that will be send once the confirmation URL is used',
'type' => 'blob',
'size' => 'big',
'serialize' => TRUE,
),
'datetime' => array(
'created' => array(
'description' => 'Creation timestamp used for cron job cleanup of confirmation mails that exceeded their storage lifetime set by the admin',
'type' => 'int',
'not null' => TRUE,
),
),
'primary key' => array('nid', 'sid', 'eid'),
);
$schema['webform_confirm_email_confirmation_emails'] = array(
'description' => 'Confirmation emails are stored here to be send once the user used the confirmation URL',
'fields' => array(
'nid' => array(
'description' => 'The node ID of a webform submission to be confirmed.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'sid' => array(
'description' => 'Submission ID of a webform submission to be confirmed.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'email_message' => array(
'description' => 'The confirmation email that will be send once th confirmation URL is used',
'type' => 'text',
'size' => 'medium',
'serialize' => TRUE,
),
),
'primary key' => array('id'),
'indexes' => array(
'webform_confirm_email_confirmation_emails_nidsid_index' => array('nid', 'sid'),
),
'webform_confirm_email_submission' => array('nid', 'sid'),
'webform_confirm_email_email_created' => array('created'),
),
);
$schema['webform_confirm_email'] = array(
......@@ -187,6 +161,84 @@ function webform_confirm_email_uninstall() {
// **************** UPDATES ****************
// *****************************************
/**
* Completely redo email and code storage.
*/
function webform_confirm_email_update_7207() {
db_create_table('webform_confirm_email_queued_emails', array(
'description' => 'Emails waiting for a submission to be confirmed',
'fields' => array(
'id' => array(
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'nid' => array(
'description' => 'The node ID of a webform submission to be confirmed.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'sid' => array(
'description' => 'Submission ID of a webform submission to be confirmed.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'email' => array(
'description' => 'The confirmation email that will be send once the confirmation URL is used',
'type' => 'text',
'size' => 'medium',
'serialize' => TRUE,
),
'created' => array(
'description' => 'Creation timestamp used for cron job cleanup of confirmation mails that exceeded their storage lifetime set by the admin',
'type' => 'int',
'not null' => FALSE,
),
),
'primary key' => array('id'),
'indexes' => array(
'webform_confirm_email_submission' => array('nid', 'sid'),
'webform_confirm_email_email_created' => array('created'),
),
));
$sql = <<<SQL
INSERT INTO {webform_confirm_email_queued_emails} (nid, sid, email, created)
SELECT nid, sid, e.email_message, NULL
FROM {webform_confirm_email_confirmation_emails} e
SQL;
db_query($sql);
$sql = <<<SQL
UPDATE {webform_confirm_email_queued_emails} e
INNER JOIN (
SELECT nid, sid, MAX(datetime) AS created
FROM {webform_confirm_email_code}
GROUP BY nid, sid
) c USING(nid, sid)
SET e.created=c.created
SQL;
db_query($sql);
db_change_field('webform_confirm_email_queued_emails', 'created', 'created', array(
'description' => 'Creation timestamp used for cron job cleanup of confirmation mails that exceeded their storage lifetime set by the admin',
'type' => 'int',
'not null' => FALSE,
));
db_drop_table('webform_confirm_email_code');
db_drop_table('webform_confirm_email_confirmation_emails');
}
/**
* Drop {webform_confirm_email_code}.code.
*/
function webform_confirm_email_update_7206() {
db_drop_field('webform_confirm_email_code', 'code');
}
/**
* Migrate to expiration config columns in {webform}.
*/
......
......@@ -18,12 +18,7 @@ include_once 'webform_confirm_email.inc';
* The Webform submission that was just deleted from the database.
*/
function webform_confirm_email_webform_submission_delete($node, $submission) {
db_delete('webform_confirm_email_code')
->condition('nid', $node->nid)
->condition('sid', $submission->sid)
->execute();
db_delete('webform_confirm_email_confirmation_emails')
db_delete('webform_confirm_email_queued_emails')
->condition('nid', $node->nid)
->condition('sid', $submission->sid)
->execute();
......@@ -52,36 +47,21 @@ function webform_confirm_email_get_email_type($nid, $eid) {
}
/**
* generate a hash for a new email submission, or get an existing hash
* Generate a hash for a new email submission, or get an existing hash.
*
* @param $nid
* node id of the submitted form
* @param $sid
* submission id of the submitted form
* @param $email
* email address of the submitter; if empty, it's assumed that the submission
* has already happened and the webform_confirm_email_code table is searched
* for a hash
* @param $eid
* The email ID of the email that is being confirmed.
*
* @return string
* The hash for this submission / email.
*/
function webform_confirm_email_generate_key($nid, $sid, $eid, $email = NULL) {
if (isset($email)) {
return hash_hmac('md5', serialize(array($nid, $sid, $eid, $email)), drupal_get_private_key());
}
else {
$result = db_query(
'SELECT code ' .
' FROM {webform_confirm_email_code} ' .
' WHERE nid = :nid ' .
' AND sid = :sid ' .
' AND eid = :eid ',
array(
':nid' => $nid,
':sid' => $sid,
':eid' => $eid,
)
);
return $result->fetchField();
}
function webform_confirm_email_generate_key($nid, $sid, $eid) {
$data = "webform-confirm-email-code:$nid:$sid:$eid";
return drupal_hmac_base64($data, drupal_get_private_key());
}
/**
......@@ -107,120 +87,99 @@ function webform_confirm_email_mail_alter(&$message) {
if ( webform_confirm_email_get_email_type($nid, $eid) == WEBFORM_CONFIRM_EMAIL_CONFIRMATION
&& isset($message['params']['webform_confirm_email_confirmation_send']) == FALSE) {
$obj = array(
'nid' => $nid,
'sid' => $sid,
'email_message' => $message,
);
'nid' => $nid,
'sid' => $sid,
'email' => $message,
'created' => $_SERVER['REQUEST_TIME'],
);
$message['send'] = FALSE; // prevents drupal_mail from actually sending the message
unset($obj["email_message"]["params"]["node"]); // https://framagit.org/framasoft/framaforms/issues/24
drupal_write_record('webform_confirm_email_confirmation_emails', $obj);
drupal_write_record('webform_confirm_email_queued_emails', $obj);
}
}
}
/**
* callback function that is set in hook_menu().
* This function is called when a user clicks on the confirmation URL that
* a submitee gets via email after the 1st submission.
* If the submission code is found the confirmation mail is send and
* the submission record is removed from the DB
* Access callback: Check the confirmation page hash value.
*/
function webform_confirm_email_confirmation($node,
$submission,
$eid,
$code) {
if ( !empty($code)
&& webform_confirm_email_generate_key($node->nid, $submission->sid, $eid) == $code) {
db_delete('webform_confirm_email_code')
->condition('nid', $node->nid)
->condition('sid', $submission->sid)
->condition('eid', $eid)
->execute();
db_query(
'UPDATE {webform_submissions} ' .
' SET confirmed = 1 ' .
' WHERE nid = :nid ' .
' AND sid = :sid ',
array(':nid' => $node->nid, ':sid' => $submission->sid)
);
$email_messages = db_query(
'SELECT email_message ' .
' FROM {webform_confirm_email_confirmation_emails} ' .
' WHERE nid = :nid ' .
' AND sid = :sid ' ,
array(
':nid' => $node->nid,
':sid' => $submission->sid,
)
)->fetchCol();
foreach ($email_messages as $email_message) {
$email_message = unserialize($email_message);
// Concatenate and wrap the e-mail body.
if (is_array($email_message['body'])) {
$email_message['body'] = implode("\n\n", $email_message['body']);
}
function webform_confirm_email_confirmation_access($node, $submission, $eid, $code) {
return webform_confirm_email_generate_key($node->nid, $submission->sid, $eid) === $code;
}
$email_message['params']['webform_confirm_email_confirmation_send'] = TRUE;
/**
* Page callback: User clicked on a confirmation link.
*
* When any confirmation link is clicked for the first time:
* - All the emails waiting for the confirmation are sent.
* - The submission is marked as confirmed.
*
* Later clicks on the same or other confirmation links will not lead to any
* action. The user simply redirected to the appropriate URL.
*/
function webform_confirm_email_confirmation($node, $submission, $eid) {
db_update('webform_submissions')
->fields(array('confirmed' => 1))
->condition('nid', $node->nid)
->condition('sid', $submission->sid)
->execute();
$submission->confirmed = 1;
$email_message = drupal_mail(
$email_message['module'],
$email_message['key'],
$email_message['to'],
$email_message['language'],
$email_message['params'],
$email_message['from'],
TRUE
);
$messages = db_select('webform_confirm_email_queued_emails', 'e')
->fields('e', array('email'))
->condition('nid', $node->nid)
->condition('sid', $submission->sid)
->execute()
->fetchCol();
if ($email_message['result'] == FALSE) {
watchdog(
'mail',
'Error sending e-mail (from %from to %to).',
array(
'%from' => $email_message['from'],
'%to' => $email_message['to']
),
WATCHDOG_ERROR
);
drupal_set_message(t(
'Unable to send e-mail. ' .
'Please contact the site administrator if the problem persists.'
),
'error'
);
}
foreach ($messages as $email_message) {
$email_message = unserialize($email_message);
// Concatenate and wrap the e-mail body.
if (is_array($email_message['body'])) {
$email_message['body'] = implode("\n\n", $email_message['body']);
}
$codes_left_to_be_confirmed = db_query(
'SELECT nid ' .
' FROM {webform_confirm_email_code} ' .
' WHERE nid = :nid ' .
' AND sid = :sid ' ,
array(
':nid' => $node->nid,
':sid' => $submission->sid,
)
)->fetchField();
if ($codes_left_to_be_confirmed == FALSE) {
db_query(
'DELETE FROM {webform_confirm_email_confirmation_emails} ' .
' WHERE nid = :nid ' .
' AND sid = :sid ' ,
$email_message['params']['webform_confirm_email_confirmation_send'] = TRUE;
$email_message = drupal_mail(
$email_message['module'],
$email_message['key'],
$email_message['to'],
$email_message['language'],
$email_message['params'],
$email_message['from'],
TRUE
);
if ($email_message['result'] == FALSE) {
watchdog(
'mail',
'Error sending e-mail (from %from to %to).',
array(
':nid' => $node->nid,
':sid' => $submission->sid,
)
'%from' => $email_message['from'],
'%to' => $email_message['to']
),
WATCHDOG_ERROR
);
drupal_set_message(t(
'Unable to send e-mail. ' .
'Please contact the site administrator if the problem persists.'
),
'error'
);
}
// call implementations of hook_email_confirmed
module_invoke_all('webform_confirm_email_email_confirmed', $node, $submission);
// trigger a rules email confirmed event
if (module_exists('rules') == TRUE) {
rules_invoke_event('webform_confirm_email_email_confirmed', $node, $submission);
}
}
db_delete('webform_confirm_email_queued_emails')
->condition('nid', $node->nid)
->condition('sid', $submission->sid)
->execute();
// Let other modules react to the submission being confirmed.
module_invoke_all('webform_confirm_email_email_confirmed', $node, $submission);
if (module_exists('rules') == TRUE) {
rules_invoke_event('webform_confirm_email_email_confirmed', $node, $submission);
}
$redirect_url = db_query(
'SELECT redirect_url ' .
' FROM {webform_confirm_email} ' .
......@@ -267,8 +226,9 @@ function webform_confirm_email_menu() {
'title' => 'Submit email confirmation',
'load arguments' => array(1),
'page callback' => 'webform_confirm_email_confirmation',
'page arguments' => array(1, 3, 5, 7),
'access callback' => TRUE,
'page arguments' => array(1, 3, 5),
'access callback' => 'webform_confirm_email_confirmation_access',
'access arguments' => array(1, 3, 5, 7),
'type' => MENU_CALLBACK,
),
'node/%webform_menu/webform/confirmation_request/%webform_menu_email' => array(
......@@ -442,48 +402,14 @@ function webform_confirm_email_tokens($type, $tokens, array $data = array(), arr
$sid = (int) ($submission->sid);
$eid = (int) $data['webform-email']['eid'];
if (webform_confirm_email_get_email_type($nid, $eid) == WEBFORM_CONFIRM_EMAIL_CONFIRMATION_REQUEST) {
$obj = array(
'nid' => $nid,
'sid' => $sid,
'eid' => $eid,
'email' => $data['webform-email']['email'],
);
$obj['code'] = webform_confirm_email_generate_key($nid, $sid, $eid, $obj['email']);
$obj['datetime'] = REQUEST_TIME;
$code = webform_confirm_email_generate_key($nid, $sid, $eid);
$confirm_url = url(
"node/$nid/sid/$sid/eid/$eid/confirm_email/" . $obj['code'],
"node/$nid/sid/$sid/eid/$eid/confirm_email/$code",
array(
'absolute' => TRUE,
'external' => FALSE,
)
);
$result = db_query(
'SELECT nid ' .
' FROM {webform_confirm_email_code} ' .
' WHERE nid = :nid ' .
' AND sid = :sid ' .
' AND eid = :eid ' ,
array(
':nid' => $nid,
':sid' => $sid,
':eid' => $eid,
)
)->fetchField();
if ($result != FALSE) {
// mail was resend -> update record
drupal_write_record(
'webform_confirm_email_code',
$obj,
array('nid', 'sid', 'eid')
);
}
else {
// new mail
drupal_write_record('webform_confirm_email_code', $obj);
}
if (!empty($data['webform-email']['html'])) {
$confirm_url = "<a href=\"$confirm_url\">$confirm_url</a>";
}
......@@ -594,40 +520,22 @@ function webform_confirm_email_cron() {
if (!empty($nids_lifetime)) {
foreach ($nids_lifetime as $nid => $settings) {
$expired_sids = array();
// calculate the oldets timestamp that is still not expired
// for this nid;
// Calculate the oldest timestamp that is still not expired for this nid.
$timestamp = REQUEST_TIME - $settings->confirm_email_request_lifetime;
$expired_sids[$nid] = db_query(
'SELECT sid ' .
' FROM {webform_confirm_email_code} ' .
' WHERE nid = :nid ' .
' AND datetime < :oldest ' .
' GROUP BY sid ' ,
array(
':nid' => $nid,
':oldest' => $timestamp,
)
)->fetchCol();
if (!empty($expired_sids[$nid])) {
// delete requests from both tables (webform_confirm_email_code,
// webform_confirm_email_confirmation_emails) at once via JOIN
db_query(
'DELETE code, conf ' .
' FROM {webform_confirm_email_code} code ' .
' LEFT JOIN {webform_confirm_email_confirmation_emails} conf' .
' ON code.nid = conf.nid ' .
' AND code.sid = conf.sid ' .
' WHERE code.nid = :nid ' .
' AND code.sid in (:sids) ' ,
array(
':nid' => $nid,
':sids' => $expired_sids[$nid],
)
);
}
module_invoke_all('webform_confirm_email_request_expired', $expired_sids);
$expired_sids[$nid] = db_select('webform_confirm_email_queued_emails', 'e')
->fields('e', array('sid'))
->condition('nid', $nid)
->condition('created', $timestamp, '<')
->groupBy('sid')
->execute()
->fetchCol();
db_delete('webform_confirm_email_queued_emails')
->condition('nid', $nid)
->condition('created', $timestamp, '<')
->execute();
if ($settings->confirm_email_delete_submissions) {
require_once drupal_get_path('module', 'webform') . '/includes/webform.submissions.inc';
$node = node_load($nid);
......@@ -636,6 +544,9 @@ function webform_confirm_email_cron() {
}
}
}
if ($expired_sids) {
module_invoke_all('webform_confirm_email_request_expired', $expired_sids);
}
}
}
......
# French translation of Webform Confirm Email Address (7.x-2.4)
# Copyright (c) 2015 by the French translation team
#
msgid ""
msgstr ""
"Project-Id-Version: Webform Confirm Email Address (7.x-2.4)\n"
"POT-Creation-Date: 2015-12-15 11:14+0000\n"
"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
"Language-Team: French\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n>1);\n"
msgid "Save configuration"
msgstr "Enregistrer la configuration"
msgid "Delete"
msgstr "Supprimer"
msgid "Operations"
msgstr "Actions"