Location: PHPKode > projects > ADbNewsSender > ADbNewsSender 2.1.0/protected/skeleton/public_apis.class.php.inc
<?php
/* 
    Last change in version: 2.1 Alpha 4
#########################################################################################
#    ADbNewsSender 2 									#
#    Copyright (C) 2010 Florian Grannemann (E-mail: hide@address.com)  		#
#    Website: http://adbnewssender.sf.net						#
#	                								#
#    This program is free software: you can redistribute it and/or modify		#
#    it under the terms of the GNU General Public License as published by		#
#    the Free Software Foundation, either version 3 of the License, or			#
#    any later version.									#
#											#
#    This program is distributed in the hope that it will be useful,			#
#    but WITHOUT ANY WARRANTY; without even the implied warranty of			#
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the			#
#    GNU General Public License for more details.					#
#											#
#    You should have received a copy of the GNU General Public License			#
#    along with this program.  If not, see http://www.gnu.org/licenses/			#
#########################################################################################
	
*/
/*
	This file defines public apis for database acces, (read only) access to newsletters and configuration settings  
	
*/

//Database Access API: ADbNewsSender Database
//It uses the PHP functions/APIs of the supported Database Systems in the database definition files.
class ADBNS_DB
{
	private $session="";
	private $type ="";
	private $DB_name ="";
	private $DB_serv="";
	private $DB_usr="";
	private $DB_pwd="";
	private $DB_definitions="";
	
	

