<?
/***************************************************************************
*
* Filename: functions.php
* Date: February 29, 2004
* Copyright: (C) 2004 GMM Computer Technologies
* Author: Michael L. Malony Jr.
* Email: hide@address.com
* URL: http://www.g-m-m.com/
*
*
***************************************************************************/
/***************************************************************************
*
* 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 2 of
* the License, or (at your option) 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
***************************************************************************/
//includes
require_once("includes.php");
//connects to database
function gstats_dbConnect()
{
//imports vars
global $CONFIG;
//if db vars arent defined
if(!isset($CONFIG['dbType']) || !isset($CONFIG['dbHost']) ||
!isset($CONFIG['dbUserName']) || !isset($CONFIG['dbPassword']) ||
!isset($CONFIG['dbName']))
{
return false;
}
//dont count buffer records for counting
$ADODB_COUNTRECS = false;
//if not already connected
if(!$CONFIG['dbCon'])
{
//mysql
if($CONFIG['dbType']=='MySQL')
{
//connects
$con = &ADONewConnection('mysql');
if(!$con->Connect($CONFIG['dbHost'], $CONFIG['dbUserName'], $CONFIG['dbPassword'], $CONFIG['dbName']))
return false;
}
//PostgreSQL
else if($CONFIG['dbType']=='PostgreSQL')
{
//connects
$con = &ADONewConnection('postgres7');
if(!$con->PConnect($CONFIG['dbHost'], $CONFIG['dbUserName'], $CONFIG['dbPassword'], $CONFIG['dbName']))
return false;
}
//Access
else if($CONFIG['dbType']=='MS Access')
{
//connects
$con = &ADONewConnection('access');
$dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq={$CONFIG['dbName']};Uid={$CONFIG['dbUserName']};Pwd={$CONFIG['dbPassword']};";
if(!$con->Connect($dsn))
return false;
}
//MS SQL Server
else if($CONFIG['dbType']=='MS SQL Server')
{
//connects
$con = &ADONewConnection('odbc_mssql');
$dsn = "Driver={SQL Server};Server={$CONFIG['dbHost']};Database={$CONFIG['dbName']};";
if(!$con->Connect($dsn, $CONFIG['dbUserName'], $CONFIG['dbPassword']))
return false;
}
//none
else
{
return false;
}
//sets debugging
$con->debug = $CONFIG['dbDebug'];
//sets as shared connection
$CONFIG['dbCon'] = $con;
}
//returns connection
return $CONFIG['dbCon'];
}
//parses the date string
function gstats_parseDateRange($startDate, $endDate, $startTime, $endTime)
{
//imports config
global $CONFIG;
//gets times
$startDateTime = strtotime($startDate);
$endDateTime = strtotime($endDate);
//day date range
if($CONFIG['currentReporting']['range']=="day")
{
$s = date("F d, Y", $startDateTime);
}
//month date range
else if($CONFIG['currentReporting']['range']=="month")
{
$s = date("F, Y", $startDateTime);
}
//year date range
else if($CONFIG['currentReporting']['range']=="year")
{
$s = date("Y", $startDateTime);
}
//custom (or week)
else
{
//starting date
$s = date("F d, Y", $startDateTime);
//starting time (if not at very start of day)
if($startTime != 0)
$s .= " ".date("h:ia", $startTime);
//end date
$s .= " - ".date("F d, Y", $endDateTime);
//ending time (if not at very end of day)
if($endTime < SECONDS_IN_DAY)
$s .= " ".date("h:ia", $endTime);
}
//returns it
return $s;
}
//makes graph
function gstats_makeGraph($width, $height, $per)
{
//imports vars
global $CONFIG;
//new width
$width = (int)($per*$width);
//makes graph name
$path = $CONFIG['statsAbsPath']."images/graphs/";
$wwwPath = $CONFIG['statsWWWPath']."images/graphs/";
$fileName = "graph{$width}x{$height}.jpg";
//if it exists - return it
if(file_exists($path.$fileName))
return $wwwPath.$fileName;
//checks dimensions
if(!$width || !$height)
return $wwwPath."error.png";
//creates image
$im = @imagecreate($width, $height);
//not created
if(!$im)
return $wwwPath."error.png";
//allocates colors
$background = @imagecolorallocate($im, $CONFIG['graphRedColor'], $CONFIG['graphGreenColor'], $CONFIG['graphBlueColor']);
$black = @imagecolorallocate($im, 0, 0, 0);
//fills background
if(!@imagefilledrectangle($im, 0, 0, $width, $height, $background))
return $wwwPath."error.png";
//outlines graph portion
if(!@imagerectangle($im, 0, 0, ($width-1), ($height-1), $black))
return $wwwPath."error.png";
if(!@imagerectangle($im, 1, 1, ($width-2), ($height-2), $black))
return $wwwPath."error.png";
//writes image
if(!@imagepng($im, $path.$fileName, 75))
return $wwwPath."error.png";
//cleans up
@imagedestroy($im);
//returns image path
return $wwwPath.$fileName;
}
//parses domain from url
function gstats_parseDomain($URL)
{
//for direct
if($URL == "direct")
return $URL;
//gets info from url
$info = parse_url($URL);
//domain is host
$domain = $info['host'];
//returns it
return $domain;
}
//returns URI minus query string
function gstats_parseFile($URI)
{
//parses url
$info = parse_url($URI);
//just file/path portion
$file = $info['path'];
//returns it
return $file;
}
//parses query string from URL
function gstats_parseQuery($URL)
{
//for direct
if($URL == "direct")
return $URL;
//gets info from url
$info = parse_url($URL);
//domain is host
$query = $info['query'];
//returns it
return $query;
}
//url encodes just the query portion of a full URL
function gstats_urlencode($URL)
{
//parses url
$info = parse_url($URL);
$newURL = "";
//gets components
$scheme = $info['scheme'];
$host = $info['host'];
$user = $info['user'];
$pass = $info['pass'];
$path = $info['path'];
$query = $info['query'];
$fragment = $info['fragment'];
//if scheme
if($scheme)
$newURL .= $scheme."://";
//if user
if($user)
$newURL .= $user.":".$pass."@";
//if hostname
if($host)
$newURL .= $host;
//if path
if($path)
$newURL .= $path;
//if query
if($query)
{
//query portion
$newURL .= "?";
//breaks up query into vars
$vars = array();
parse_str($query, $vars);
//loops through vars
for($i=0; (list($key, $val) = each($vars)); $i++)
{
//not first
if($i)
$newURL .= "&";
//adds var
$newURL .= urlencode($key)."=".urlencode($val);
}
}
//if fragment
if($fragment)
$newURL .= "#".$fragment;
//returns it
return $newURL;
}
//html entities - strips slashes as well
function gstats_htmlentities($string)
{
//removes slashed quotes
$string = stripslashes($string);
$string = stripcslashes($string);
//converts any other entities
$string = htmlentities($string);
//done
return $string;
}
//splits array into $pieces number of portions (differant from standard array_chunk function)
function gstats_arrayChunk($array, $pieces)
{
//makes array to return
$ra = array();
//gets split num
if((count($array)%$pieces)==0)
$splitNum = ((int)(count($array)/$pieces));
else
$splitNum = (((int)(count($array)/$pieces))+1);
//makes each piece
for($i=0; $i<$pieces; $i++)
{
$ra[$i] = array_slice($array, ($i*$splitNum), $splitNum);
}
//sets group size
$ra['chunkSize'] = $splitNum;
//return it
return $ra;
}
//detects country (modified from example code at ip-to-country.com)
function gstats_ipToCountryCode($ip)
{
//imports globals
global $CONFIG;
//connects to database
$con = $CONFIG['dbCon'];
//gets country code
$ps = $con->Prepare("SELECT country_code2 FROM {$CONFIG['tableIPToCountry']} WHERE ip_from<=? AND ip_to>=?");
$rs = $con->Execute($ps, array($ip, $ip));
//gets results
if($rs && $record=$rs->FetchRow())
$code = $record['country_code2'];
else
$code = "";
//close db connection
//
//make great britain and uk the same
if($code=="UK")
$code = "GB";
//returns country code
return $code;
}
//gets country name from country code
function gstats_countryCodeToName($code)
{
//imports globals
global $CONFIG;
//connects to database
$con = $CONFIG['dbCon'];
//gets country code
$ps = $con->Prepare("SELECT country_name FROM {$CONFIG['tableIPToCountry']} WHERE country_code2=?");
$rs = $con->SelectLimit($ps, 1, 0, array($code));
//gets results
if($rs && $record=$rs->FetchRow())
$name = $record['country_name'];
else
$name = "N/A";
//close db connection
//
//returns country code
return $name;
}
//checks for install dir
function gstats_checkForInstallDir()
{
//imports config
global $CONFIG;
//if it exists
if(file_exists($CONFIG['statsAbsPath']."install/"))
{
//shows warning
gstats_showErrorBox("Install Directory Still Exists", '<b>Remove Directory</b>
<br>
Please remove the install directory at:
<br><br>
<code>
'.$CONFIG['statsAbsPath'].'install/
</code>
<br><br>
Leaving this directory can result in a user resetting your gStats install.',
"You must remove your install directory.");
echo "<br>";
}
}
//checks user login
function gstats_checkLogin($userName="", $password="", $rememberLogin=false)
{
//imports config
global $CONFIG;
$login = true;
//if new user name and password specified
if(!empty($userName) && !empty($password))
{
//sets login in globals
$CONFIG['loginUserName'] = $userName;
$CONFIG['loginPassword'] = md5($password);
//if a timeout is specified
if($rememberLogin && ($CONFIG['loginTimeout']>0))
{
//sets cookies with timeout
$timeout = time() + ($CONFIG['loginTimeout'] * SECONDS_IN_HOUR);
setcookie('userName', $userName, $timeout);
setcookie('password', md5($password), $timeout);
}
//no timeout
else
{
//sets cookie with no timeout - logs out when browser closes
setcookie('userName', $userName);
setcookie('password', md5($password));
}
}
//checks for login information
if(empty($CONFIG['loginUserName']) || empty($CONFIG['loginPassword']))
$login = false;
//checks username
if($CONFIG['userName'] != $CONFIG['loginUserName'])
$login = false;
//checks password
if(md5($CONFIG['password']) != $CONFIG['loginPassword'])
$login = false;
//if a bad login
if(!$login)
{
$CONFIG['loginUserName'] = "";
$CONFIG['loginPassword'] = "";
}
//return results
return $login;
}
//logs out of gstats
function gstats_logout()
{
//removes cookies
setcookie('userName', "");
setcookie('password', "");
//removes local store
$CONFIG['loginUserName'] = "";
$CONFIG['loginPassword'] = "";
}
//shows login form
function gstats_showLoginForm($redirect, $badLogin=false)
{
//imports config
global $CONFIG;
?>
<form action="<? echo $CONFIG['statsWWWPath']; ?>login.php" method="POST">
<input type="hidden" name="action" value="login">
<input type="hidden" name="redirect" value="<? echo $redirect; ?>">
<table width="100%" align="center" cellspacing="0" class="box">
<tr>
<td class="boxHeading" colspan="3">
<table border="0" width="100%" cellpadding="0" cellspacing="0">
<tr>
<td class="boxHeading" width="100%">Login to gStats</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="boxItemHeading" colspan="3">Enter user name and password.</td>
</tr>
<?
//bad login
if($badLogin)
{
?>
<tr>
<td class="boxItem">
<span class="warning">Incorrect User Name / Password combination.</span>
</td>
</tr>
<?
}
?>
<tr>
<td class="boxItem">
<b>User Name:</b>
<br>
<input type="text" name="userName" size="55" class="text">
<br><br>
</td>
</tr>
<tr>
<td class="boxItem">
<b>Password:</b>
<br>
<input type="password" name="password" size="55" class="text">
<br><br>
</td>
</tr>
<tr>
<td class="boxItem">
<input type="checkbox" name="rememberLogin" value="1" class="checkbox"> Keep me logged in.
<br><br>
</td>
</tr>
<tr>
<td class="boxItem" align="center">
<input type="submit" name="Login" value="Login" class="button">
<br><br>
</td>
</tr>
</table>
</form>
<?
}
//show a simple error box
function gstats_showErrorBox($header, $message, $subHeader="")
{
?>
<table width="100%" align="center" cellspacing="0" class="box">
<tr>
<td colspan="4" class="boxHeading">
<table border="0" width="100%" cellpadding="0" cellspacing="0">
<tr>
<td class="boxHeading"><? echo $header; ?></td>
</tr>
</table>
</td>
</tr>
<?
//if there is a sub-header
if(!empty($subHeader))
{
?>
<tr>
<td class="boxItemHeading"><b>You must remove your install directory.</b></td>
</tr>
<?
}
?>
<tr>
<td class="boxItem">
<? echo $message; ?>
</td>
</tr>
</table>
<?
}
//this is a highly modified version of the browscap functions provided at http://www.garykeith.com/browsers/downloads.asp
//it combines code from both the CSV file parser as well as the browcap2mysql sample. Original comments are below.
function gstats_browscap($UA)
{
//imports config
global $CONFIG;
//no ua
if(empty($UA))
$UA = $_SERVER['HTTP_USER_AGENT'];
//holds values
$browscap = array();
//db connection
$con = $CONFIG['dbCon'];
//gets browser
$ps = $con->Prepare("SELECT * FROM {$CONFIG['tableBrowscap']} WHERE ? LIKE title ORDER BY parent DESC, id ASC LIMIT 0,1");
$rs = $con->Execute($ps, array($UA));
//gets match result
if($rs && $record=$rs->FetchRow())
{
//loops through each field returned
while(list($key,$val) = each($record))
{
//ignore num keys (ADOdb returns both associative and index
if(is_int($key))
continue;
//if a default value - get parents
if((is_numeric($val) && ($val==-1)) || ($val=="") || (is_numeric($val) && ($val==0)))
{
//gets value from parent browser
$ps2 = $con->Prepare("SELECT $key FROM {$CONFIG['tableBrowscap']} WHERE title=? LIMIT 0,1");
$rs2 = $con->Execute($ps2, array($record['parent']));
//sets value
if($rs2 && $record2=$rs2->FetchRow())
{
$browscap[$key] = $record2[$key];
}
else
$browscap[$key] = "";
}
//no default - set it
else
$browscap[$key] = $val;
}
}
//sets user agent
$browscap["userAgent"] = $UA;
//returns results
return $browscap;
}
/**
* What these functions will do, is very similar to the PHP get_browser() function.
* If you don't have administrative privileges and get_browser() is not available or
* browsercap.ini is out of date, these functions might be an alternative.
* You can also easily modify it to fit your personal needs.
*
*Installation instructions:
* - copy this file and the most recent browscap.csv in any directory
* - include this file: e.g. include "browscap.php";
* - then run the function: e.g. $caps = browscap($_SERVER['HTTP_USER_AGENT']);
* - the array $caps now contains capabilies for the desired user-Agent
*
* @author Tobias I. Rothe (hide@address.com)
*
* browscap.csv managed by Gary J. Keith http://www.garykeith.com/index.asp
*/
/*****************************************************************************
******************************************************************************
*** ***
*** browscap.ini to MySQL converter v1.1.0 ***
*** -------------------------------------- ***
*** ***
*** This little PHP script parses the browscap.ini file and inserts the ***
*** data from it into a fast MySQL table. ***
*** ***
*** browscap.ini support is now built into PHP itself, but this MySQL ***
*** table is much faster, uses less resources and allows you to keep the ***
*** browser definitions as up to date as you require. ***
*** ***
******************************************************************************
*** ***
*** To use this code simply fill in the 4 MySQL variables below and ***
*** upload this file to your webserver along with the latest version of ***
*** browscap.ini (obtainable from http://garykeith.com/) both in the ***
*** same directory. Then just go to URL of this file on your server and ***
*** the MySQL table will be created and populated. ***
*** ***
******************************************************************************
*** ***
*** SQL query to retrieve the values of the visiting browser: ***
*** ***
*** SELECT * FROM browscap WHERE '$_SERVER['HTTP_USER_AGENT']' LIKE ***
*** title ORDER BY parent DESC, id ASC LIMIT 0,1 ***
*** ***
*** Any values returned as a default value of -1 inherit that property ***
*** from the parent browser type. So for any retrieved value that is -1: ***
*** ***
*** SELECT fieldname FROM browscap WHERE title = '$parent' LIMIT 0,1 ***
*** ***
******************************************************************************
*** ***
*** Coded by Jake Dean (hide@address.com) ***
*** browscap.ini maintained by Gary Keith (http://garykeith.com/) ***
*** ***
*** Please send any bug reports or feature suggestions to me at the ***
*** address above, your help and advice is very much appreciated. ***
*** ***
*** You may distribute this file freely and modifications are welcome as ***
*** long as you send me a copy. ***
*** ***
******************************************************************************
*** ***
*** Changelog: ***
*** ***
*** 1.1.0: Added support for reintroduced AK and SK browser properties ***
*** Minor code optimisations ***
*** Minor documentation changes ***
*** 1.0.1: Updated documentation to better explain usage ***
*** 1.0.0: First release ***
*** 0.9.0: Working test version ***
*** ***
******************************************************************************
*****************************************************************************/
?>