mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-29 10:09:24 +01:00
1339 lines
30 KiB
PHP
1339 lines
30 KiB
PHP
|
<?php
|
||
|
/*
|
||
|
Validator 1.2 1999/03/05 CDI
|
||
|
|
||
|
A class for validating common data from forms
|
||
|
Copyright (c) 1999 CDI, cdi@thewebmasters.net All Rights Reserved
|
||
|
|
||
|
*/
|
||
|
|
||
|
/* $Id$ */
|
||
|
|
||
|
class validator
|
||
|
{
|
||
|
var $ERROR = "";
|
||
|
var $CLEAR = false;
|
||
|
|
||
|
function validator ()
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
function clear_error ()
|
||
|
{
|
||
|
$this->ERROR = "";
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Checks a string for whitespace. True or false
|
||
|
|
||
|
function has_space ($text)
|
||
|
{
|
||
|
if( ereg("[ ]",$text) )
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
|
||
|
function chconvert ($fragment)
|
||
|
{
|
||
|
if ($fragment == 7) { $result = "rwx"; }
|
||
|
elseif ($fragment == 6) { $result = "rw-"; }
|
||
|
elseif ($fragment == 5) { $result = "r-x"; }
|
||
|
elseif ($fragment == 4) { $result = "r--"; }
|
||
|
elseif ($fragment == 3) { $result = "-wx"; }
|
||
|
elseif ($fragment == 2) { $result = "-w-"; }
|
||
|
elseif ($fragment == 1) { $result = "--x"; }
|
||
|
elseif ($fragment == 0) { $result = "---"; }
|
||
|
|
||
|
else { $result = "unk"; }
|
||
|
|
||
|
return($result);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// ************************************************************
|
||
|
|
||
|
function get_perms ($fileName )
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
$atrib = array();
|
||
|
|
||
|
$perms = fileperms($fileName);
|
||
|
|
||
|
if(!$perms)
|
||
|
{
|
||
|
$this->ERROR = "get_perms: Unable to obtain file perms on [$fileName]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$octal = sprintf("%lo", ($perms & 07777) );
|
||
|
|
||
|
$one = substr($octal,0,1);
|
||
|
$two = substr($octal,1,1);
|
||
|
$three = substr($octal,2,1);
|
||
|
|
||
|
$user = $this->chconvert($one);
|
||
|
$group = $this->chconvert($two);
|
||
|
$other = $this->chconvert($three);
|
||
|
|
||
|
if(is_dir($fileName))
|
||
|
{
|
||
|
$user = "d$user";
|
||
|
}
|
||
|
|
||
|
$atrib = array(
|
||
|
"octal" => $octal,
|
||
|
"user" => $user,
|
||
|
"group" => $group,
|
||
|
"other" => $other
|
||
|
);
|
||
|
|
||
|
return $atrib;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
|
||
|
function is_sane ($filename)
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if (!file_exists($filename))
|
||
|
{
|
||
|
$this->ERROR = "File does not exist";
|
||
|
return false;
|
||
|
}
|
||
|
if (!is_readable($filename))
|
||
|
{
|
||
|
$this->ERROR = "File is not readable";
|
||
|
return false;
|
||
|
}
|
||
|
if(!is_writeable($filename))
|
||
|
{
|
||
|
$this->ERROR = "File is not writeable";
|
||
|
return false;
|
||
|
}
|
||
|
if(is_dir($filename))
|
||
|
{
|
||
|
$this->ERROR = "File is a directory";
|
||
|
return false;
|
||
|
}
|
||
|
if(is_link($filename))
|
||
|
{
|
||
|
$this->ERROR = "File is a symlink";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Strips whitespace (tab or space) from a string
|
||
|
|
||
|
function strip_space ($text)
|
||
|
{
|
||
|
$Return = ereg_replace("([ ]+)","",$text);
|
||
|
return ($Return);
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Returns true if string contains only numbers
|
||
|
|
||
|
function is_allnumbers ($text)
|
||
|
{
|
||
|
if( (gettype($text)) == "integer") { return true; }
|
||
|
|
||
|
$Bad = $this->strip_numbers($text);
|
||
|
|
||
|
if(empty($Bad))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Strip numbers from a string
|
||
|
|
||
|
function strip_numbers ($text)
|
||
|
{
|
||
|
$Stripped = eregi_replace("([0-9]+)","",$text);
|
||
|
return ($Stripped);
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Returns true if string contains only letters
|
||
|
|
||
|
function is_allletters ($text)
|
||
|
{
|
||
|
$Bad = $this->strip_letters($text);
|
||
|
if(empty($Bad))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ************************************************************
|
||
|
// Strips letters from a string
|
||
|
|
||
|
function strip_letters ($text)
|
||
|
{
|
||
|
$Stripped = eregi_replace("([A-Z]+)","",$text);
|
||
|
return $Stripped;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Checks for HTML entities in submitted text.
|
||
|
// If found returns true, otherwise false. HTML specials are:
|
||
|
//
|
||
|
// " => "
|
||
|
// < => <
|
||
|
// > => >
|
||
|
// & => &
|
||
|
//
|
||
|
// The presence of ",<,>,& will force this method to return true.
|
||
|
//
|
||
|
function has_html ($text = "")
|
||
|
{
|
||
|
if(empty($text))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
$New = htmlspecialchars($text);
|
||
|
if($New == $text)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// strip_html()
|
||
|
//
|
||
|
// Strips all html entities, attributes, elements and tags from
|
||
|
// the submitted string data and returns the results.
|
||
|
//
|
||
|
// Can't use a regex here because there's no way to know
|
||
|
// how the data is laid out. We have to examine every character
|
||
|
// that's been submitted. Consequently, this is not a very
|
||
|
// efficient method. It works, it's very good at removing
|
||
|
// all html from the data, but don't send gobs of data
|
||
|
// at it or your program will slow to a crawl.
|
||
|
|
||
|
// If you're stripping HTML from a file, use PHP's fgetss()
|
||
|
// and NOT this method, as fgetss() does the same thing
|
||
|
// about 100x faster.
|
||
|
|
||
|
function strip_html ($text = "")
|
||
|
{
|
||
|
if( (!$text) or (empty($text)) )
|
||
|
{
|
||
|
return "";
|
||
|
}
|
||
|
$outside = true;
|
||
|
$rawText = "";
|
||
|
$length = strlen($text);
|
||
|
$count = 0;
|
||
|
|
||
|
for($count=0; $count < $length; $count++)
|
||
|
{
|
||
|
$digit = substr($text,$count,1);
|
||
|
if(!empty($digit))
|
||
|
{
|
||
|
if( ($outside) and ($digit != "<") and ($digit != ">") )
|
||
|
{
|
||
|
$rawText .= $digit;
|
||
|
}
|
||
|
if($digit == "<")
|
||
|
{
|
||
|
$outside = false;
|
||
|
}
|
||
|
if($digit == ">")
|
||
|
{
|
||
|
$outside = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return $rawText;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Returns true of the submitted text has meta characters in it
|
||
|
// . \\ + * ? [ ^ ] ( $ )
|
||
|
//
|
||
|
//
|
||
|
function has_metas ($text = "")
|
||
|
{
|
||
|
if(empty($text))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$New = quotemeta($text);
|
||
|
|
||
|
if($New == $text)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ************************************************************
|
||
|
// Strips " . \\ + * ? [ ^ ] ( $ ) " from submitted string
|
||
|
//
|
||
|
// Metas are a virtual MINE FIELD for regular expressions,
|
||
|
// see custom_strip() for how they are removed
|
||
|
|
||
|
function strip_metas ($text = "")
|
||
|
{
|
||
|
if(empty($text))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$Metas = array( '.','+','*','?','[','^',']','(','$',')' );
|
||
|
$text = stripslashes($text);
|
||
|
$New = $this->custom_strip($Metas,$text);
|
||
|
return $New;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// $Chars must be an array of characters to remove.
|
||
|
// This method is meta-character safe.
|
||
|
|
||
|
function custom_strip ($Chars, $text = "")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if(empty($text))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if( (gettype($Chars)) != "array")
|
||
|
{
|
||
|
$this->ERROR = "custom_strip: [$Chars] is not an array";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
while ( list ( $key,$val) = each ($Chars) )
|
||
|
{
|
||
|
if(!empty($val))
|
||
|
{
|
||
|
// str_replace is meta-safe, ereg_replace is not
|
||
|
$text = str_replace($val,"",$text);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $text;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Array_Echo will walk through an array,
|
||
|
// continuously printing out key value pairs.
|
||
|
//
|
||
|
// Multi dimensional arrays are handled recursively.
|
||
|
|
||
|
function array_echo ($MyArray, $Name = "Array")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if( (gettype($MyArray)) != "array") { return; }
|
||
|
|
||
|
$count = 0;
|
||
|
|
||
|
while ( list ($key,$val) = each ($MyArray) )
|
||
|
{
|
||
|
if($count == 0)
|
||
|
{
|
||
|
echo "\n\n<P><TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 COLS=8\n";
|
||
|
echo "><TR><TD VALIGN=TOP COLSPAN=4><B>$Name Contents:</B></TD\n";
|
||
|
echo "><TD COLSPAN=2><B>KEY</B></TD><TD COLSPAN=2><B>VAL</B></TD></TR\n>";
|
||
|
}
|
||
|
if( (gettype($val)) == "array")
|
||
|
{
|
||
|
$NewName = "$key [$Name $count]";
|
||
|
$NewArray = $MyArray[$key];
|
||
|
echo "</TD></TR></TABLE\n\n>";
|
||
|
$this->array_echo($NewArray,$NewName);
|
||
|
echo "\n\n<P><TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 COLS=8\n";
|
||
|
echo "><TR><TD VALIGN=TOP COLSPAN=4><B>$Name Continued:</B></TD\n";
|
||
|
echo "><TD COLSPAN=2><B>KEY</B></TD><TD COLSPAN=2><B>VAL</B></TD></TR\n>";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
echo "<TR>";
|
||
|
$Col1 = sprintf("[%s][%0d]",$Name,$count);
|
||
|
$Col2 = $key;
|
||
|
if(empty($val)) { $val = ' '; }
|
||
|
$Col3 = $val;
|
||
|
echo "<TD COLSPAN=4>$Col1</TD>";
|
||
|
echo "<TD COLSPAN=2>$Col2</TD\n>";
|
||
|
echo "<TD COLSPAN=2>$Col3</TD></TR\n\n>";
|
||
|
}
|
||
|
$count++;
|
||
|
}
|
||
|
echo "<TR><TD COLSPAN=8><B>Array [$Name] complete.</B></TD></TR\n>";
|
||
|
echo "</TD></TR></TABLE\n\n>";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ************************************************************
|
||
|
// Valid email format? true or false
|
||
|
// This checks the raw address, not RFC 822 addresses.
|
||
|
|
||
|
// Looks for [something]@[valid hostname with DNS record]
|
||
|
|
||
|
function is_email ($Address = "")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if(empty($Address))
|
||
|
{
|
||
|
$this->ERROR = "is_email: No email address submitted";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if(!ereg("@",$Address))
|
||
|
{
|
||
|
$this->ERROR = "is_email: Invalid, no @ symbol in string";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
list($User,$Host) = split("@",$Address);
|
||
|
|
||
|
if ( (empty($User)) or (empty($Address)) )
|
||
|
{
|
||
|
$this->ERROR = "is_email: missing data [$User]@[$Host]";
|
||
|
return false;
|
||
|
}
|
||
|
if( ($this->has_space($User)) or ($this->has_space($Host)) )
|
||
|
{
|
||
|
$this->ERROR = "is_email: Whitespace in [$User]@[$Host]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Can't look for an MX only record as that precludes
|
||
|
// CNAME only records. Thanks to everyone that slapped
|
||
|
// me upside the head for this glaring oversite. :)
|
||
|
|
||
|
if(!$this->is_host($Host,"ANY")) { return false; }
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Valid URL format? true or false
|
||
|
|
||
|
// Checks format of a URL - does NOT handle query strings or
|
||
|
// urlencoded data.
|
||
|
|
||
|
function is_url ($Url = "")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if (empty($Url))
|
||
|
{
|
||
|
$this->ERROR = "is_url: No URL submitted";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Wow, the magic of parse_url!
|
||
|
|
||
|
$UrlElements = parse_url($Url);
|
||
|
if( (empty($UrlElements)) or (!$UrlElements) )
|
||
|
{
|
||
|
$this->ERROR = "is_url: Parse error reading [$Url]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$scheme = $UrlElements[scheme];
|
||
|
$HostName = $UrlElements[host];
|
||
|
|
||
|
if(empty($scheme))
|
||
|
{
|
||
|
$this->ERROR = "is_url: Missing protocol declaration";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if(empty($HostName))
|
||
|
{
|
||
|
$this->ERROR = "is_url: No hostname in URL";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (!eregi("^(ht|f)tp",$scheme))
|
||
|
{
|
||
|
$this->ERROR = "is_url: No http:// or ftp://";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
## padraic renaghan change for bookmarker ver 1.4 bug 69
|
||
|
## if hostname is an ip address, check the validity of
|
||
|
## the ip address, otherwise check as if host name
|
||
|
## is specified.
|
||
|
if (ereg("[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+",$HostName)) {
|
||
|
if(!$this->is_ipaddress($HostName)) { return false; }
|
||
|
} else {
|
||
|
if(!$this->is_hostname($HostName)) { return false; }
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// URL responds to requests? true or false
|
||
|
// This will obviously fail if you're not connected to
|
||
|
// the internet, or if there are connection problems. (firewall etc)
|
||
|
|
||
|
function url_responds ($Url = "")
|
||
|
{
|
||
|
global $php_errormsg;
|
||
|
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if(empty($Url))
|
||
|
{
|
||
|
$this->ERROR = "url_responds: No URL submitted";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if(!$this->is_url($Url)) { return false; }
|
||
|
|
||
|
$fd = @fopen($Url,"r");
|
||
|
if(!$fd)
|
||
|
{
|
||
|
$this->ERROR = "url_responds: Failed : $php_errormsg";
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
@fclose($fd);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Valid phone number? true or false
|
||
|
// Tries to validate a phone number
|
||
|
|
||
|
// Strips (,),-,+ from number prior to checking
|
||
|
// Less than 7 digits = fail
|
||
|
// More than 13 digits = fail
|
||
|
// Anything other than numbers after the stripping = fail
|
||
|
|
||
|
function is_phone ($Phone = "")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if(empty($Phone))
|
||
|
{
|
||
|
$this->ERROR = "is_phone: No Phone number submitted";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$Num = $Phone;
|
||
|
$Num = $this->strip_space($Num);
|
||
|
$Num = eregi_replace("(\(|\)|\-|\+)","",$Num);
|
||
|
if(!$this->is_allnumbers($Num))
|
||
|
{
|
||
|
$this->ERROR = "is_phone: bad data in phone number";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ( (strlen($Num)) < 7)
|
||
|
{
|
||
|
$this->ERROR = "is_phone: number is too short [$Num][$Phone]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// 000 000 000 0000
|
||
|
// CC AC PRE SUFX = max 13 digits
|
||
|
|
||
|
if( (strlen($Num)) > 13)
|
||
|
{
|
||
|
$this->ERROR = "is_phone: number is too long [$Num][$Phone]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Valid, fully qualified hostname? true or false
|
||
|
// Checks the -syntax- of the hostname, not it's actual
|
||
|
// validity as a reachable internet host
|
||
|
|
||
|
function is_hostname ($hostname = "")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
$web = false;
|
||
|
|
||
|
if(empty($hostname))
|
||
|
{
|
||
|
$this->ERROR = "is_hostname: No hostname submitted";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Only a-z, 0-9, and "-" or "." are permitted in a hostname
|
||
|
|
||
|
// Patch for POSIX regex lib by Sascha Schumann sas@schell.de
|
||
|
$Bad = eregi_replace("[-A-Z0-9\.]","",$hostname);
|
||
|
|
||
|
if(!empty($Bad))
|
||
|
{
|
||
|
$this->ERROR = "is_hostname: invalid chars [$Bad]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// See if we're doing www.hostname.tld or hostname.tld
|
||
|
if(eregi("^www\.",$hostname))
|
||
|
{
|
||
|
$web = true;
|
||
|
}
|
||
|
|
||
|
// double "." is a not permitted
|
||
|
if(ereg("\.\.",$hostname))
|
||
|
{
|
||
|
$this->ERROR = "is_hostname: Double dot in [$hostname]";
|
||
|
return false;
|
||
|
}
|
||
|
if(ereg("^\.",$hostname))
|
||
|
{
|
||
|
$this->ERROR = "is_hostname: leading dot in [$hostname]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$chunks = explode(".",$hostname);
|
||
|
|
||
|
if( (gettype($chunks)) != "array")
|
||
|
{
|
||
|
$this->ERROR = "is_hostname: Invalid hostname, no dot seperator [$hostname]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$count = ( (count($chunks)) - 1);
|
||
|
|
||
|
if($count < 1)
|
||
|
{
|
||
|
$this->ERROR = "is_hostname: Invalid hostname [$count] [$hostname]\n";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Bug that can't be killed without doing an is_host,
|
||
|
// something.something will return TRUE, even if it's something
|
||
|
// stupid like NS.SOMETHING (with no tld), because SOMETHING is
|
||
|
// construed to BE the tld. The is_bigfour and is_country
|
||
|
// checks should help eliminate this inconsistancy. To really
|
||
|
// be sure you've got a valid hostname, do an is_host() on it.
|
||
|
|
||
|
if( ($web) and ($count < 2) )
|
||
|
{
|
||
|
$this->ERROR = "is_hostname: Invalid hostname [$count] [$hostname]\n";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$tld = $chunks[$count];
|
||
|
|
||
|
if(empty($tld))
|
||
|
{
|
||
|
$this->ERROR = "is_hostname: No TLD found in [$hostname]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if(!$this->is_bigfour($tld))
|
||
|
{
|
||
|
if(!$this->is_country($tld))
|
||
|
{
|
||
|
$this->ERROR = "is_hostname: Unrecognized TLD [$tld]";
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
|
||
|
function is_bigfour ($tld)
|
||
|
{
|
||
|
if(empty($tld))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
if(eregi("^\.",$tld))
|
||
|
{
|
||
|
$tld = eregi_replace("^\.","",$tld);
|
||
|
}
|
||
|
$BigFour = array (com=>com,edu=>edu,net=>net,org=>org,gov=>gov,mil=>mil,int=>int);
|
||
|
$tld = strtolower($tld);
|
||
|
|
||
|
if(isset($BigFour[$tld]))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Hostname is a reachable internet host? true or false
|
||
|
|
||
|
function is_host ($hostname = "", $type = "ANY")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if(empty($hostname))
|
||
|
{
|
||
|
$this->ERROR = "is_host: No hostname submitted";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if(!$this->is_hostname($hostname)) { return false; }
|
||
|
|
||
|
if(!checkdnsrr($hostname,$type))
|
||
|
{
|
||
|
$this->ERROR = "is_host: no DNS records for [$hostname].";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Dotted quad IPAddress within valid range? true or false
|
||
|
// Checks format, leading zeros, and values > 255
|
||
|
// Does not check for reserved or unroutable IPs.
|
||
|
|
||
|
function is_ipaddress ($IP = "")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if(empty($IP))
|
||
|
{
|
||
|
$this->ERROR = "is_ipaddress: No IP address submitted";
|
||
|
return false;
|
||
|
}
|
||
|
// 123456789012345
|
||
|
// xxx.xxx.xxx.xxx
|
||
|
|
||
|
$len = strlen($IP);
|
||
|
if( $len > 15 )
|
||
|
{
|
||
|
$this->ERROR = "is_ipaddress: too long [$IP][$len]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$Bad = eregi_replace("([0-9\.]+)","",$IP);
|
||
|
|
||
|
if(!empty($Bad))
|
||
|
{
|
||
|
$this->ERROR = "is_ipaddress: Bad data in IP address [$Bad]";
|
||
|
return false;
|
||
|
}
|
||
|
$chunks = explode(".",$IP);
|
||
|
$count = count($chunks);
|
||
|
|
||
|
if ($count != 4)
|
||
|
{
|
||
|
$this->ERROR = "is_ipaddress: not a dotted quad [$IP]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
while ( list ($key,$val) = each ($chunks) )
|
||
|
{
|
||
|
if(ereg("^0",$val))
|
||
|
{
|
||
|
$this->ERROR = "is_ipaddress: Invalid IP segment [$val]";
|
||
|
return false;
|
||
|
}
|
||
|
$Num = $val;
|
||
|
settype($Num,"integer");
|
||
|
if($Num > 255)
|
||
|
{
|
||
|
$this->ERROR = "is_ipaddress: Segment out of range [$Num]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
|
||
|
} // end is_ipaddress
|
||
|
|
||
|
// ************************************************************
|
||
|
// IP address is valid, and resolves to a hostname? true or false
|
||
|
|
||
|
function ip_resolves ($IP = "")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if(empty($IP))
|
||
|
{
|
||
|
$this->ERROR = "ip_resolves: No IP address submitted";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if(!$this->is_ipaddress($IP))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$Hostname = gethostbyaddr($IP);
|
||
|
|
||
|
if($Hostname == $IP)
|
||
|
{
|
||
|
$this->ERROR = "ip_resolves: IP does not resolve.";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if($Hostname)
|
||
|
{
|
||
|
if(!checkdnsrr($Hostname))
|
||
|
{
|
||
|
$this->ERROR = "is_ipaddress: no DNS records for resolved hostname [$Hostname]";
|
||
|
return false;
|
||
|
}
|
||
|
if( (gethostbyname($Hostname)) != $IP )
|
||
|
{
|
||
|
$this->ERROR = "is_ipaddress: forward:reverse mismatch, possible forgery";
|
||
|
// Non-fatal, but it should be noted.
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$this->ERROR = "ip_resolves: IP address does not resolve";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ************************************************************
|
||
|
|
||
|
function browser_gen ()
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
$generation = "UNKNOWN";
|
||
|
|
||
|
$client = getenv("HTTP_USER_AGENT");
|
||
|
if(empty($client))
|
||
|
{
|
||
|
$this->ERROR = "browser_gen: No User Agent for Client";
|
||
|
return $generation;
|
||
|
}
|
||
|
|
||
|
$client = $this->strip_metas($client);
|
||
|
|
||
|
$agents = array(
|
||
|
'Anonymizer' => "ANONYMIZER",
|
||
|
'Ahoy' => "SPIDER",
|
||
|
'Altavista' => "SPIDER",
|
||
|
'Anzwers' => "SPIDER",
|
||
|
'Arachnoidea' => "SPIDER",
|
||
|
'Arachnophilia' => "SPIDER",
|
||
|
'ArchitextSpider' => "SPIDER",
|
||
|
'Backrub' => "SPIDER",
|
||
|
'CherryPicker' => "SPAMMER",
|
||
|
'Crescent' => "SPAMMER",
|
||
|
'Duppies' => "SPIDER",
|
||
|
'EmailCollector' => "SPAMMER",
|
||
|
'EmailSiphon' => "SPAMMER",
|
||
|
'EmailWolf' => "SPAMMER",
|
||
|
'Extractor' => "SPAMMER",
|
||
|
'Fido' => "SPIDER",
|
||
|
'Fish' => "SPIDER",
|
||
|
'GAIS' => "SPIDER",
|
||
|
'Googlebot' => "SPIDER",
|
||
|
'Gulliver' => "SPIDER",
|
||
|
'HipCrime' => "SPAMMER",
|
||
|
'Hamahakki' => "SPIDER",
|
||
|
'ia_archive' => "SPIDER",
|
||
|
'IBrowse' => "THIRD",
|
||
|
'Incy' => "SPIDER",
|
||
|
'InfoSeek' => "SPIDER",
|
||
|
'KIT-Fireball' => "SPIDER",
|
||
|
'Konqueror' => "THIRD",
|
||
|
'libwww' => "SECOND",
|
||
|
'LocalEyes' => "SECOND",
|
||
|
'Lycos' => "SPIDER",
|
||
|
'Lynx' => "SECOND",
|
||
|
'Microsoft.URL' => "SPAMMER",
|
||
|
'MOMspider' => "SPIDER",
|
||
|
'Mozilla/1' => "FIRST",
|
||
|
'Mozilla/2' => "SECOND",
|
||
|
'Mozilla/3' => "THIRD",
|
||
|
'Mozilla/4' => "FOURTH",
|
||
|
'Mozilla/5' => "FIFTH",
|
||
|
'Namecrawler' => "SPIDER",
|
||
|
'NICErsPRO' => "SPAMMER",
|
||
|
'Scooter' => "SPIDER",
|
||
|
'sexsearch' => "SPIDER",
|
||
|
'Sidewinder' => "SPIDER",
|
||
|
'Slurp' => "SPIDER",
|
||
|
'SwissSearch' => "SPIDER",
|
||
|
'Ultraseek' => "SPIDER",
|
||
|
'WebBandit' => "SPAMMER",
|
||
|
'WebCrawler' => "SPIDER",
|
||
|
'WiseWire' => "SPIDER",
|
||
|
'Mozilla/3.0 (compatible; Opera/3' => "THIRD"
|
||
|
);
|
||
|
|
||
|
while ( list ($key,$val) = each ($agents) )
|
||
|
{
|
||
|
$key = $this->strip_metas($key);
|
||
|
if(eregi("^$key",$client))
|
||
|
{
|
||
|
unset($agents);
|
||
|
return $val;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unset($agents);
|
||
|
return $generation;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// United States valid state code? true or false
|
||
|
|
||
|
function is_state ($State = "")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if(empty($State))
|
||
|
{
|
||
|
$this->ERROR = "is_state: No state submitted";
|
||
|
return false;
|
||
|
}
|
||
|
if( (strlen($State)) != 2)
|
||
|
{
|
||
|
$this->ERROR = "is_state: Too many digits in state code";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$State = strtoupper($State);
|
||
|
|
||
|
// 50 states, Washington DC, Puerto Rico and the US Virgin Islands
|
||
|
|
||
|
$SCodes = array (
|
||
|
|
||
|
"AK" => 1,
|
||
|
"AL" => 1,
|
||
|
"AR" => 1,
|
||
|
"AZ" => 1,
|
||
|
"CA" => 1,
|
||
|
"CO" => 1,
|
||
|
"CT" => 1,
|
||
|
"DC" => 1,
|
||
|
"DE" => 1,
|
||
|
"FL" => 1,
|
||
|
"GA" => 1,
|
||
|
"HI" => 1,
|
||
|
"IA" => 1,
|
||
|
"ID" => 1,
|
||
|
"IL" => 1,
|
||
|
"IN" => 1,
|
||
|
"KS" => 1,
|
||
|
"KY" => 1,
|
||
|
"LA" => 1,
|
||
|
"MA" => 1,
|
||
|
"MD" => 1,
|
||
|
"ME" => 1,
|
||
|
"MI" => 1,
|
||
|
"MN" => 1,
|
||
|
"MO" => 1,
|
||
|
"MS" => 1,
|
||
|
"MT" => 1,
|
||
|
"NC" => 1,
|
||
|
"ND" => 1,
|
||
|
"NE" => 1,
|
||
|
"NH" => 1,
|
||
|
"NJ" => 1,
|
||
|
"NM" => 1,
|
||
|
"NV" => 1,
|
||
|
"NY" => 1,
|
||
|
"OH" => 1,
|
||
|
"OK" => 1,
|
||
|
"OR" => 1,
|
||
|
"PA" => 1,
|
||
|
"PR" => 1,
|
||
|
"RI" => 1,
|
||
|
"SC" => 1,
|
||
|
"SD" => 1,
|
||
|
"TN" => 1,
|
||
|
"TX" => 1,
|
||
|
"UT" => 1,
|
||
|
"VA" => 1,
|
||
|
"VI" => 1,
|
||
|
"VT" => 1,
|
||
|
"WA" => 1,
|
||
|
"WI" => 1,
|
||
|
"WV" => 1,
|
||
|
"WY" => 1
|
||
|
);
|
||
|
|
||
|
if(!isset($SCodes[$State]))
|
||
|
{
|
||
|
$this->ERROR = "is_state: Unrecognized state code [$State]";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Lets not have this big monster camping in memory eh?
|
||
|
unset($SCodes);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Valid postal zip code? true or false
|
||
|
|
||
|
function is_zip ($zipcode = "")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
if(empty($zipcode))
|
||
|
{
|
||
|
$this->ERROR = "is_zip: No zipcode submitted";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$Bad = eregi_replace("([-0-9]+)","",$zipcode);
|
||
|
|
||
|
if(!empty($Bad))
|
||
|
{
|
||
|
$this->ERROR = "is_zip: Bad data in zipcode [$Bad]";
|
||
|
return false;
|
||
|
}
|
||
|
$Num = eregi_replace("\-","",$zipcode);
|
||
|
$len = strlen($Num);
|
||
|
if ( ($len > 10) or ($len < 5) )
|
||
|
{
|
||
|
$this->ERROR = "is_zipcode: Invalid length [$len] for zipcode";
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
|
||
|
}
|
||
|
|
||
|
// ************************************************************
|
||
|
// Valid postal country code?
|
||
|
// Returns the name of the country, or null on failure
|
||
|
// Current array recognizes ~232 country codes.
|
||
|
|
||
|
// I don't know if all of these are 100% accurate.
|
||
|
// You don't wanna know how difficult it was just getting
|
||
|
// this listing in here. :)
|
||
|
|
||
|
function is_country ($countrycode = "")
|
||
|
{
|
||
|
if($this->CLEAR) { $this->clear_error(); }
|
||
|
|
||
|
$Return = "";
|
||
|
|
||
|
if(empty($countrycode))
|
||
|
{
|
||
|
$this->ERROR = "is_country: No country code submitted";
|
||
|
return $Return;
|
||
|
}
|
||
|
|
||
|
$countrycode = strtolower($countrycode);
|
||
|
|
||
|
if( (strlen($countrycode)) != 2 )
|
||
|
{
|
||
|
$this->ERROR = "is_country: 2 digit codes only [$countrycode]";
|
||
|
return $Return;
|
||
|
}
|
||
|
|
||
|
// Now for a really big array
|
||
|
|
||
|
// Dominican Republic, cc = "do" because it's a reserved
|
||
|
// word in PHP. That parse error took 10 minutes of
|
||
|
// head-scratching to figure out :)
|
||
|
|
||
|
// A (roughly) 3.1 Kbyte array
|
||
|
|
||
|
$CCodes = array (
|
||
|
|
||
|
"do" => "Dominican Republic",
|
||
|
ad => "Andorra",
|
||
|
ae => "United Arab Emirates",
|
||
|
af => "Afghanistan",
|
||
|
ag => "Antigua and Barbuda",
|
||
|
ai => "Anguilla",
|
||
|
al => "Albania",
|
||
|
am => "Armenia",
|
||
|
an => "Netherlands Antilles",
|
||
|
ao => "Angola",
|
||
|
aq => "Antarctica",
|
||
|
ar => "Argentina",
|
||
|
"as" => "American Samoa",
|
||
|
at => "Austria",
|
||
|
au => "Australia",
|
||
|
aw => "Aruba",
|
||
|
az => "Azerbaijan",
|
||
|
ba => "Bosnia Hercegovina",
|
||
|
bb => "Barbados",
|
||
|
bd => "Bangladesh",
|
||
|
be => "Belgium",
|
||
|
bf => "Burkina Faso",
|
||
|
bg => "Bulgaria",
|
||
|
bh => "Bahrain",
|
||
|
bi => "Burundi",
|
||
|
bj => "Benin",
|
||
|
bm => "Bermuda",
|
||
|
bn => "Brunei Darussalam",
|
||
|
bo => "Bolivia",
|
||
|
br => "Brazil",
|
||
|
bs => "Bahamas",
|
||
|
bt => "Bhutan",
|
||
|
bv => "Bouvet Island",
|
||
|
bw => "Botswana",
|
||
|
by => "Belarus (Byelorussia)",
|
||
|
bz => "Belize",
|
||
|
ca => "Canada",
|
||
|
cc => "Cocos Islands",
|
||
|
cd => 'Congo, The Democratic Republic of the',
|
||
|
cf => "Central African Republic",
|
||
|
cg => "Congo",
|
||
|
ch => "Switzerland",
|
||
|
ci => "Ivory Coast",
|
||
|
ck => "Cook Islands",
|
||
|
cl => "Chile",
|
||
|
cm => "Cameroon",
|
||
|
cn => "China",
|
||
|
co => "Colombia",
|
||
|
cr => "Costa Rica",
|
||
|
cs => "Czechoslovakia",
|
||
|
cu => "Cuba",
|
||
|
cv => "Cape Verde",
|
||
|
cx => "Christmas Island",
|
||
|
cy => "Cyprus",
|
||
|
cz => 'Czech Republic',
|
||
|
de => "Germany",
|
||
|
dj => "Djibouti",
|
||
|
dk => 'Denmark',
|
||
|
dm => "Dominica",
|
||
|
dz => "Algeria",
|
||
|
ec => "Ecuador",
|
||
|
ee => "Estonia",
|
||
|
eg => "Egypt",
|
||
|
eh => "Western Sahara",
|
||
|
er => 'Eritrea',
|
||
|
es => "Spain",
|
||
|
et => "Ethiopia",
|
||
|
fi => "Finland",
|
||
|
fj => "Fiji",
|
||
|
fk => "Falkland Islands",
|
||
|
fm => "Micronesia",
|
||
|
fo => "Faroe Islands",
|
||
|
fr => "France",
|
||
|
fx => 'France, Metropolitan FX',
|
||
|
ga => "Gabon",
|
||
|
gb => 'United Kingdom (Great Britain)',
|
||
|
gd => "Grenada",
|
||
|
ge => "Georgia",
|
||
|
gf => "French Guiana",
|
||
|
gh => "Ghana",
|
||
|
gi => "Gibraltar",
|
||
|
gl => "Greenland",
|
||
|
gm => "Gambia",
|
||
|
gn => "Guinea",
|
||
|
gp => "Guadeloupe",
|
||
|
gq => "Equatorial Guinea",
|
||
|
gr => "Greece",
|
||
|
gs => 'South Georgia and the South Sandwich Islands',
|
||
|
gt => "Guatemala",
|
||
|
gu => "Guam",
|
||
|
gw => "Guinea-bissau",
|
||
|
gy => "Guyana",
|
||
|
hk => "Hong Kong",
|
||
|
hm => "Heard and McDonald Islands",
|
||
|
hn => "Honduras",
|
||
|
hr => "Croatia",
|
||
|
ht => "Haiti",
|
||
|
hu => "Hungary",
|
||
|
id => "Indonesia",
|
||
|
ie => "Ireland",
|
||
|
il => "Israel",
|
||
|
in => "India",
|
||
|
io => "British Indian Ocean Territory",
|
||
|
iq => "Iraq",
|
||
|
ir => "Iran",
|
||
|
is => "Iceland",
|
||
|
it => "Italy",
|
||
|
jm => "Jamaica",
|
||
|
jo => "Jordan",
|
||
|
jp => "Japan",
|
||
|
ke => "Kenya",
|
||
|
kg => "Kyrgyzstan",
|
||
|
kh => "Cambodia",
|
||
|
ki => "Kiribati",
|
||
|
km => "Comoros",
|
||
|
kn => "Saint Kitts and Nevis",
|
||
|
kp => "North Korea",
|
||
|
kr => "South Korea",
|
||
|
kw => "Kuwait",
|
||
|
ky => "Cayman Islands",
|
||
|
kz => "Kazakhstan",
|
||
|
la => "Laos",
|
||
|
lb => "Lebanon",
|
||
|
lc => "Saint Lucia",
|
||
|
li => "Lichtenstein",
|
||
|
lk => "Sri Lanka",
|
||
|
lr => "Liberia",
|
||
|
ls => "Lesotho",
|
||
|
lt => "Lithuania",
|
||
|
lu => "Luxembourg",
|
||
|
lv => "Latvia",
|
||
|
ly => "Libya",
|
||
|
ma => "Morocco",
|
||
|
mc => "Monaco",
|
||
|
md => "Moldova Republic",
|
||
|
mg => "Madagascar",
|
||
|
mh => "Marshall Islands",
|
||
|
mk => 'Macedonia, The Former Yugoslav Republic of',
|
||
|
ml => "Mali",
|
||
|
mm => "Myanmar",
|
||
|
mn => "Mongolia",
|
||
|
mo => "Macau",
|
||
|
mp => "Northern Mariana Islands",
|
||
|
mq => "Martinique",
|
||
|
mr => "Mauritania",
|
||
|
ms => "Montserrat",
|
||
|
mt => "Malta",
|
||
|
mu => "Mauritius",
|
||
|
mv => "Maldives",
|
||
|
mw => "Malawi",
|
||
|
mx => "Mexico",
|
||
|
my => "Malaysia",
|
||
|
mz => "Mozambique",
|
||
|
na => "Namibia",
|
||
|
nc => "New Caledonia",
|
||
|
ne => "Niger",
|
||
|
nf => "Norfolk Island",
|
||
|
ng => "Nigeria",
|
||
|
ni => "Nicaragua",
|
||
|
nl => "Netherlands",
|
||
|
no => "Norway",
|
||
|
np => "Nepal",
|
||
|
nr => "Nauru",
|
||
|
nt => "Neutral Zone",
|
||
|
nu => "Niue",
|
||
|
nz => "New Zealand",
|
||
|
om => "Oman",
|
||
|
pa => "Panama",
|
||
|
pe => "Peru",
|
||
|
pf => "French Polynesia",
|
||
|
pg => "Papua New Guinea",
|
||
|
ph => "Philippines",
|
||
|
pk => "Pakistan",
|
||
|
pl => "Poland",
|
||
|
pm => "St. Pierre and Miquelon",
|
||
|
pn => "Pitcairn",
|
||
|
pr => "Puerto Rico",
|
||
|
pt => "Portugal",
|
||
|
pw => "Palau",
|
||
|
py => "Paraguay",
|
||
|
qa => 'Qatar',
|
||
|
re => "Reunion",
|
||
|
ro => "Romania",
|
||
|
ru => "Russia",
|
||
|
rw => "Rwanda",
|
||
|
sa => "Saudi Arabia",
|
||
|
sb => "Solomon Islands",
|
||
|
sc => "Seychelles",
|
||
|
sd => "Sudan",
|
||
|
se => "Sweden",
|
||
|
sg => "Singapore",
|
||
|
sh => "St. Helena",
|
||
|
si => "Slovenia",
|
||
|
sj => "Svalbard and Jan Mayen Islands",
|
||
|
sk => 'Slovakia (Slovak Republic)',
|
||
|
sl => "Sierra Leone",
|
||
|
sm => "San Marino",
|
||
|
sn => "Senegal",
|
||
|
so => "Somalia",
|
||
|
sr => "Suriname",
|
||
|
st => "Sao Tome and Principe",
|
||
|
sv => "El Salvador",
|
||
|
sy => "Syria",
|
||
|
sz => "Swaziland",
|
||
|
tc => "Turks and Caicos Islands",
|
||
|
td => "Chad",
|
||
|
tf => "French Southern Territories",
|
||
|
tg => "Togo",
|
||
|
th => "Thailand",
|
||
|
tj => "Tajikistan",
|
||
|
tk => "Tokelau",
|
||
|
tm => "Turkmenistan",
|
||
|
tn => "Tunisia",
|
||
|
to => "Tonga",
|
||
|
tp => "East Timor",
|
||
|
tr => "Turkey",
|
||
|
tt => "Trinidad, Tobago",
|
||
|
tv => "Tuvalu",
|
||
|
tw => "Taiwan",
|
||
|
tz => "Tanzania",
|
||
|
ua => "Ukraine",
|
||
|
ug => "Uganda",
|
||
|
uk => "United Kingdom",
|
||
|
um => "United States Minor Islands",
|
||
|
us => "United States of America",
|
||
|
uy => "Uruguay",
|
||
|
uz => "Uzbekistan",
|
||
|
va => "Vatican City",
|
||
|
vc => "Saint Vincent, Grenadines",
|
||
|
ve => "Venezuela",
|
||
|
vg => "Virgin Islands (British)",
|
||
|
vi => "Virgin Islands (USA)",
|
||
|
vn => "Viet Nam",
|
||
|
vu => "Vanuatu",
|
||
|
wf => 'Wallis and Futuna Islands',
|
||
|
ws => "Samoa",
|
||
|
ye => 'Yemen',
|
||
|
yt => 'Mayotte',
|
||
|
yu => "Yugoslavia",
|
||
|
za => "South Africa",
|
||
|
zm => "Zambia",
|
||
|
zr => "Zaire",
|
||
|
zw => "Zimbabwe"
|
||
|
);
|
||
|
|
||
|
|
||
|
if(isset($CCodes[$countrycode]))
|
||
|
{
|
||
|
$Return = $CCodes[$countrycode];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$this->ERROR = "is_country: Unrecognized country code [$countrycode]";
|
||
|
$Return = "";
|
||
|
}
|
||
|
|
||
|
// make sure this monster is removed from memory
|
||
|
|
||
|
unset($CCodes);
|
||
|
|
||
|
return ($Return);
|
||
|
|
||
|
} // end is_country
|
||
|
|
||
|
} // End class
|
||
|
|
||
|
?>
|