PHP Mail via Exim Better Return Deployment Tutorial

PHP Mail via Exim Better Return Deployment Tutorial

PHP Mail via Exim Better Return Deployment Tutorial

Yesterday’s PHP Mail via Exim Better Return Primer Tutorial set up a …

  • framework part of an overall solution to a way to nuance PHP mail‘s return value, in an Exim Mail Server environment … and today …
  • we present a “use of” this framework for a “total solution” for a particular application need

Too boring for you?! But you see …

  • any non-synchronous scenario is bound to involve a “somewhat messy” arrangement … and …
  • the framework is solid and can remain, and the “use of” is fairly easily mimicked for another application usage … and …
  • parts of the “use of” to an “always used” by us tool web application which sends inline HTML emails (and so, effectively becomes merged into the “framework” of the solution) lessens the impact of the “somewhat messy” description above

To summarize, at least for us, we see this as a useful step forward, and besides that, we want to put this down in words.

Okay, to that last point above, we have the now changed emailhtml.php we use most often, in combination with Ajax and FormData to send out inline HTML (form) emails via our Exim Mail Server via PHP mail function. It changed in a function …

<?php

$isinline=false;
if (isset($_GET['inline']) || isset($_POST['inline'])) { $isinline=true; }


function zmail($zris, $zxsis, $ztis, $zhis) {
global $subjarr, $fflist, $ffname, $localdt, $fromer, $isinline;
// file_put_contents("091.091","");
if (strpos($zxsis, "[") === false && strpos($zxsis, "<") === false && $zxsis != "") {
$zxsis.=" at [date] for [files]";
// file_put_contents("092.092",$zxsis);
analtoken($zxsis, "");
}
// file_put_contents("093.093",$fflist);
subjtokenization($fflist, "files");
subjtokenization($ffname, "name");
// file_put_contents("094.094",$subjarr[0]);
if ($ffname == "") { $zhis=str_replace("<files>", $fflist, str_replace("[files]", $fflist, $zhis)); }
$zhis=str_replace("<files>", $fflist, str_replace("[files]", $fflist, str_replace("<name>", $ffname, str_replace("[name]", $ffname, $zhis))));
// file_put_contents("095.095",$xsis);
//$xretmd="";
//$xxretmd="";

if ($isinline && (isset($_GET['waitforreturn']) || isset($_POST['waitforreturn']))) { // relies on crontab scheduling of snapshotexim.ksh
$refd='' . date("Y-m-d H:i:s");
$cursecs=explode(':', $refd)[2];
$curtens=substr($cursecs,0,1);
$subsecs=substr($cursecs,1,1);
if ($cursecs > 56) {
sleep((61 - $cursecs));
$refd='' . date("Y-m-d H:i:s");
$cursecs=explode(':', $refd)[2];
$curtens=substr($cursecs,0,1);
$subsecs=substr($cursecs,1,1);
} else if ($subsecs > 6) {
sleep((11 - $subsecs));
$refd='' . date("Y-m-d H:i:s");
$cursecs=explode(':', $refd)[2];
$curtens=substr($cursecs,0,1);
$subsecs=substr($cursecs,1,1);
}
if ($curtens < 5) {
$refd=substr($refd, 0, 17) . '[' . $curtens . (1 + $curtens) . ']';
}
if (file_exists($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "snapshotexim.php")) {
unlink($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "snapshotexim.php");
}
if (strpos($refd, "[") !== false) {
file_put_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "snapshotexim.txt", '' . $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . ' "' . substr($refd, 0, 21) . '"');
exec('chmod 666 ' . $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "snapshotexim.txt");
} else {
file_put_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "snapshotexim.txt", '' . $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . ' "' . substr($refd, 0, 18) . '"');
exec('chmod 666 ' . $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "snapshotexim.txt");
}
}


$outretm=mail($zris, subjtokenization($zxsis,"subject"), $ztis, $zhis);


if ($isinline && (isset($_GET['waitforreturn']) || isset($_POST['waitforreturn']))) { // relies on crontab scheduling of snapshotexim.ksh
$maxwait=91;
$curwait=0;
while ($curwait < $maxwait && !file_exists($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "snapshotexim.php")) {
sleep(1);
$curwait++;
}
$reth="";
if (file_exists($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "snapshotexim.php")) {
$reth=file_get_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "snapshotexim.php");
if (strpos($reth, "no immediate delivery:") !== false) {
echo "<html><body><p>no immediate delivery</p></body></html>";
exit;
} else {
echo "<html><body><p>delivered from exim</p></body></html>";
exit;
}
} else {
echo "<html><body><p>not sure if exim delivered</p></body></html>";
exit;
}
}



