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,47 +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.',
$schema['webform_confirm_email_queued_emails'] = array(
'description' => 'Emails waiting for a submission to be confirmed',
'fields' => array(
'nid' => array(
'description' => 'The node ID of a webform submission to be confirmed.',
'type' => 'int',
'id' => array(
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'sid' => array(
'description' => 'Submission ID of a webform submission to be confirmed.',
'type' => 'int',
'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,
),
'datetime' => 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',
......@@ -60,15 +27,22 @@ function webform_confirm_email_schema() {
'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',
'email' => array(
'description' => 'The confirmation email that will be send once the confirmation URL is used',
'type' => 'blob',
'size' => 'big',
'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' => 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'),
),
);
......@@ -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());
}
/**
......@@ -109,55 +89,52 @@ function webform_confirm_email_mail_alter(&$message) {
$obj = array(
'nid' => $nid,
'sid' => $sid,
'email_message' => $message,
'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) {
function webform_confirm_email_confirmation_access($node, $submission, $eid, $code) {
return webform_confirm_email_generate_key($node->nid, $submission->sid, $eid) === $code;
}
db_delete('webform_confirm_email_code')
/**
* 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)
->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();
$submission->confirmed = 1;
foreach ($email_messages as $email_message) {
$messages = db_select('webform_confirm_email_queued_emails', 'e')
->fields('e', array('email'))
->condition('nid', $node->nid)
->condition('sid', $submission->sid)
->execute()
->fetchCol();
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']);
......@@ -193,34 +170,16 @@ function webform_confirm_email_confirmation($node,
);
}
}
$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 ' ,
array(
':nid' => $node->nid,
':sid' => $submission->sid,
)
);
}
// call implementations of hook_email_confirmed
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);
// trigger a rules email confirmed event
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"
msgid "Subject"
msgstr "Objet"
msgid "Edit"
msgstr "Modifier"
msgid "Node ID"
msgstr "Identifiant (ID) du nœud"
msgid "View"
msgstr "Voir"
msgid "URL"
msgstr "URL"
msgid "mail"
msgstr "courriel"
msgid "User"
msgstr "Utilisateur"
msgid "From"
msgstr "De"
msgid "Table"
msgstr "Tableau"
msgid "Days"
msgstr "Jours"
msgid "Hours"
msgstr "Heures"
msgid "Results"
msgstr "Résultats"
msgid "Minutes"
msgstr "Minutes"
msgid "Submissions"
msgstr "Soumissions"
msgid "Webform"
msgstr "Webform"
msgid "Go back to the form"
msgstr "Retourner au formulaire"
msgid "Redirect URL"
msgstr "Adresse URL de redirection"
msgid "IP address"
msgstr "Adresse IP"
msgid "E-mail to"
msgstr "Envoyer par e-mail à"
msgid "Confirmed"
msgstr "Confirmé"
msgid ""
"There are no submissions for this form. <a href=\"!url\">View this "
"form</a>."
msgstr ""
"Il n'y a pas de soumission pour ce formulaire. <a href=\"!url\">Voir "
"ce formulaire</a>."
msgid "Submissions for %user"
msgstr "Soumissions de %user"
msgid "Webform submission"
msgstr "Soumissions Webform"
msgid "Error sending e-mail (from %from to %to)."
msgstr "Erreur à l'envoi du courriel (de %from à %to)."
msgid "Serial number"
msgstr "Numéro de série"
msgid "Edit URL"
msgstr "Modifier URL"
msgid "email@example.com"
msgstr "email@example.com"
msgid "Your submissions"
msgstr "Vos soumissions"
msgid "@sid (draft)"
msgstr "@sid (ébauche)"
msgid "Submission ID"
msgstr "Identifiant (ID) de la soumission"
msgid "Submitter"
msgstr "Auteur"
msgid "Submission"
msgstr "Soumission"
msgid "All submissions"
msgstr "Toutes les soumissions"
msgid "Date submitted"
msgstr "Date de soummission"
msgid "The date the webform was submitted."
msgstr "La date de soumission du webform."
msgid "Tokens related to webform submissions."
msgstr "Jetons associés aux soumissions de formulaire."
msgid "The unique indentifier for the webform submission."
msgstr "L'identifiant unique de la soumission du formulaire."
msgid "The IP address that was used when submitting the webform."
msgstr "L'adresse IP utilisée lors de la soumission du formulaire"
msgid "The user that submitted the webform result."
msgstr "L'utilisateur qui a soumis le résultat du formulaire webform."