	//private method: call_db_function:
	//It calls the  needed database function ($function_name).
	//$default_return_value is the default return value for the called function.
	//The optional parameter $querystring may be used for querys or other purposes.
	//The called db function has to store it's result value(s) in $result 
	//you may use $params as normal variable or as an array (for multible parameters)
	//$querystring may be used as main parameter for the called db function.
	//$params may be used for additional parameters, e.g as an array of parameters.
	private function call_db_function($function_name, $default_return_value, $querystring=NULL, $params=NULL)
	{
		
		
		$result=$default_return_value;
		if(!@include ($this->DB_definitions."/defs.php.inc"))
		{
			//echo ("ADBNS_DB: ERROR: Could not open path to database definitions directory (".$this->DB_definitions."/defs.php.inc)!  (In file: ".__FILE__.", line: ".__LINE__.")");
			//exit(false);
			user_error("ADBNS_DB: ERROR: Could not open path to database definitions directory (".$this->DB_definitions."/defs.php.inc) in method: <b>".__METHOD__."</b>!" , E_USER_ERROR);

		}
		 
		if(!$db_defs[$this->type])
		{	
			user_error("ADBNS_DB: ERROR: Selected database type '".$this->type."' is not supported! (In method: <b>".__METHOD__."</b>)",E_USER_ERROR); 
			
		}
		
		if(!@include ($this->DB_definitions."/".$db_defs[$this->type][$function_name]))
		{	
			//print $this->DB_definitions."/".$db_defs[$this->type][$function_name]."<br>";
			user_error("ADBNS_DB: ERROR: Could not include ".$function_name." definitions for \"".$this->type."\" !  (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);
			
			
		}
		
		return $result;
	}	
	
	function set_DB_options($db_type, $db_server, $db_name, $db_user, $db_password)
	{
		
		
		$this->type=strtolower($db_type);
 		$this->DB_name=$db_name;
		$this->DB_serv=$db_server;
		$this->DB_usr=$db_user;
		$this->DB_pwd=$db_password;
		
	}


	function __construct($path_to_db_definitions, $path_to_DB_conf=NULL)
	{	
		if($path_to_DB_conf !=NULL)
		{	
			
			if(!file_exists($path_to_DB_conf) || preg_match("/^[0-9]+:[X-Z]+$/D",$path_to_DB_conf) )
			{
				user_error("ADBNS_DB: ERROR: Could not include database config file ($path_to_DB_conf)! (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);
				
			}
			@include_once $path_to_DB_conf;
			$this->set_DB_options($db_type, $db_server, $db_name, $db_user, $db_password);
 			
		}
		 
		if(!isset($path_to_db_definitions) || preg_match("/^[0-9]+:[X-Z]+$/D",$path_to_db_definitions))
		{
			user_error("ADBNS_DB: ERROR: You have to provide the path to database definitions directory! (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);
			

		}
		else
		{
				
			if (!file_exists($path_to_db_definitions."/defs.php.inc"))
			{
				user_error("ADBNS_DB: ERROR: Could not database definitions file  ($path_to_db_definitions/defs.php.inc)!  (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);
				

			}
			$this->DB_definitions=$path_to_db_definitions;
		}


	}

	

	function get_DB_Type()
	{
		return $this->type;
	}



	function connect()
	{	
		
		
		return $this->call_db_function("connect",FALSE);		
		
	}

	function query($querystring)
	{
		//do we have an active connection?
		if(!$this->session)
		{
			//no:
			user_error("ADBNS_DB: WARNING: Database query without active connection! You have to connect to database first!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
			return false;

		}
		
		
		return $this->call_db_function("query", NULL, $querystring);
	}

	function get_last_insert_ID()
	{
		if(!$this->session)
		{
			//no:
			user_error("ADBNS_DB: WARNING: This operation requires an active connection! You have to connect to database first!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
			return false;

		}


		return $this->call_db_function("get_last_insert_id", NULL);

	}
	function fetch_row($result)
	{
		
		if(!$result)
		{
			
			user_error("ADBNS_DB: WARNING: Invalid SQL-result! (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
			return false;

		}

		return $this->call_db_function("fetch_row", FALSE, $result);
		
	}

	function fetch_array($result, $result_type=NULL)
	{
		
		if(!$result)
		{
			
			user_error("ADBNS_DB: WARNING: Invalid SQL-result! (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
			return false;

		}
		return $this->call_db_function("fetch_array", FALSE, $result,$result_type);
	}
	function fetch_object($result)
	{
		if(!$result)
		{
			
			user_error("ADBNS_DB: WARNING: Invalid SQL-result! (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
			return false;

		}
		return $this->call_db_function("fetch_object", FALSE, $result);
		
	}

	function disconnect()
	{
		
		return $this->call_db_function("disconnect", FALSE);	

	}

	function setSessionID($newSession)
	{
		$this->session=$newSession;
	}


	function getSessionID()
	{
		return $this->session;
	}

	function is_connected()
	{
		if(!$this->session)
		{
			return false;
		}
		
		
		return $this->call_db_function("is_connected", true);
		
	}
	function connect_if_not_connected(){
	    //connect to db if not connected
	    if(!$this->is_connected()){
		if(!@$this->connect()){				
		    return false;
		}
	    }
	    return true;
	}
	function real_escape_string($querystring)
	{
		return $this->call_db_function("real_escape_string", $querystring, $querystring);
	}
	
	function last_db_error()
	{
		if(!$this->session)
		{
			//no:
			user_error("ADBNS_DB: WARNING: This operation requires an active connection! You have to connect to database first!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
			return " ";

		}
		return $this->call_db_function("last_db_error", "");

	}

	function create_table($tablename,$columns,$defaults=array(),$PKs="",$UKs="",$null=array())
	{
		//$tablename=strtolower($tablename);
		if(!$this->session)
		{
			//no:
			user_error("ADBNS_DB: WARNING: This operation requires an active connection! You have to connect to database first!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
			return false;

		}
		
		if(!isset($tablename))
		{
			user_error("ADBNS_DB: WARNING: Error: No table name specified!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
			return false;

			
		}
		if(count($columns) <1)
		{
			user_error("ADBNS_DB: WARNING: Error: No columns specified!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
			return false;


		}

		$number_of_serials=0;
		//Making sure, that fieldnames are lower case for compatibility reasons:
		$columnss_lower=array();
		foreach($columns as $columnname =>$datatype)
		{
			$datatype=preg_replace("/ /","",$datatype);
			$datatype=$datatype."|";
			
			$columns_lower[strtolower($columnname)]=$datatype;
			
		}		 
		
		
		//$columns["columnname"]="Datatype|size";
		//size is only needed for varchar.

		//primary key
		//$PKs="column1,column2..."
		//not allowed for text!

		//unique key:
		//$UKs="column1,column2..."
		//not allowed for integer  field or if already pk

		$PKs=preg_replace("/ /","",$PKs);
		$UKs=preg_replace("/ /","",$UKs);
		$null=preg_replace("/ /","",$null);
		$PKs=$PKs.",";
		$UKs=$UKs.",";
		

		$PKs=explode(",",$PKs);
		$UKs=explode(",",$UKs);
		
		//allowed datatypes =type (numeric or string):
		$datatypes=array();
		$datatypes["bigserial"]="numeric";
		$datatypes["serial"]="numeric";
		$datatypes["float"]="numeric";
		$datatypes["float8"]="numeric";
		$datatypes["boolean"]="numeric";
		$datatypes["text"]="string";
		$datatypes["varchar"]="string";
		$datatypes["integer"]="numeric";
		$datatypes["bigint"]="numeric";
		//checking params
		foreach($columns_lower as $columnname => $datatype)
		{

			
			
			//does the datatype exist?
			$tmp_datatype=explode("|",$datatype);
			
			if(!$datatypes[strtolower($tmp_datatype[0])])
			{
				//no: returning false and throwing a user warning:
				user_error("ADBNS_DB: WARNING: Unknown datatype ".$tmp_datatype[0]." for column '$columnname'!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
				return false;
			}	

			if(in_array($columnname,$PKs) && in_array($columnname,$UKs))
			{

				
				user_error("ADBNS_DB: WARNING: It is not allowed to set '$columnname' as Primary Key and Unique Key at the same time!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
				return false;
			}
			
			if(strtolower($tmp_datatype[0])=="serial" || strtolower($tmp_datatype[0])=="bigserial" )
			{
				
				$number_of_serials++;
				if(($number_of_serials >1) || !in_array($columnname,$PKs))
				{
					
					user_error("ADBNS_DB: WARNING: Only one (big)serial column is allowed and it has to be a primary key!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
					return false;

				}
		
			}
			

			if(strtolower($tmp_datatype[0])=="text" && in_array($columnname,$PKs))
			{

				//no: returning false and throwing a user warning:
				user_error("ADBNS_DB: WARNING: It is not allowed to set a text field as Primary Key (column:'$columnname')!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
				return false;
			}

			if($datatypes[strtolower($tmp_datatype[0])]=="numeric" && in_array($columnname,$UKs))
			{
				user_error("ADBNS_DB: WARNING: It is not allowed to set a ".$tmp_datatype[0]." field as Unique Key (column:'$columnname')!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
				return false;				

			}
			
			if((strtolower($tmp_datatype[0])=="serial"|| strtolower($tmp_datatype[0])=="bigserial") && $defaults[$columnname] )
			{
				if($datatypes[strtolower($tmp_datatype[0])]=="numeric" && in_array($columnname,$UKs))
				{
					user_error("ADBNS_DB: WARNING: It is not allowed to set a Default value for ".$tmp_datatype[0]." datatypes (column:'$columnname')!  (In method: <b>".__METHOD__."</b>)",E_USER_WARNING ); 
					return false;				

				}
			
			}

		}


		$params=array();

		$params["columns"]=$columns_lower;
		$params["PKs"]=array_unique($PKs);
		$params["UKs"]=array_unique($UKs);
		$params["defaults"]=$defaults;
		$params["null"]=$null;
	
		return $this->call_db_function("create_table", false, $tablename,$params);
		
	}
	function drop_table($tablename)
	{
	  
		if(!isset($tablename))
		{
			  
			return false;
		}
		return $this->call_db_function("drop_table",false,$tablename);
	}
	function rename_table($old_tablename, $new_tablename)
	{
	    if(!isset($old_tablename) || !isset($new_tablename))
	    {
		return false;
	    }
	    return $this->call_db_function("rename_table",false,$old_tablename,$new_tablename);

	}
	function replace_into($tablename, $columns)
	{
		if(!isset($tablename))
		{
			return false;
		}
		
	
		return $this->call_db_function("replace_into",false,$tablename,$columns);


	}

	function insert_into($tablename, $columns)
	{
		if(!isset($tablename))
		{
			return false;
		}
		$params=array();
	
		
		
		
		return $this->call_db_function("insert_into",false,$tablename,$columns);

	}

	
	
	function __destruct()
	{
		$this->disconnect();
		
	}

	
	

}

/********************************************************************************************************************************************
# API for public (read only) access to global config settings                 								    #
*********************************************************************************************************************************************/

class global_config_ro
{
	
protected $DB=NULL;
	function __construct($DB_object)
	{
		if($DB_object !=NULL)
		{
			
			$this->DB=$DB_object;
		 
		}
		else
		{
			user_error("global_config_ro: ERROR: please provide a valid reference to an existing object of ADBNS_DB!  (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);

		}
	}
	function get_config_value($key)
	{
		$this->DB->connect_if_not_connected();
		$result="";
		
		$res=$this->DB->query("Select value from ADBNS2_global_config_table where name='".$this->DB->real_escape_string($key)."';");
		if($row=@$this->DB->fetch_row($res))
		{
			$result=$row[0];
		}
		
		return $result;
		
	}
	function get_all_config_settings()
	{
		$this->DB->connect_if_not_connected();
		
		$result=array();
		
		$res=$this->DB->query("Select name, value from ADBNS2_global_config_table;");
		while($row=$this->DB->fetch_row($res))
		{
						

			$result[$row[0]]=$row[1];
		}
		
		return $result;
	}
	
	function NL_exists($NLID)
	{
		$NLID=intval($NLID);
		if($NLID <1)
		{
			return false;
		}
		
		$this->DB->connect_if_not_connected();

		$result=false;
		
		$res=$this->DB->query("Select id from ADBNS2_Newsletters where id = ".$NLID.";");
		if($row=@$this->DB->fetch_row($res))
		{
			if($row[0]==$NLID)
			{
				$result=true;
			}
		}	
		
		
		return $result;

	}
	function get_all_newsletters()
	{
		$result=array();
		$this->DB->connect_if_not_connected();
		
		$i=0;
		$res=$this->DB->query("Select id from ADBNS2_Newsletters;");
		while($row=@$this->DB->fetch_row($res))
		{
			
			$result[$i]=$row[0];
			$i++;
		}
		
				
		return $result;
	}

	function get_timezone()
	{
		$TimeZone=date("T");
		if($TimeZone !="UTC")
		{
			$TimeZone=$TimeZone." (UTC ".date("O").") ";
		}		
		return $TimeZone;
	}
	function get_NL_name($NLID)
	{
		//return codes:
		//-2 : Invalid NL ID
		//-1 : NL does not exist
		//0  : DB error
		//String: NL name


		if($NLID <1 || !isset($NLID))
		{
			return -2;
		}
	
		if(!$this->DB->connect_if_not_connected()){
		    return 0;
		}

		$NLID=intval($NLID);
		if(!$this->NL_exists($NLID))
		{
			return -1;
		}
		$res=$this->DB->query("Select value from ADBNS2_NL_Config_Table_$NLID where name='NL_name';");
		if(@($result=$this->DB->fetch_row($res)))
		{
			
			return $result[0];
		}
		
				
		return 0;
	}
	function setTimeZone()
	{
	    $TimeZone=trim($this->get_config_value("UseTimeZone"));
	    if($TimeZone != "" && $TimeZone !="default")
	    {
		@date_default_timezone_set($TimeZone);
	    }
	}

	function getCurrentVersion($option="complete"){
	    //params:
	    //option: 
	    //"complete": return complete version
	    //"ignoreUnstable": ignore unstable addition and milestones
	    $currentVersion=$this->get_config_value("Version");
	
	    if($option=="ignoreUnstable"){
		if(preg_match("/ /",$currentVersion))
		{
		    $currentVersionArr=@explode(" ",$currentVersion);
		    $currentVersion=$currentVersionArr[0];
		    
		}
	    }
	    
	    
	    return $currentVersion;
	}

	function version_smaller_than($version)
	{
		//returns true if $version is smaller than the current ADBNS2 Version
		$currentVersion=$this->getCurrentVersion("ignoreUnstable");
		
		//ignoring types and milestones of unstable versions:
		if(preg_match("/ /",$version))
		{
		   
		    $version_arr=@explode(" ",$version);
		    $version=$version_arr[0];
		   
		}
		
		$version=explode(".",$version);
		$currentVersion=explode(".",$currentVersion);
		if(($version[0] <$currentVersion[0]) || (($version[0]==$currentVersion[0]) &&($version[1]<$currentVersion[1])) || (($version[0]==$currentVersion[0]) &&($version[1]==$currentVersion[1]) &&($version[2]<$currentVersion[2])))
		{
			
			return true;
		}	

		return false;
	}

	function version_greater_than($version)
	{	
		//returns true if $version is greater than the current ADBNS2 version
		//ignoring types and milestones of unstable versions:
		if(preg_match("/ /",$version))
		{
		   
		    $version_arr=@explode(" ",$version);
		    $version=$version_arr[0];
		   
		}
		return(($this->getCurrentVersion("ignoreUnstable")!=$version && !$this->version_smaller_than($version))); 
	}
	
	function main_version_is_equal($version)
	{
		$version=explode(".",$version);
		$currentVersion=explode(".",$this->get_config_value("Version"));

	
		if(($version[0] == $currentVersion[0]) && ($version[1] == $currentVersion[1]))
		{
		    return true;
		}	

		return false;
	}
	
}
//********************************************************************************************************************
//API for public Newsletter access:
//********************************************************************************************************************
class pub_Newsletter
{
	
protected $DB=NULL;
protected $ID=NULL;

	function __construct($NLID,$DB_object)
	{	
		$NLID=intval($NLID);
		if($NLID <1)
		{
			
			user_error("pub_Newsletter: ERROR: please provide a valid newsletter ID!  (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);

		}
		
				
		if($DB_object==NULL)
		{
			user_error("pub_Newsletter: ERROR: Invalid Database Object.  (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);
	
		}
			
		$this->DB=$DB_object;
		$this->DB->connect_if_not_connected();
		
		
		$res=$this->DB->query("Select id from ADBNS2_Newsletters where id = ".$this->DB->real_escape_string($NLID).";");
		$row=@$this->DB->fetch_row($res);
		
		if($row[0]!=$NLID)
		{
		    user_error("pub_Newsletter: ERROR: Newsletter with ID $NLID does not exist!  (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);
	
		}
		
		$this->ID=$NLID;
	}

	function create_randcode($sizeofRandCode, $init_randg=true)
	{
		if($init_randg==true)
		{
			srand((double)microtime()*10000000);  //initialising random number generator	
		}
		//creating string with all characters that are allowed in the codeword (Do NOT use "<",">",";" ":", "-" "=","?","$","&","*" or umlauts or other special characters as possible characters!):	
		$codestring="a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z-A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-Z-1-2-3-4-5-6-7-8-9";

		// exploding string to an array:
		$codearray=explode("-",$codestring);
	
		//initialising running-variable and randomcode-variable:
		$i=0;
		$randword="";

		//counting number of characters
		$NumOfChars=count($codearray)-1;

		//creating a array that contains the characters in a random order	
		$rand_arr=array_rand($codearray, $NumOfChars);

		while ($i <=$NumOfChars)
		{
			$rand_codearray[$i]=$codearray[$rand_arr[$i]];
		
			$i++;

		}

		$i=1; 
	
		//creating a random word with the given size
		while($i<=$sizeofRandCode)
		{
			//generate a random number between 0 and the number of potential characters in random order array
                	//and using the characters, selected randomly, in our random code. 
			$randword.=$rand_codearray[rand(0,$NumOfChars)];
			$i++;
		}


		//returning random word.	
		return $randword;
		
	}

	function on_ML($email)
	{
		$result=false;
		//checking for unwanted characters in email address (to avoid possible security risks):
		if((preg_match("/\n/", $email) || preg_match("/,/", $email) ||preg_match("/;/", $email) || preg_match("/:/", $email) || preg_match("/'/", $email) || preg_match("/</", $email) || preg_match("/>/", $email) || preg_match("/\"/", $email) || preg_match("/ /", $email)))
		{
			
			return false;
		}		
		//is the e-mail address in a correct format?
		if(!preg_match("/^.+@.+\\..+/", $email))
		{
			
			// if not:
			return false;
		}
			
		if(isset($email))
		{
			$email=strtolower($email);
			if(!$this->DB->is_connected())
			{
				$this->DB->connect();
			}
			
		
			$res=$this->DB->query("Select email from ADBNS2_Mailinglist_".$this->ID." where email='".$this->DB->real_escape_string($email)."';");
			if($row=@$this->DB->fetch_row($res))
			{
				if($row[0]==$email)
				{
					return true;
				}
			}

		
		}
		return $result;	
	}

	function on_PL($email)
	{
		//checking for unwanted characters in email address (to avoid possible security risks):
		if((preg_match("/\n/", $email) || preg_match("/,/", $email) ||preg_match("/;/", $email) || preg_match("/:/", $email) || preg_match("/'/", $email) || preg_match("/</", $email) || preg_match("/>/", $email) || preg_match("/\"/", $email) || preg_match("/ /", $email)))
		{
			
			return false;
		}		
		//is the e-mail address in a correct format?
		if(!preg_match("/^.+@.+\\..+/", $email))
		{
			
			// if not:
			return false;
		}

		$result=false;
		if(isset($email))
		{
			$email=strtolower($email);
			$this->DB->connect_if_not_connected();
			
			$res=$this->DB->query("Select email from ADBNS2_Pendinglist_".$this->ID." where email='".$this->DB->real_escape_string($email)."';");
			if($row=@$this->DB->fetch_row($res))
			{
				if($row[0]==$email)
				{
					return true;
				}
			}

		}
		return $result;	
	}


	function email_address_exists($email)
	{
		if($this->on_PL($email) || $this->on_ML($email))
		{
			return true;
		}
		return false;
	}

	function get_NLconfig_setting($key)
	{
		$this->DB->connect_if_not_connected();
		$result="";
		
		$res=$this->DB->query("Select value from ADBNS2_NL_Config_Table_".$this->ID." where name='".$this->DB->real_escape_string($key)."';");
		if($row=@$this->DB->fetch_row($res))
		{
			$result=$row[0];
		}
		
		return $result;
		
	}

	function get_all_NLconfig_settings()
	{
		$this->DB->connect_if_not_connected();
		
		$result=array();
		
		$res=$this->DB->query("Select name, value from ADBNS2_NL_Config_Table_".$this->ID.";");
		while($row=$this->DB->fetch_row($res))
		{
			
			$result[$row[0]]=$row[1];
		}
		
		return $result;

	}
	function add_to_PL($email, $IP, $path_to_confirmation_email)
	{
		//possible return codes:
		//-6: Max number of equal IP addresses has been reached
		//-5: invalid/empty email address
		//-4: invalid/empty IP address
		//-3: Could not include Confirmation e-mail
		//-2: already on ML 
		//-1: already on PL
		//0: no/failed DB-connection
		//>0: success, returning ID of new PL entry.

		
		
		//Validation area:
		if(!isset($email))
		{
			
			return -5;
		}
		$email=strtolower($email);
		//is the e-mail address in a correct format?
		if(!preg_match("/^.+@.+\\..+/", $email))
		{
			
			// if not:
			return -5;
		}

		//Let's see if there is EXACTLY one @ in the address:
		if(substr_count($email, "@") != 1)
		{
		    //if not: return
		    return -5;
		}

		//checking for unwanted characters in email address (to avoid possible security risks):
		if((preg_match("/\n/", $email) || preg_match("/,/", $email) ||preg_match("/;/", $email) || preg_match("/:/", $email) || preg_match("/'/", $email) || preg_match("/</", $email) || preg_match("/>/", $email) || preg_match("/\"/", $email) || preg_match("/ /", $email)))
		{
			
			return -5;
		}		
		

		if(!isset($IP))
		{
			
			return -4;
		}
		
		

		if(!(@include $path_to_confirmation_email) || !isset($path_to_confirmation_email))
		{
			return -3;
		}
		
		$result=0;
		if($this->on_ML($email))
		{
			$result=-2;
			return $result;
		}
		
		if($this->on_PL($email))
		{
			$result=-1;
			return $result;
		}
		
		
		if(!$this->DB->connect_if_not_connected()){
		    return 0;
		}
		//fetching Max number of eq ip addresses
		$Max_no_of_eq_IP_Addr=$this->get_NLconfig_setting("Max_no_of_eq_IP_Addr_on_PL");
		if(intval($Max_no_of_eq_IP_Addr) >0)
		{
		    //if Max number of eq ip addresses is enabled:
		    //fetching number of entries with the IP address $IP
		    $res=@$this->DB->query("Select count(*) from ADBNS2_Pendinglist_".$this->ID." where ip='".$this->DB->real_escape_string($IP)."';");
		    $row=@$this->DB->fetch_row($res);
		 
		    if($row[0] >= intval($Max_no_of_eq_IP_Addr))
		    {
			
			$result=-6;
			return $result;
		    }
		}
	    
		$random=$this->create_randcode(18);
		$dateTS=time();
		$expires=strtotime("+".$this->get_NLconfig_setting("Time_on_PL")." day");
	
		$cur_date=date($dateformat,$dateTS);
		$cur_time=date($timeformat,$dateTS);
		$date_expires=date($dateformat,$expires);
		$time_expires=date($timeformat,$expires);
		
		//getting current URL:
		$Ordered_from="http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
		
		//Because we will need access to global config settings:
		$tmp_globalCF=new global_config_ro($this->DB);

		$columns=array();
		$columns["email"]=$this->DB->real_escape_string($email);
		$columns["randomcode"]=$random;
		$columns["ip"]=$this->DB->real_escape_string($IP);
		$columns["timestamp_entry"]=$dateTS;
		$columns["timestamp_expires"]=$expires;
		$columns["numberofattempts"]=0;	
		if(@($this->DB->insert_into("ADBNS2_Pendinglist_".$this->ID,$columns)))
		{
			
			//retrieving id number: 
			
			$result=$this->DB->get_last_insert_ID();
			if($result==0)
			{
				//if get_last_inster_ID() is not supported:
				$res=$this->DB->query("Select id from ADBNS2_Pendinglist_".$this->ID." Where email='".$this->DB->real_escape_string($email)."';");
				$row=$this->DB->fetch_row($res);

				$result=$row[0];
			}
			//preparing subject for confirmation mail:
			
			//for placeholdes of NL settings:
			$send_subject=preg_replace("/<-nl_name->/",html_entity_decode($this->get_NLconfig_setting("NL_name")),$subject);

			//preparing mailtext for confirmation mail:
			$NlID=$this->ID;
			$send_mailtext=preg_replace("/<-nl_name->/",html_entity_decode($this->get_NLconfig_setting("NL_name")),$mailtext);	
			$send_mailtext=preg_replace("/<-nl_email->/",$this->get_NLconfig_setting("Email"),$send_mailtext);	
			$send_mailtext=preg_replace("/<-time_on_ML->/",$this->get_NLconfig_setting("Time_on_ML"),$send_mailtext);		$send_mailtext=preg_replace("/<-ID->/","$NlID",$send_mailtext);

			//for placeholders of global settings:
			$send_mailtext=preg_replace("/<-ConfirmationURL->/",$tmp_globalCF->get_config_value("ConfirmationURL"),$send_mailtext); 
			$send_mailtext=preg_replace("/<-WebsiteURL->/",$tmp_globalCF->get_config_value("URL"),$send_mailtext); 
			$send_mailtext=preg_replace("/<-timezone->/",$tmp_globalCF->get_timezone(),$send_mailtext);

			//for other placeholders:
			$send_mailtext=preg_replace("/<-IP->/",$IP,$send_mailtext);
			$send_mailtext=preg_replace("/<-date->/",$cur_date,$send_mailtext);
			$send_mailtext=preg_replace("/<-time->/",$cur_time,$send_mailtext);
			$send_mailtext=preg_replace("/<-date_expires->/",$date_expires,$send_mailtext);
			$send_mailtext=preg_replace("/<-time_expires->/",$time_expires,$send_mailtext);		
			$send_mailtext=preg_replace("/<-ordered_from->/",$Ordered_from,$send_mailtext);
			$send_mailtext=preg_replace("/<-email_address->/",$email,$send_mailtext);
			$send_mailtext=preg_replace("/<-random_code->/",$random,$send_mailtext);
			
			$from_name=stripslashes(mb_encode_mimeheader(html_entity_decode($this->get_NLconfig_setting("NL_name")),strtolower($charset)));
			//preparing mail header:
			$XMailer="ADbNewsSender ".$tmp_globalCF->get_config_value("Version");
			$header="From: $from_name <".$this->get_NLconfig_setting("Email")."> \n";
			$header .="X-Mailer: $XMailer \n";
			$header .="Content-Type: text/plain; charset=\"$charset\"\n";
			$send_subject=mb_encode_mimeheader($send_subject,strtolower($charset));
			//sending confirmation e-mail:
			mail(stripslashes($email), stripslashes($send_subject), stripslashes($send_mailtext),$header); 
			
			return $result;		

		}
		//print $this->DB->last_db_error();
		return 0;

	}

	function get_PL_entry_id($email)
	{	
		//possible return codes:
		//-2: Empty/invalid Email address
		//-1: email is not on PL
		//0:  no/failed DB-connection
		//>0 ID of entry.
		//checking for unwanted characters in email address (to avoid possible security risks):
		if((preg_match("/\n/", $email) || preg_match("/,/", $email) ||preg_match("/;/", $email) || preg_match("/:/", $email) || preg_match("/'/", $email) || preg_match("/</", $email) || preg_match("/>/", $email) || preg_match("/\"/", $email) || preg_match("/ /", $email)))
		{
			
			return -2;
		}		
		//is the e-mail address in a correct format?
		if(!preg_match("/^.+@.+\\..+/", $email))
		{
			
			// if not:
			return -2;
		}

		if(!isset($email))
		{
			return -2;
		}
		$email=strtolower($email);
		if(!($this->on_PL($email)))
		{
			return -1;
		}
		if(!$this->DB->connect_if_not_connected()){
		    return 0;
		}
		$res=$this->DB->query("Select id from ADBNS2_Pendinglist_".$this->ID." where email='".$this->DB->real_escape_string($email)."';");
		$result=$this->DB->fetch_row($res);
		return $result[0];
	}
	function get_PL_entry_randcode($ID)
	{	
		
		if(!isset($ID))
		{
			return "";
		}
		
		if(!$this->DB->connect_if_not_connected()){
		    return "";
		}
		
		$ID=intval($ID);
		
		$res=$this->DB->query("Select randomcode from ADBNS2_Pendinglist_".$this->ID." where id=".$this->DB->real_escape_string($ID).";");
		$result=@$this->DB->fetch_row($res);
		
		return $result[0];


	}

	function get_number_of_attempts($ID)
	{	
		//return codes:
		//-2: DB connection.failed
		//-1: if entry does not exist
		// >=0 number of attempts
		
		if(!isset($ID))
		{
			return -1;
		}
		
		if(!$this->DB->connect_if_not_connected()){
		    return -2;
		}
		$ID=intval($ID);
		
		$res=$this->DB->query("Select numberofattempts from ADBNS2_Pendinglist_".$this->ID." where id=".$this->DB->real_escape_string($ID).";");
		$result=$this->DB->fetch_row($res);
		
		return $result[0];


	}
	function delete_from_PL($ID)
	{
		if(!isset($ID) ||$ID <1)
		{
			return false;
		}
		if(!$this->DB->connect_if_not_connected()){
		    return false;
		}
		$ID=intval($ID);

		
		if(@$this->DB->query("Delete from ADBNS2_Pendinglist_".$this->ID." where id = ".$this->DB->real_escape_string($ID).";"))
		{
			return true;
		}
		return false;
	}	

	function add_to_ML($email, $randomCode, $IP)
	{
		//possible return codes:
		//-5  empty/invalid e-mail address
		//-4: empty IP address
		//-3: invalid/incorrect random code
		//-2: email address is not on PL
		//-1: email address is already on ML, 
		//0:  no/failed DB-connection
		//>0: success, returning ID of new ML entry.

		if(!isset($email))
		{
			return -5;
		}
		if(!isset($IP))
		{
			return -4; 
		}
		//checking for unwanted characters in email address (to avoid possible security risks):
		if((preg_match("/\n/", $email) || preg_match("/,/", $email) ||preg_match("/;/", $email) || preg_match("/:/", $email) || preg_match("/'/", $email) || preg_match("/</", $email) || preg_match("/>/", $email) || preg_match("/\"/", $email) || preg_match("/ /", $email)))
		{
			
			return -5;
		}		
		//is the e-mail address in a correct format?
		if(!preg_match("/^.+@.+\\..+/", $email))
		{
			
			// if not:
			return -5;
		}

		if(!isset($randomCode))
		{
			return -3;
		}
		$email=strtolower($email);

		$cur_date=time();
		if(!$this->DB->connect_if_not_connected()){
		    return 0;
		}
		//deleting expired entryies:
		@$this->DB->query("Delete from ADBNS2_Pendinglist_".$this->ID." where timestamp_expires <= $cur_date;");
		
		if($this->on_ML($email))
		{
			return -1;

		}
		if(!$this->on_PL($email))
		{
			return -2;

		}
		
		
		$ID=$this->get_PL_entry_id($email);
		if($ID <1)
		{
			return $ID;
		}
		
		if($this->get_PL_entry_randcode($ID)!=$randomCode)
		{	
			//print $this->get_PL_entry_randcode($ID).": ".$randomCode."<br>"; 	
			$max_no_of_Attempts=intval($this->get_NLconfig_setting("Limit_Confirmation_Attempts"));
			if($max_no_of_Attempts>0)
			{
				$number_of_Attempts=$this->get_number_of_attempts($ID);
				if($number_of_Attempts <0)
				{
					$number_of_Attempts=0;
				}
				$number_of_Attempts++;
				if($max_no_of_Attempts <= $number_of_Attempts)
				{
					$this->delete_from_PL($ID);
			
				}
				else
				{
						
					@$this->DB->query("UPDATE ADBNS2_Pendinglist_".$this->ID." SET numberofattempts='$number_of_Attempts' where id=$ID;");		
				}
				
				
			}
			return -3;
		}
		$time_in_ML=$this->get_NLconfig_setting("Time_on_ML");
		$TS_entry=time();		
		$TS_expires=strtotime("+ $time_in_ML month");
		$renewal_time=$time_in_ML-1;
		$TS_renewal=strtotime("+ $renewal_time month");
		
		$columns=array();

		$columns["email"]=$this->DB->real_escape_string($email);
		$columns["ip"]=$this->DB->real_escape_string($IP);
		$columns["timestamp_entry"]=$TS_entry;
		$columns["timestamp_renewal"]=$TS_renewal;
		$columns["timestamp_expires"]=$TS_expires;

		if(@($this->DB->insert_into("ADBNS2_Mailinglist_".$this->ID,$columns)))
		{	
			$result=$this->DB->get_last_insert_ID();
			if($result==0)
			{
				//if get_last_inster_ID() is not supported:
				$res=$this->DB->query("Select id from ADBNS2_Mailinglist_".$this->ID." Where email='".$this->DB->real_escape_string($email)."';");
				$row=$this->DB->fetch_row($res);

				$result=$row[0];
			}

			
			$this->delete_from_PL($ID);
			return $result;
		}
		
		return 0;
	}
	function get_ML_entry_id($email)
	{	
		//possible return codes:
		//-2: Empty/invalid Email address
		//-1: email is not on ML
		//0:  no/failed DB-connection
		//>0 ID of entry.

		if(!isset($email))
		{
			return -2;
		}
		//checking for unwanted characters in email address (to avoid possible security risks):
		if((preg_match("/\n/", $email) || preg_match("/,/", $email) ||preg_match("/;/", $email) || preg_match("/:/", $email) || preg_match("/'/", $email) || preg_match("/</", $email) || preg_match("/>/", $email) || preg_match("/\"/", $email) || preg_match("/ /", $email)))
		{
			
			return -2;
		}		
		//is the e-mail address in a correct format?
		if(!preg_match("/^.+@.+\\..+/", $email))
		{
			
			// if not:
			return -2;
		}

		$email=strtolower($email);
		if(!($this->on_ML($email)))
		{
			return -1;
		}
		if(!$this->DB->connect_if_not_connected()){
		    return 0;
		}
		$res=$this->DB->query("Select id from ADBNS2_Mailinglist_".$this->ID." where email='".$this->DB->real_escape_string($email)."';");
		$result=@$this->DB->fetch_row($res);
		return $result[0];
	}
	
	function delete_from_ML($ID)
	{	if(!isset($ID) || $ID <1)
		{
			return false;
		}
		if(!$this->DB->connect_if_not_connected()){
		    return false;
		}
		$ID=intval($ID);

		
		if(@$this->DB->query("delete from ADBNS2_Mailinglist_".$this->ID." where id = ".$this->DB->real_escape_string($ID).";"))
		{
			return true;
		}
		return false;
	}

	function renew_entry($ID,$subscriptionkey,$IP)
	{	
		//return codes:
		
		// -3: invalid subscription key, IP or ID
		// -2: combination of ID and subscription key (Timestamp of expiration date) does not exist
		// -1: Entry is not in renewal period 
		//  0: DB connection failed
		// >0: Success: returning new Timestamp of expiration date
		if(!isset($ID)||!isset($subscriptionkey)||!isset($IP) || $ID <1 ||$subscriptionkey<1)
		{
			return -3;
		}
		if(!$this->DB->connect_if_not_connected()){
		    return 0;
		}
		//deleting expired entryies:

		$ID=intval($ID);
		$subscriptionkey=$subscriptionkey*1;
	
		$res=$this->DB->query("Select count(*) from ADBNS2_Mailinglist_".$this->ID." where id=$ID AND timestamp_expires =".$subscriptionkey.";");
		$row=$this->DB->fetch_row($res);
		if($row[0] !=1)
		{
			return -2;
		}

		$res=$this->DB->query("Select count(*) from ADBNS2_Mailinglist_".$this->ID." where id=$ID AND timestamp_renewal <=".time().";");
		$row=$this->DB->fetch_row($res);
		if($row[0] !=1)
		{
			return -1;
		}
		$time_in_ML=$this->get_NLconfig_setting("Time_on_ML");
		$TS_entry=time();		
		$TS_expires=strtotime("+ $time_in_ML month");
		$renewal_time=$time_in_ML-1;
		$TS_renewal=strtotime("+ $renewal_time month");
		$query="UPDATE ADBNS2_Mailinglist_".$this->ID." SET ip='".$this->DB->real_escape_string($IP)."', timestamp_entry=$TS_entry, timestamp_renewal=$TS_renewal, timestamp_expires=$TS_expires WHERE id=$ID;";
		if(@$this->DB->query($query))
		{
			return $TS_expires;
		}
		
		return 0;
	}
	function get_ML_entry_expiration_TS($ID)
	{
		 //return codes:		
		//-2: invalid entry id
		//-1: DB connection failed
		// 0: Entry does not exist
		//>1: Timestamp of the expiration Date
		$ID=intval($ID);
		if(!isset($ID) || $ID < 1)
		{
			return -2;
		}
		
		if(!$this->DB->connect_if_not_connected()){
		    return -1;
		}
		
		
		$res=$this->DB->query("Select timestamp_expires from ADBNS2_Mailinglist_".$this->ID." where id=".$this->DB->real_escape_string($ID).";");
		$result=$this->DB->fetch_row($res);
		
		return $result[0];
	}
}


//********************************************************************************************************************
//API for public Archive access:
//********************************************************************************************************************
class pub_Archive
{
	
protected $DB=NULL;
protected $ID=NULL;

	function __construct($NLID,$DB_object)
	{	
		$NLID=intval($NLID);
		if($NLID <1)
		{
			
			user_error(__CLASS__.": ERROR: please provide a valid newsletter ID!  (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);

		}
		
				
		if($DB_object==NULL)
		{
			user_error(__CLASS__.": ERROR: Invalid Database Object.  (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);
	
		}
			
		$this->DB=$DB_object;
		if(!$this->DB->is_connected())
		{
			$this->DB->connect();
		}
		//.
		
		$res=$this->DB->query("Select id from ADBNS2_Newsletters where id = ".$this->DB->real_escape_string($NLID).";");
		$row=@$this->DB->fetch_row($res);
		
		if($row[0]!=$NLID)
		{
		    user_error(__CLASS__.": ERROR: Newsletter with ID $NLID does not exist!  (In method: <b>".__METHOD__."</b>)",E_USER_ERROR);
	
		}
		
		$this->ID=$NLID;
	}

	function get_entry_data($entryID)
	{
	    $entryID=intval($entryID);
	    $return_val=array();

	    if(!$this->DB->connect_if_not_connected()){
		    return $return_val;
	    }
	    $result=$this->DB->query("Select id, message, subject, type, date from ADBNS2_ArchiveTable_".$this->ID." WHERE id=$entryID LIMIT 1; ");

	   $row=@$this->DB->fetch_array($result,"ASSOC");
	    //for compatibility reasons:
	    if(count($row) >1)
	    {
		
		foreach($row as $key =>$val)
		{
		    $return_val[strtolower($key)]=$val;
		}
		$return_val["message"]=stripslashes($return_val["message"]);
		$return_val["subject"]=stripslashes($return_val["subject"]);
	    }
	    return $return_val;
	}
	
	function get_entries_of_month($month=0,$year=0)
	{
	    //$month: 1 (januaray) -> 12 (december)
	    if(!$month)
	    {
		$month=date("n");

	    }
	    if(!$year)
	    {
		$year=date("Y");
	    }
	    $month=intval($month);
	    $year=intval($year);
	    //checks, error handling:
	    if($month <1 || ($year==date("Y") && $month >date("n")))
	    {
		$month=date("n");
	    }
	    if($year < 1970 || $year >date("Y"))
	    {
		$year=date("Y");
	    }
	   
	    if($month >=12)
	    {
		$to_month=1;
		$to_year=$year+1;
	    }
	    else
	    {
		$to_month=$month+1;
		$to_year=$year;
	    }
	    $timestamp_start=mktime ( 0, 0, 0, $month, 1, $year );
	    
	    $timestamp_end=mktime ( 0, 0, 0, $to_month, 1, $to_year );
	    $return_val=array();
	    if(!$this->DB->connect_if_not_connected()){
		    return $return_val;
	    }
	    $result=$this->DB->query("Select id, message, subject, type, date from ADBNS2_ArchiveTable_".$this->ID." WHERE date >=$timestamp_start AND date < $timestamp_end order by date DESC; ");
	    $i=0;
	    while($row=@$this->DB->fetch_array($result,"ASSOC"))
	    {
		$return_val[$i]=array();
		//for compatibility reasons:
		foreach($row as $key =>$val)
		{
		    $return_val[$i][strtolower($key)]=$val;
		}
		$return_val[$i]["message"]=stripslashes($return_val[$i]["message"]);
		$return_val[$i]["subject"]=stripslashes($return_val[$i]["subject"]);
		$i++;
	    }
   
	    

	   return $return_val;
	}

	function get_number_of_entries_of_month($month=0,$year=0)
	{
	  
	   //$month: 1 (januaray) -> 12 (december)
	   //return codes: -1: DB error, >=0: number of entries in the provided month
	  
	    $month=intval($month);
	    $year=intval($year);
	    
	    if(!$month)
	    {
		$month=date("n");

	    }
	    if(!$year)
	    {
		$year=date("Y");
	    }
	    $month=intval($month);
	    $year=intval($year);
	    //checks, error handling:
	    if($month <1 || ($year==date("Y") && $month >date("n")))
	    {
		$month=date("n");
	    }
	    if($year < 1970 || $year >date("Y"))
	    {
		$year=date("Y");
	    }
	   
	    if($month >=12)
	    {
		$to_month=1;
		$to_year=$year+1;
	    }
	    else
	    {
		$to_month=$month+1;
		$to_year=$year;
	    }
	    $timestamp_start=mktime ( 0, 0, 0, $month, 0, $year );
	    
	    $timestamp_end=mktime ( 0, 0, 0, $to_month, 0, $to_year );
	   
	    if(!$this->DB->connect_if_not_connected()){
		    return -1;
	    }
	    $result=$this->DB->query("Select count(*) from ADBNS2_ArchiveTable_".$this->ID." WHERE date >=$timestamp_start AND date < $timestamp_end; ");
	    $row=$this->DB->fetch_row($result);
	    return $row[0];
	   
	}
	function get_number_of_entries()
	{
	    //return values: 
	    // -1: DB error
	    // >=0: number of entries in archive 

	    if(!$this->DB->connect_if_not_connected()){
		    return -1;
	    }
	    $result=$this->DB->query("Select count(*) from ADBNS2_ArchiveTable_".$this->ID.";");
	    $row=$this->DB->fetch_row($result);
	    return $row[0];
	    
	}
	function get_earliest_year()
	{
	    //return values: 
	    //0 :DB error
	    // >0: earliest year

	    if(!$this->DB->connect_if_not_connected()){
		    return 0;
	    }
	    $result=$this->DB->query("SELECT date FROM ADBNS2_ArchiveTable_".$this->ID." ORDER BY date ASC LIMIT 1;");

	    $row=$this->DB->fetch_row($result);
	    $return_val=$row[0];
	    if(!$return_val)
	    {
		return date("Y");
	    }
	    return date("Y",$return_val);
	}
	
}

?> 
Return current item: ADbNewsSender