Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 117 additions & 53 deletions Make_statuscodes.php
Original file line number Diff line number Diff line change
@@ -1,59 +1,123 @@
<?php
#+++
# Make_statuscodes.php
# create the include file with all of the latest IANA standards RFC3463 + changes


print "<?php\n";
print "#Generated by Make_statuscodes.php\n\n";
print "#from http://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes-1.csv\n";
print "#and smtp-enhanced-status-codes-3.csv\n\n";

$fh = fopen("http://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes-1.csv", "r");
if ($fh !== FALSE) {
$a = fgets($fh); # 1st line is titles
while (!feof($fh)) {
$a = fgetcsv($fh, 0, ',', '"');
$a[0] = preg_replace('/\..*/', '', $a[0]); # 5.x.x -> 5
$a[1] = preg_replace('/\n\s*/', ' ', $a[1]); #remove line breaks
$a[1] = preg_replace('/\s\s+/', ' ', $a[1]); #remove double spaces
$a[1] = preg_replace('/"/', '\\"', $a[1]); #requote quotes
$a[2] = preg_replace('/\n\s*/', ' ', $a[2]); #remove line breaks
$a[2] = preg_replace('/\s\s+/', ' ', $a[2]); #remove double spaces
$a[2] = preg_replace('/"/', '\\"', $a[2]); #requote quotes
print "\$status_code_classes['$a[0]']['title'] = \"". $a[1]. "\"; # $a[3]\n";
print "\$status_code_classes['$a[0]']['descr'] = \"". $a[2]. "\";\n";
}
fclose ($fh);
/**
* Make status codes file
*
* Create the include file with all of the latest IANA standards RFC3463 + changes
*
* PHP version 5
*
* @category Email
* @package BounceHandler
* @author Multiple <[email protected]>
* @license http://opensource.org/licenses/BSD-2-Clause BSD
* @link https://github.com/cfortune/PHP-Bounce-Handler/
*/

$codes_1_url='http://www.iana.org/assignments/smtp-enhanced-status-codes/'.
'smtp-enhanced-status-codes-1.csv';
$codes_3_url='http://www.iana.org/assignments/smtp-enhanced-status-codes/'.
'smtp-enhanced-status-codes-3.csv';

$nl="\n";


/**
* Split a line into sections to avoid going over 80 character limit
* whilst preserving PEAR standards.
*
* @param string $describer Describer line
* @param string $line Line to split
* @param string $nl New line character(s)
*
* @return void
*/
function splitIt($describer,$line,$nl)
{
if (strlen($describer.$line)>70) {
$line_start = $nl . str_repeat(' ', 7) . '"';
$line_continues = '".';
print $describer . $nl;
print str_repeat(' ', 4) . '= "';
$split = chunk_split($line, 72, $line_continues . $line_start);
print substr($split, 0, -strlen($line_continues . $line_start));
print '";' . $nl . $nl;
} else {
print $describer.'="'.$line.'";'.$nl;
}
}
print "\n";
print '<?php'.$nl;
print '/** '.$nl;
print ' * Bounce status codes.'.$nl;
print ' *'.$nl;
print ' * Auto-generated by Make_statuscodes.php'.$nl;
print ' * on '.date('Y-m-d H:i:s').$nl;
print ' * From the following URLs:'.$nl;
print ' * '.chunk_split($codes_1_url, 75, $nl.' * ').$nl;
print ' * '.chunk_split($codes_3_url, 75, $nl.' * ').$nl;
print ' *'.$nl;
print ' * PHP version 5'.$nl;
print ' *'.$nl;
print ' * @category Email'.$nl;
print ' * @package BounceHandler'.$nl;
print ' * @author Multiple <[email protected]>'.$nl;
print ' * @license http://opensource.org/licenses/BSD-2-Clause BSD'.$nl;
print ' * @link https://github.com/cfortune/PHP-Bounce-Handler/'.$nl;
print ' */'.$nl.$nl;

$fh = fopen($codes_1_url, "r");
if ($fh !== false) {
$a = fgets($fh); // 1st line is titles
while (!feof($fh)) {
$a = fgetcsv($fh, 0, ',', '"');
if (false===isset($a[0]) || false===isset($a[1])
|| false===isset($a[2])
) {
die('Unable to read CSV line: '.print_r($a, true));
}
$a[0] = preg_replace('/\..*/', '', $a[0]); // 5.x.x -> 5
$a[1] = preg_replace('/\n\s*/', ' ', $a[1]); // remove line breaks
$a[1] = preg_replace('/\s\s+/', ' ', $a[1]); // remove double spaces
$a[1] = preg_replace('/"/', '\\"', $a[1]); // requote quotes
$a[2] = preg_replace('/\n\s*/', ' ', $a[2]); // remove line breaks
$a[2] = preg_replace('/\s\s+/', ' ', $a[2]); // remove double spaces
$a[2] = preg_replace('/"/', '\\"', $a[2]); // requote quotes
print '// '.$a[3].$nl;
splitIt('$status_code_classes[\''.$a[0].'\'][\'title\']', $a[1], $nl);
splitIt('$status_code_classes[\''.$a[0].'\'][\'descr\']', $a[2], $nl);

#X.7.17,Mailbox owner has changed,5XX,"This status code is returned when a message is
#received with a Require-Recipient-Valid-Since
#field or RRVS extension and the receiving
#system is able to determine that the intended
#recipient mailbox has not been under
#continuous ownership since the specified date.",[RFC-ietf-appsawg-rrvs-header-field-10] (Standards Track),M. Kucherawy,IESG


$fh = fopen("http://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes-3.csv", "r");
if ($fh !== FALSE) {
$a = fgets($fh); # 1st line is titles
while (!feof($fh)) {
$a = fgetcsv($fh, 0, ',', '"');
$a[0] = preg_replace('/^X./i', '', $a[0]); #X.5.0 -> 5.0
$a[1] = preg_replace('/\n\s*/', ' ', $a[1]); #remove line breaks
$a[1] = preg_replace('/\s\s+/', ' ', $a[1]); #remove double spaces
$a[1] = preg_replace('/"/', '\\"', $a[1]); #requote quotes
$a[3] = preg_replace('/\n\s*/', ' ', $a[3]); #remove line breaks
$a[3] = preg_replace('/\s\s+/', ' ', $a[3]); #remove double spaces
$a[3] = preg_replace('/"/', '\\"', $a[3]); #requote quotes
print "\$status_code_subclasses['$a[0]']['title'] = \"". $a[1]. "\"; # $a[4]\n";
print "\$status_code_subclasses['$a[0]']['descr'] = \"". $a[3]. "\";\n";
}
fclose ($fh);
}
fclose($fh);
}
print "\n\n?>";
print "\n";


// X.7.17,Mailbox owner has changed,5XX,"This status code is
// returned when a message is
// received with a Require-Recipient-Valid-Since
// field or RRVS extension and the receiving
// system is able to determine that the intended
// recipient mailbox has not been under
// continuous ownership since the specified date.",
// [RFC-ietf-appsawg-rrvs-header-field-10] (Standards Track),M. Kucherawy,IESG


$fh = fopen($codes_3_url, "r");
if ($fh !== false) {
$a = fgets($fh); // 1st line is titles
while (!feof($fh)) {
$a = fgetcsv($fh, 0, ',', '"');
$a[0] = preg_replace('/^X./i', '', $a[0]); // X.5.0 -> 5.0
$a[1] = preg_replace('/\n\s*/', ' ', $a[1]); // remove line breaks
$a[1] = preg_replace('/\s\s+/', ' ', $a[1]); // remove double spaces
$a[1] = preg_replace('/"/', '\\"', $a[1]); // requote quotes
$a[3] = preg_replace('/\n\s*/', ' ', $a[3]); // remove line breaks
$a[3] = preg_replace('/\s\s+/', ' ', $a[3]); // remove double spaces
$a[3] = preg_replace('/"/', '\\"', $a[3]); // requote quotes

print '// '.$a[4].$nl;
splitIt('$status_code_subclasses[\''.$a[0].'\'][\'title\']', $a[1], $nl);
splitIt('$status_code_subclasses[\''.$a[0].'\'][\'descr\']', $a[3], $nl);

?>
}
fclose($fh);
}
75 changes: 75 additions & 0 deletions README.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<p>Quick and dirty bounce handler</p>
<p><strong>Usage</strong></p>
<blockquote><code>
require_once('bounce_driver.class.php');
$bouncehandler=new Bouncehandler();
$multiArray=$bouncehandler->get_the_facts(\$strEmail)
</code></blockquote>

<p>( $multiArray=$bouncehandler->get_the_facts(\$strEmail) can be replaced by $multiArray = $bouncehandler->parse_email($strEmail) )</p>
<p>Returns a multi-dimensional associative array of bounced recipient addresses and their SMTP status codes (if available) - see
<code>print_r(\$multiArray);</code></p>

<p>Will return recipient's email address, the RFC1893 error code, and the action. Action can be one of the following:<dl>
<dt>transient</dt><dd>Temporary problem</dd>
<dt>failed</dt><dd>Permanent problem</dd>
<dt>autoresponse</dt><dd>Vacation auto-response/auto-responder<dd>
<dt>""</dt><dd>Empty string - not classified</dd>
</dl></p>

You could dereference the \$multiArray in a 'for loop', for example...</P>
<pre>
foreach($multiArray as $the){
switch($the['action']){
case 'failed':
//do something
kill_him($the['recipient']);
break;
case 'transient':
//do something else
$num_attempts = delivery_attempts($the['recipient']);
if($num_attempts > 10){
kill_him($the['recipient']);
}
else{
insert_into_queue($the['recipient'], ($num_attempts+1));
}
break;
case 'autoresponse':
//do something different
postpone($the['recipient'], '7 days');
break;
default:
//don't do anything
break;
}
}
</pre>

Or, if it is an FBL, you could use the class variables to access the
data (Unlike Multipart-reports, FBL's report only one bounce)
You could also use them if the output array has only one index:

<pre>
if($bouncehandler->type == 'fbl'
or count($bouncehandler->output) == 1)
{
echo $bouncehandler->action;
echo $bouncehandler->status;
echo $bouncehandler->recipient;
echo $bouncehandler->feedback_type;
}
</pre>

These class variables are safe for all bounce types:
<ul>
<li>$bouncehandler->type</li>
<li>$bouncehandler->subject</li>
<li>$bouncehandler->web_beacon_1</li>
<li>$bouncehandler->web_beacon_2</li>
<li>$bouncehandler->x_header_beacon_1</li>
<li>$bouncehandler->x_header_beacon_2</li>

</ul>

<p>That's all you need to know, but if you want to get more complicated you can. Most methods are public. See source code.</p>
Loading