Skip to content

Instantly share code, notes, and snippets.

@johansolve
Last active August 29, 2015 14:14
Show Gist options
  • Save johansolve/38e8b743a34ac02dfd6a to your computer and use it in GitHub Desktop.
Save johansolve/38e8b743a34ac02dfd6a to your computer and use it in GitHub Desktop.
Patch email_send subject encoding for Lasso 8
[
// [Email_Send2]
//
// This tag is a drop-in replacement for [Email_Send]. It uses [Email_Compose] on the back-end in order
// to create the message to be sent.
//
/* PATCH
* Replaces subject line that is encoded word by word with a subject line that is encoded as a whole.
* Include this file and use email_send2 instead of email_send.
* 2015-01-29 Johan Sölve
*
*/
Define_Tag: 'Send2',
-Priority='replace',
-namespace = 'email_',
-Optional='host',
-Optional='username',
-Optional='password',
-Optional='port',
-Optional='timeout',
-Optional='priority',
-Optional='to',
-Optional='cc',
-Optional='bcc',
-Optional='from',
-Optional='replyto',
-Optional='sender',
-Optional='subject',
-Optional='body',
-Optional='html',
-Optional='transferencoding',
-Optional='contenttype',
-Optional='characterset',
-Optional='attachments',
-Optional='extramimeheaders',
-Optional='simpleform',
-Optional='tokens',
-Optional='merge',
-Optional='date';
fail_if: ((local_defined: 'from') && (!#from->size)) || (!(local_defined: 'from')), -1, '[Email_Send] Requires a -From address.';
fail_if: !(local_defined: 'subject'), -1, '[Email_Send] Requires a -Subject.';
fail_if: !(((local_defined: 'to') && (#to->size > 0)) || ((local_defined: 'cc') && (#cc->size > 0)) || ( (local_defined: 'bcc') && (#bcc->size > 0))), -1, '[Email_Send] Requires a recipient.';
local(
'_params' = params,
'_host' = string(local('host')),
'_username' = string(local('username')),
'_password' = string(local('password'))
);
if((!#_username->size) && (!#_password->size) && (#_host >> '||') && (#_host->split('||')->size == 3));
#_username = #_host->split('||')->get(1);
#_password = #_host->split('||')->get(2);
#_host = #_host->split('||')->get(3);
else(#_host >> '||');
#_host = #_host->split('||')->last;
/if;
if: (local_defined: 'simpleform');
#_params->(removeall: '-simpleform');
#_params->(removeall: '-body');
if: !(local_defined: 'body');
local: '_body' = string;
else;
local: '_body' = #body + '\n\n';
/if;
iterate: action_params, (local: 'i');
if: !#i->first->(beginswith: '-');
#_body += #i->first ': ' #i->second '\n';
/if;
/iterate;
#_body += '\nForm was submitted by: ' client_ip '\n';
#_body += 'Form was submitted on: ' date->(format: '%-D %-r %Z') '\n';
#_params->(removeall: '-body');
#_params->(insert: -body = @#_body);
/if;
local: 'data' = @(\email_compose->(run: -params=#_params, -name='email_compose'));
local: 'mime_from' = #data->from;
local: 'mime_recipients' = #data->recipients;
local: 'mime_text' = #data->data;
fail_if: (#mime_text == ''), -1, '[Email_Send] The MIME encoding for the email message could not be generated.';
fail_if: (#mime_recipients == ''), -1, '[Email_Send] Requires one or more valid email addresses for recipients.';
fail_if: (#mime_from == ''), -1, '[Email_Send] Requires a -From parameter with the sender\'s email address.';
if: ((local_defined: 'date') == false) || (#date->(isa: 'date') == false);
local: 'date' = date;
/if;
// PATCH
if: (local_defined: 'characterset');
local('mime_charset' = #characterset);
else;
local('mime_charset' = 'utf-8');
/if;
local('mime_subject'= String_FindRegExp(#mime_text, -find='\\r\\nSubject: (.*?)\\r\\n')); // find subject line. Should be ^ at beginning and $ at the end of regex, but that doesn't work with Lasso.
if(#mime_subject -> isa('array') && #mime_subject -> size >= 2);
#mime_subject = #mime_subject -> get(2); // pick the first occurrence
local('mime_subject_fixed'=encode_stricturl(bytes(#subject,#mime_charset)));
if(#mime_subject >> '=?' + #mime_charset + '?Q?');
#mime_subject_fixed
-> replace('_', '%5F') // encode underscore
& replace('!', '%21') // encode !
& replace('%20', '_') // use underscore for spaces
& replace('%', '='); // use = instead of % in QP header
#mime_subject_fixed =
'=?' + #mime_charset + '?Q?' // add back opening encoding marker
+ #mime_subject_fixed // the encoded subject
+ '?='; // add back the closing encoding marker
#mime_text -> replace(#mime_subject, #mime_subject_fixed); // replace the bad subject with the fixed subject
/if;
/if;
// END PATCH
if: ((local: 'priority') == 'immediate') || (local_defined: 'immediate');
Email_Immediate:
-data=#mime_text,
-from=#mime_from,
-recipients=#mime_recipients,
-host = #_host,
-port = (local: 'port'),
-timeout = (local: 'timeout'),
-username = #_username,
-password = #_password,
-tokens = (local: 'tokens'),
-merge = (local: 'merge');
else;
Email_Queue:
-data=#mime_text,
-from=#mime_from,
-recipients=#mime_recipients,
-priority=(local: 'priority'),
-host = #_host,
-port = (local: 'port'),
-timeout = (local: 'timeout'),
-username = #_username,
-password = #_password,
-tokens = (local: 'tokens'),
-merge = (local: 'merge'),
-date = #date;
/if;
/Define_Tag;
]
@johansolve
Copy link
Author

[email_send] in Lasso 8 encodes extended text word by word. This causes display issues in some email clients (in particular Mail.app).
The patch modifies the subject so that the entire subject text is encoded as a whole.

Include the patch file and call email_send2 instead of email_send.

@johansolve
Copy link
Author

This is the same as the original email_send tag, with the addition of lines 100-123

@johansolve
Copy link
Author

For very long subjects that fold on multiple header lines, the patch will only correct the encoding of the first line.

@johansolve
Copy link
Author

Updated with new implementation that relies on encode_stricturl instead, to correctly handle subjects with question marks

@johansolve
Copy link
Author

Added encoding for "!"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment