<?php
require('fpdf.php');
class PDF_POSTNET extends FPDF
{
// PUBLIC PROCEDURES
// draws a bar code for the given zip code using pdf lines
// triggers error if zip code is invalid
// x,y specifies the lower left corner of the bar code
function POSTNETBarCode($x, $y, $zipcode)
{
// Save nominal bar dimensions in user units
// Full Bar Nominal Height = 0.125"
$FullBarHeight = 9 / $this->k;
// Half Bar Nominal Height = 0.050"
$HalfBarHeight = 3.6 / $this->k;
// Full and Half Bar Nominal Width = 0.020"
$BarWidth = 1.44 / $this->k;
// Bar Spacing = 0.050"
$BarSpacing = 3.6 / $this->k;
$FiveBarSpacing = $BarSpacing * 5;
// 1 represents full-height bars and 0 represents half-height bars
$BarDefinitionsArray = Array(
1 => Array(0,0,0,1,1),
2 => Array(0,0,1,0,1),
3 => Array(0,0,1,1,0),
4 => Array(0,1,0,0,1),
5 => Array(0,1,0,1,0),
6 => Array(0,1,1,0,0),
7 => Array(1,0,0,0,1),
8 => Array(1,0,0,1,0),
9 => Array(1,0,1,0,0),
0 => Array(1,1,0,0,0));
// validate the zip code
$this->_ValidateZipCode($zipcode);
// set the line width
$this->SetLineWidth($BarWidth);
// draw start frame bar
$this->Line($x, $y, $x, $y - $FullBarHeight);
$x += $BarSpacing;
// draw digit bars
for($i = 0; $i < 5; $i++)
{
$this->_DrawDigitBars($x, $y, $BarSpacing, $HalfBarHeight,
$FullBarHeight, $BarDefinitionsArray, $zipcode[$i]);
$x += $FiveBarSpacing;
}
// draw more digit bars if 10 digit zip code
if(strlen($zipcode) == 10)
{
for($i = 6; $i < 10; $i++)
{
$this->_DrawDigitBars($x, $y, $BarSpacing, $HalfBarHeight,
$FullBarHeight, $BarDefinitionsArray, $zipcode[$i]);
$x += $FiveBarSpacing;
}
}
// draw check sum digit
$this->_DrawDigitBars($x, $y, $BarSpacing, $HalfBarHeight,
$FullBarHeight, $BarDefinitionsArray,
$this->_CalculateCheckSumDigit($zipcode));
$x += $FiveBarSpacing;
// draw end frame bar
$this->Line($x, $y, $x, $y - $FullBarHeight);
}
// Reads from end of string and returns first matching valid
// zip code of form DDDDD or DDDDD-DDDD, in that order.
// Returns empty string if no zip code found.
function ParseZipCode($stringToParse)
{
// check if string is an array or object
if(is_array($stringToParse) || is_object($stringToParse))
{
return "";
}
// convert parameter to a string
$stringToParse = strval($stringToParse);
$lengthOfString = strlen($stringToParse);
if ( $lengthOfString < 5 ) {
return "";
}
// parse the zip code backward
$zipcodeLength = 0;
$zipcode = "";
for ($i = $lengthOfString-1; $i >= 0; $i--)
{
// conditions to continue the zip code
switch($zipcodeLength)
{
case 0:
case 1:
case 2:
case 3:
if ( is_numeric($stringToParse[$i]) ) {
$zipcodeLength += 1;
$zipcode .= $stringToParse[$i];
} else {
$zipcodeLength = 0;
$zipcode = "";
}
break;
case 4:
if ( $stringToParse[$i] == "-" ) {
$zipcodeLength += 1;
$zipcode .= $stringToParse[$i];
} elseif ( is_numeric($stringToParse[$i]) ) {
$zipcodeLength += 1;
$zipcode .= $stringToParse[$i];
break 2;
} else {
$zipcodeLength = 0;
$zipcode = "";
}
break;
case 5:
case 6:
case 7:
case 8:
if ( is_numeric($stringToParse[$i]) ) {
$zipcodeLength = $zipcodeLength + 1;
$zipcode = $zipcode . $stringToParse[$i];
} else {
$zipcodeLength = 0;
$zipcode = "";
}
break;
case 9:
if ( is_numeric($stringToParse[$i]) ) {
$zipcodeLength = $zipcodeLength + 1;
$zipcode = $zipcode . $stringToParse[$i];
break;
} else {
$zipcodeLength = 0;
$zipcode = "";
}
break;
}
}
// return the parsed zip code if found
if ( $zipcodeLength == 5 || $zipcodeLength == 10 ) {
// reverse the zip code
return strrev($zipcode);
} else {
return "";
}
}
// PRIVATE PROCEDURES
// triggers user error if the zip code is invalid
// valid zip codes are of the form DDDDD or DDDDD-DDDD
// where D is a digit from 0 to 9, returns the validated zip code
function _ValidateZipCode($zipcode)
{
$functionname = "ValidateZipCode Error: ";
// check if zipcode is an array or object
if(is_array($zipcode) || is_object($zipcode))
{
trigger_error($functionname.
"Zip code may not be an array or object.", E_USER_ERROR);
}
// convert zip code to a string
$zipcode = strval($zipcode);
// check if length is 5
if ( strlen($zipcode) != 5 && strlen($zipcode) != 10 ) {
trigger_error($functionname.
"Zip code must be 5 digits or 10 digits including hyphen. len:".
strlen($zipcode)." zipcode: ".$zipcode, E_USER_ERROR);
}
if ( strlen($zipcode) == 5 ) {
// check that all characters are numeric
for ( $i = 0; $i < 5; $i++ ) {
if ( is_numeric( $zipcode[$i] ) == false ) {
trigger_error($functionname.
"5 digit zip code contains non-numeric character.",
E_USER_ERROR);
}
}
} else {
// check for hyphen
if ( $zipcode[5] != "-" ) {
trigger_error($functionname.
"10 digit zip code does not contain hyphen in right place.",
E_USER_ERROR);
}
// check that all characters are numeric
for ( $i = 0; $i < 10; $i++ ) {
if ( is_numeric($zipcode[$i]) == false && $i != 5 ) {
trigger_error($functionname.
"10 digit zip code contains non-numeric character.",
E_USER_ERROR);
}
}
}
// return the string
return $zipcode;
}
// takes a validated zip code and
// calculates the checksum for POSTNET
function _CalculateCheckSumDigit($zipcode)
{
// calculate sum of digits
if( strlen($zipcode) == 10 ) {
$sumOfDigits = $zipcode[0] + $zipcode[1] +
$zipcode[2] + $zipcode[3] + $zipcode[4] +
$zipcode[6] + $zipcode[7] + $zipcode[8] +
$zipcode[9];
} else {
$sumOfDigits = $zipcode[0] + $zipcode[1] +
$zipcode[2] + $zipcode[3] + $zipcode[4];
}
// return checksum digit
if( ($sumOfDigits % 10) == 0 )
return 0;
else
return 10 - ($sumOfDigits % 10);
}
// Takes a digit and draws the corresponding POSTNET bars.
function _DrawDigitBars($x, $y, $BarSpacing, $HalfBarHeight, $FullBarHeight,
$BarDefinitionsArray, $digit)
{
// check for invalid digit
if($digit < 0 && $digit > 9)
trigger_error("DrawDigitBars: invalid digit.", E_USER_ERROR);
// draw the five bars representing a digit
for($i = 0; $i < 5; $i++)
{
if($BarDefinitionsArray[$digit][$i] == 1)
$this->Line($x, $y, $x, $y - $FullBarHeight);
else
$this->Line($x, $y, $x, $y - $HalfBarHeight);
$x += $BarSpacing;
}
}
}
?>
<?php
require('postnet.php');
$pdf = new PDF_POSTNET("P","pt");
$pdf->AddPage();
$pdf->SetFont("Arial","",10);
// ParseZipCode examples
//$stringToParse = "Ann Arbor, MI 48109-110asdf"; // returns "48109"
//$stringToParse = "Ann Arbor, MI 48109-110"; // returns "48109"
//$stringToParse = "Ann Arbor, MI 481091109"; // returns "91109"
//$stringToParse = "Ann Arbor, MI 48109-1109asdf"; // returns "48109-1109"
//$stringToParse = "Cambridge, MA 0192"; // returns empty string
//$stringToParse = "Cambridge, MA 02139"; // perfect, returns "01239"
$stringToParse = "Ann Arbor, MI 48109-1109"; // perfect, returns "48109-1109"
$zipcode = $pdf->ParseZipCode($stringToParse);
$pdf->POSTNETBarCode(40,40,$zipcode);
$pdf->Text(40,90,$zipcode);
$pdf->Output();
?>
View the result