<?php
/*
Last change in version: 2.0.2
#########################################################################################
# ADbNewsSender 2 #
# Copyright (C) 2009 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 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 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)
{
if(!$this->DB->is_connected())
{
$this->DB->connect();
}
$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()
{
if(!$this->DB->is_connected())
{
$this->DB->connect();
}
$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;
}
if(!$this->DB->is_connected())
{
$this->DB->connect();
}
//....
$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();
if(!$this->DB->is_connected())
{
$this->DB->connect();
}
$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
$NLID=intval($NLID);
if($NLID <1 || !isset($NLID))
{
return -2;
}
if(!$this->DB->is_connected())
{
if(!@$this->DB->connect())
{
return 0;
}
}
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 version_smaller_than($version)
{
//returns true if $version is smaller than the current ADBNS2 Version
$currentVersion=$this->get_config_value("Version");
if($version==$currentVersion)
{
return false;
}
//ignoring types and milestones of unstable versions:
if(preg_match("/ /",$version))
{
$version_arr=@explode(" ",$version);
$version=$version_arr[0];
}
if(preg_match("/ /",$currentVersion))
{
$currentVersionArr=@explode(" ",$currentVersion);
$currentVersion=$currentVersionArr[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
$currentVersion=$this->get_config_value("Version");
if($version==$currentVersion)
{
return false;
}
//ignoring types and milestones of unstable versions:
if(preg_match("/ /",$version))
{
$version_arr=@explode(" ",$version);
$version=$version_arr[0];
}
if(preg_match("/ /",$currentVersion))
{
$currentVersionArr=@explode(" ",$currentVersion);
$currentVersion=$currentVersionArr[0];
}
if($version==$currentVersion)
{
return false;
}
if($this->version_smaller_than($version))
{
return false;
}
return true;
}
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;
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("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_Maillinglist_".$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);
if(!$this->DB->is_connected())
{
$this->DB->connect();
}
$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)
{
if(!$this->DB->is_connected())
{
$this->DB->connect();
}
$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()
{
if(!$this->DB->is_connected())
{
$this->DB->connect();
}
$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->is_connected())
{
if(!@$this->DB->connect())
{
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;
}
$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 "";
}
$ID=$ID*1;
if(!$this->DB->is_connected())
{
if(!@$this->DB->connect())
{
return "";
}
}
$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;
}
$ID=$ID*1;
if(!$this->DB->is_connected())
{
if(!@$this->DB->connect())
{
return -2;
}
}
$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->is_connected())
{
if(!@$this->DB->connect())
{
return false;
}
}
$ID=$ID*1;
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->is_connected())
{
if(!@$this->DB->connect())
{
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_Maillinglist_".$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_Maillinglist_".$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->is_connected())
{
if(!@$this->DB->connect())
{
return 0;
}
}
$res=$this->DB->query("Select id from ADBNS2_Maillinglist_".$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->is_connected())
{
if(!@$this->DB->connect())
{
return false;
}
}
$ID=$ID*1;
if(@$this->DB->query("delete from ADBNS2_Maillinglist_".$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->is_connected())
{
if(!@$this->DB->connect())
{
return 0;
}
}
//deleting expired entryies:
$ID=$ID*1;
$subscriptionkey=$subscriptionkey*1;
$res=$this->DB->query("Select count(*) from ADBNS2_Maillinglist_".$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_Maillinglist_".$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_Maillinglist_".$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->is_connected())
{
if(!@$this->DB->connect())
{
return 1;
}
}
$res=$this->DB->query("Select timestamp_expires from ADBNS2_Maillinglist_".$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->is_connected())
{
if(!@$this->DB->connect())
{
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->is_connected())
{
if(!@$this->DB->connect())
{
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->is_connected())
{
if(!@$this->DB->connect())
{
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->is_connected())
{
if(!@$this->DB->connect())
{
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->is_connected())
{
if(!@$this->DB->connect())
{
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);
}
}
?>