return $outretm;
}

?>

… telling us the caller of this Exim emailing PHP tool needs to define a new argument called waitforreturn and the usual argument called inline for this solution to kick in. With our recent Sudoku game (that we last talked about with PHP/HTML/Javascript Sudoku Game Inline HTML Email Tutorial) we started to make that happen

<?php echo ”

function stateChanged() {
if (zhr.readyState == 4) {
if (zhr.status == 200) {
if (zhr.response.indexOf('no immediate delivery') != -1) {
aeclick(document.getElementById('aemail'));
} else {
preaeto='';
presubj='';
}
}
}
}



function simemail() {
var aeto='newwindow';
//alert('here');
thenums='';
var esels=document.getElementsByTagName('select');
for (var ejj=0; ejj<esels.length; ejj++) {
if (('' + esels[ejj].id) != 'smode') {
thenums+=retcn(esels[ejj].getAttribute('data-answer'));
}
}
var dspare=''
var dbi=document.body.innerHTML;
if (document.URL.indexOf('hard=') != -1 || ('' + location.hash).indexOf('hard') != -1) {
if (1 == 1) {
dbi=dbi.replace('\"easy\">Easy</option>', '\"hard\">Easy</option>').replace('\"hard\">Hard</option>', '\"easy\">Easy</option>').replace('\"hard\">Easy</option>', '\"hard\">Hard</option>');
predbi=predbi.replace('\"easy\">Easy</option>', '\"hard\">Easy</option>').replace('\"hard\">Hard</option>', '\"easy\">Easy</option>').replace('\"hard\">Easy</option>', '\"hard\">Hard</option>');
} else {
dbi=dbi.replace('>Hard</option>', ' selected>Hard</option>');
predbi=predbi.replace('>Hard</option>', ' selected>Hard</option>');
}
}
dbi=dbi.replace('\" border=', 'text-align:center;\" border=').replace(/\.\/index\.php/g, document.URL.split('?')[0].split('#')[0]).replace(/\ class\=\"bright\ bbottom\"/g, ' style=\"border-right:3px solid black;border-bottom:3px solid black;\" class\=\"bright\ bbottom\"').replace(/\ class\=\"bright\"/g, ' style=\"border-right:3px solid black;\" class\=\"bright\"').replace(/\ class\=\"bbottom\"/g, ' style=\"border-bottom:3px solid black;\" class\=\"bbottom\"');
predbi=predbi.replace('\" border=', 'text-align:center;\" border=').replace(/\.\/index\.php/g, document.URL.split('?')[0].split('#')[0]).replace(/\ class\=\"bright\ bbottom\"/g, ' style=\"border-right:3px solid black;border-bottom:3px solid black;\" class\=\"bright\ bbottom\"').replace(/\ class\=\"bright\"/g, ' style=\"border-right:3px solid black;\" class\=\"bright\"').replace(/\ class\=\"bbottom\"/g, ' style=\"border-bottom:3px solid black;\" class\=\"bbottom\"');
var dbis=dbi.split(' id=\"s'), dbiss=[];
var pdbis=predbi.split(' id=\"s');
var mustbe=0, imust=0, gval='';
for (var idb=1; idb<dbis.length; idb++) {
dspare=dbis[idb].split('\"')[0];
if (dspare == '' + mustbe) {
mustbe++;
if (dbi.indexOf(' name=\"s' + dspare + '\"') == -1) {
if (dbis[idb].indexOf(' disabled') != -1) {
gval=eval(10 - eval(dbis[idb].split(' value=\"')[1].split('\"')[0]));
//alert(dbis[idb].replace('></option>','>' + gval + '</option>') + ' ... ' + dbis[idb]);
if (dbis[idb].indexOf('> </option>') != -1) {
dbi=dbi.replace(dbis[idb], dbis[idb].replace('> </option>','>' + emj(gval) + '</option>').replace(' disabled', ' data-disabled'));
predbi=predbi.replace(pdbis[idb], pdbis[idb].replace('> </option>','>' + (gval) + '</option>').replace(' disabled', ' data-disabled'));
} else {
dbi=dbi.replace(dbis[idb], dbis[idb].replace('></option>','>' + emj(gval) + '</option>').replace(' disabled', ' data-disabled'));
predbi=predbi.replace(pdbis[idb], pdbis[idb].replace('></option>','>' + (gval) + '</option>').replace(' disabled', ' data-disabled'));
}
dbi=dbi.replace(' id=\"s' + dspare + '\"', ' id=\"s' + dspare + '\"' + ' name=\"s' + dspare + '\" value=\"' + gval + '\"');
predbi=predbi.replace(' id=\"s' + dspare + '\"', ' id=\"s' + dspare + '\"' + ' name=\"s' + dspare + '\" value=\"' + gval + '\"');
dbiss=dbi.split(' id=\"s');
//alert(dbiss[idb]);
} else {
dbi=dbi.replace(' id=\"s' + dspare + '\"', ' id=\"s' + dspare + '\"' + ' name=\"s' + dspare + '\"');
predbi=predbi.replace(' id=\"s' + dspare + '\"', ' id=\"s' + dspare + '\"' + ' name=\"s' + dspare + '\"');
}
}
}
}
//alert(mustbe);
if (document.URL.indexOf('newwindow=') == -1 && ('' + location.hash).indexOf('newwindow') == -1) {
aeto=prompt('Please enter email address to invite regarding this Sudoku game in a form within the message. Prefixing blanks will try emoji characters within the form (which some email clients are okay with). This methodology sometimes has delays and so we try another Sudoku game collaboration and sharing approach after that, in which you can optionally prefix by your Sudoku playing name and a : colon character, unless your email address is mixed case. Enter newwindow for game in a new popup window instead, where all uppercase in a new web browser tab. Optionally suffix by # followed by your email subject line [Sudoku game share invitation link]','');
var trye=false;
if (aeto.trim() != aeto) {
trye=true;
aeto=aeto.trim();
}
preaeto=aeto;
presubj='';
if (aeto.indexOf('#') != -1) {
presubj=aeto.split('#')[1];
}
if (aeto.indexOf(':') != -1) {
yourname=aeto.split(':')[0];
mapfromto('" . $weare . "', yourname);
document.getElementById('ibb').value=document.getElementById('ibb').value.replace(' your name', ' ' + yourname);
aeto=aeto.replace(yourname + ':', '');
}
if (aeto.indexOf('@') != -1) {
zhr = new XMLHttpRequest();
zform=new FormData();
if (aeto.split('#')[0].toUpperCase() == aeto.split('#')[0] || aeto.split('#')[0].toLowerCase() == aeto.split('#')[0]) {
zform.append('inline', '');
} else {
zform.append('inline', '');
zform.append('waitforreturn', 'y');
}

zform.append('to', aeto.replace(/\ /g,'').replace(/\;/g,',').split('#')[0]);
if (aeto.indexOf('#') != -1) {
zform.append('subject', aeto.split('#')[1]);
} else {
zform.append('subject', 'Sudoku game share invitation link');
}
if (trye) {
zform.append('htmlis', '<ht' + 'ml><bo' + 'dy><form method=GET action=' + document.URL.split('?')[0].split('&')[0].split('#')[0].replace('https:','http:').replace('?','#') + ' target=_blank>' + dbi.replace('body style=', 'body data-style=').replace(/\<button /g,'<button style=display:none; ') + '<input type=hidden id=thenums name=thenums value=' + thenums + ' style=display:none;></input>" . $hrd . "<input style=background-color:yellow; type=submit value=Check></input></form></body></html>');
} else {
zform.append('htmlis', '<ht' + 'ml><bo' + 'dy><form method=GET action=' + document.URL.split('?')[0].split('&')[0].split('#')[0].replace('https:','http:').replace('?','#') + ' target=_blank>' + predbi.replace('body style=', 'body data-style=').replace(/\<button /g,'<button style=display:none; ') + '<input type=hidden id=thenums name=thenums value=' + thenums + ' style=display:none;></input>" . $hrd . "<input style=background-color:yellow; type=submit value=Check></input></form></body></html>');
}
if (aeto.split('#')[0].toUpperCase() == aeto.split('#')[0] || aeto.split('#')[0].toLowerCase() == aeto.split('#')[0]) {
zhr.open('post', '//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php', true);
//alert('not trying exim log look ' + aeto);
} else {
zhr.onreadystatechange=stateChanged;
zhr.open('post', '//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php?rand=' + Math.floor(Math.random() * 198765643), true);
//alert('trying exim log look ' + aeto);
}

zhr.send(zform);
if (aeto.split('#')[0].toUpperCase() == aeto.split('#')[0] || aeto.split('#')[0].toLowerCase() == aeto.split('#')[0]) {
aeclick(document.getElementById('aemail'));
} else { // we now wait for an exim status return, so hang onto globals longer 21/12/2022
if (1 == 11) { preaeto=''; }
if (presubj == '') { presubj='Inline HTML Sudoku form delayed. ' + decodeURIComponent(document.getElementById('aemail').href.split('subject=')[1].split('&')[0]); if (preaeto.indexOf('#') == -1) { preaeto+='#' + presubj; } } else { presubj='Inline HTML Sudoku form delayed. ' + presubj; if (preaeto.indexOf('#') == -1) { preaeto+='#' + presubj; } }
}

}
}
if ((document.URL.indexOf('newwindow=') != -1 || ('' + location.hash).indexOf('newwindow') != -1) || aeto.replace(' ','').toLowerCase().indexOf('newwindow') == 0 && aeto.indexOf('@') == -1) {
if (aeto.replace(' ','').indexOf('NEWWINDOW') == 0) {
wo=window.open('','_blank');
} else {
wo=window.open('','_blank','top=50,left=50,width=900,height=800');
}
wo.document.write('<html><head><style> .bright { border-right: 5px solid black; } .bbottom { border-bottom: 5px solid black; } td { font-size: 24px; width: 11%; height: 9%; text-align: center; vertical-align: middle; } select { font-size: 24px; } th { text-align: left; vertical-align: top; } </style></head><body style=\" background-image: linear-gradient(to bottom right, rgb(255,255,255), rgb(224, 255, 255),rgb(175, 238, 238),rgb(173, 216, 230),rgb(135, 206, 235),rgb(135, 206, 250),rgb(0, 191, 255),rgb(30, 144, 255),rgb(100, 149, 237),rgb(123, 104, 238),rgb(65, 105, 225),rgb(0, 0, 255),rgb(0, 0, 205),rgb(0, 0, 139),rgb(0, 0, 128),rgb(25, 25, 112)); \"><form method=GET action=' + document.URL.split('?')[0].split('&')[0].split('#')[0].replace('?','#') + ' target=_blank>' + dbi.replace(/\<button /g,'<button style=display:none; ').replace('81%;','78%') + '<input type=hidden id=thenums name=thenums value=' + thenums + ' style=display:none;></input>" . $hrd . "<input style=background-color:yellow; type=submit value=Check></input></form></body></html>');
}
}

“; ?>

… meaning a button prompt window answer of Robert:RMetcalfe15@gmail.com (for example) in the second chance inline HTML email collaboration and sharing logic for index.php PHP Sudoku game will try to email an inline HTML email to the recipient via PHP mail through RJM Programming’s Exim mail server and will wait around to examine the relevant snippet of the /var/log/exim_mainlog log file to determine whether it should offer an “a” link “mailto” alternative approach because the logs show “no immediate delivery” in that relevant snippet of logging, while that Robert:RMetcalfe15@gmail.com was selected by the user to not offer this alternative with our Sudoku game.


Previous relevant PHP Mail via Exim Better Return Primer Tutorial is shown below.

PHP Mail via Exim Better Return Primer Tutorial

PHP Mail via Exim Better Return Primer Tutorial

We are exploring a way to improve on the PHP mail return value telling you nothing about whether the email gets off to the intended recipient. One step, here at RJM Programming, is to verify if the email has immediately been sent off according to our Exim mail server logs.

We are turning to a crontab operated (ie. scheduled) call to a new …

… to, in our MAMP local Apache web server wooooorrrrrlllllddd would work with either …


echo '/Applications/MAMP/htdocs/ "2022-12-20 11:4[01]"' > snapshotexim.txt
ksh ./snapshotexim.ksh # may populate /Applications/MAMP/htdocs/snapshotexim.php

… or …


echo '' > snapshotexim.txt
ksh ./snapshotexim.ksh /Applications/MAMP/htdocs/ "2022-12-20 11:4[01]" # may populate /Applications/MAMP/htdocs/snapshotexim.php

… methodologies to place a relevant “slice” (dated 2022-12-20 11:40 or 2022-12-20 11:41) of the Exim mail server log into a file in our Apache web server’s Document Root called snapshotexim.php for ongoing local work to follow.

We prefer the first way because our future PHP interfacing can better write out “the intelligence” into snapshotexim.txt itself.

Up with crontab, in a Korn Shell procedure that runs every minute, we place (code like) …


if [ -f "$HOME/snapshotexim.txt" ]; then
if [ -f "/etc/init.d/snapshotexim.ksh" ]; then
ksh /etc/init.d/snapshotexim.ksh
fi
fi

… ready for our journey of discovery to continue!

Did you know?

If you are thinking of implementing a solution of this ilk, within the next phase of the procedures we’ll tackle into the future, you will need a PHP reader of snapshotexim.php above, via file_get_contents or HTML and Javascript and Ajax reader such as eximsnapshot.php as some sort of starting point.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

This entry was posted in Ajax, eLearning, Event-Driven Programming, Operating System, Tutorials and tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>