<?php
/* Par beridoxy
  Version         Date              Data source      Commentaires
  V0.1            23 Aout      2005: (hardcoded)        Implementation GD de base, date, gestion minimale bdd, temps de génération
  V0.2            25 Aout      2005: (mysql)            Rajout de variable de configuration ($__VISIBLE)
  V0.3            29 Aout      2005: (mysql)            degagerTropVieux implémenté
  V0.35         14 Septembre 2005: (mysql)            Usage de dieMessageImage pour eviter les images générés incorrectes, correction centisecondes => secondes.
  V0.36            17 Octobre   2005: (mysql)            Débuggage des constantes.
  V0.40            18 Octobre   2005: (mysql & file)    Lecture Ecriture fichier et ajout dans le tableau conditionnel
  V0.41            19 Octobre   2005: (mysql & file)    Tri du tableau selon la date
*/
    /*Constantes*/
    
$__VISIBLE = 1;         //N'affiche pas les résultats des requetes. (mais fait quand meme les requete de recherche de données: comment ca pas optimisé ? :D)
    
$__SNEAKYMODE = 0;         //Met l'image en 1*1 pixel
    
$__DELTIME = 259200;    //3 jours avant effacement
    
    /**************************
    
    SGBAccess. See sql structure for installation
    
    *************/
    
define ("BDD_TYPE", "mysql");
    
define ("BDD_PASSWORD", "root");
    
define ("BDD_LOGIN", "");
    
define ("BDD_DNSLOCATION", "localhost");
    
define ("FILE_LOCATION", "test.txt");
    
    
$__COPYRIGHT       = "GNU GPL Not for commercial use.";
    
$__VERSION         = "v0.4 (text file)";
    
// Source écrit par T pour php 4.2 ou plus
    // website : http://www.overdrived.com
    // email : ab@overdrived.com
    // _POST=code de la source afficher et a précopier
    // aide : http://overdrived.com/btcode.php
    //Code à inclure dans la tete de la page HEAD

    
function get_microtime() {
        list(
$tps_usec, $tps_sec) = explode(" ",microtime());
        return ((float)
$tps_usec + (float)$tps_sec);
    }
    
$tps_start = get_microtime();
    
    
testsGD();
    
// fin de la tete HEAD
    
    
    
header("Content-type: image/png");
    
    
//Préparation
    
if (BDD_TYPE == "mysql") {
        
connectDB();
        
/*On va ajouter celui qui demande l'image*/
        
ajouter_MYSQL();
        
degagerTropVieux($__DELTIME);
    }
    
   
/*Variables GET gérés*/

//-> Efface tout les connectés
    
if(isset($_GET['RAZ'])) {
        if(
$_GET['RAZ']=='roxen') {
            if (
BDD_TYPE == "mysql") {
               
mysql_query("DELETE FROM connected;");
               
dieImageMessage ("Effacement effectué");
            }
            if (
BDD_TYPE == "file") {
                
$visiteur = null;
                
flush_FILE($visiteur);
                
dieImageMessage ("Effacement effectué");
            }
        }
    }
    
    
//->--------------------
    
$visiteur = null;
    
       if (
BDD_TYPE == "mysql") {
        
$visiteurs=liredansBDD();
    }
    if (
BDD_TYPE == "file") {
        
$visiteurs=lirefichier_FILE();
        
$visiteurs=ajouter_FILE($visiteurs);
        
$visiteurs=triertableau_FILE($visiteurs);
        
$visiteurs=degagerTropVieux_FILE($visiteurs);
        
flush_FILE($visiteurs);
    }


   
/* On va afficher */


   
   
if($__SNEAKYMODE == 1) {
       
$im = @imagecreate (1, 1)
       or die (
"Impossible d'initialiser la bibliothèque GD");
   }else {
//Génération a taille NORMALE
       
       /*Démination de la taille !*/
       
$pngx = 920;
       
$pngy = 200; //count($visiteurs) * 8 + 40
   
       
$im = @imagecreate ($pngx, $pngy)
       or die (
"Impossible d'initialiser la bibliothèque GD");
   }
   
   
   
   
   
$background_color = imagecolorallocate ($im, 255, 255, 255);
   
$text_color = imagecolorallocate ($im, 0, 0, 0);
   
$title_color = imagecolorallocate ($im, 25, 40, 231);
   
   
/*Allocation pour les temps spéciaux.*/
   
$recent1 = imagecolorallocate ($im, 102, 4, 27);
   
//$recent1 = imagecolorallocate ($im, 5, 223, 255);
   
$recent2 = imagecolorallocate ($im, 203, 80, 5);
   
$recent3 = imagecolorallocate ($im, 255, 11, 5);
   
$recent4 = imagecolorallocate ($im, 5, 223, 245);
   
   
   if(
$__VISIBLE == 1) {
       
/*Collones titres*/
       
imagestring ($im, 2, 5, 1, "Visiteurs", $title_color);
       
       
       
/*Inclusion du texte*/
       
if(count($visiteurs)>0) {
           for(
$i=0;$i<count($visiteurs);$i++) {
               
               
$coloruse = choisircouleur(mktime(),$visiteurs[$i][3],$recent1,$recent2,$recent3,$recent4);
               
               
//Conversion date vers affichage
               
$dateaffiche = date("d/m/y   H:i:s", $visiteurs[$i][3]);
               
imagestring ($im, 1, 5, 20 + (($i) * 19),$visiteurs[$i][0], $text_color);
               
imagestring ($im, 1, 120, 20 + (($i) * 19),tronquer_Texte($visiteurs[$i][1],50), $text_color);
               
               
imagestring ($im, 1, 450, 20 + (($i) * 19),$texte = substr($visiteurs[$i][2], 0, 50), $text_color);
               
imagestring ($im, 1, 450, 30 + (($i) * 19),$texte = substr($visiteurs[$i][2].iif(strlen($visiteurs[$i][2])>100,"...",""), 50, 100), $text_color);
               
imagestring ($im, 1, 740, 20 + (($i) * 19),$dateaffiche, $coloruse);
               
               
//DEBUG
               //imagestring ($im, 1, 1, 100,"MKTIME DIT: ".mktime(), $text_color);
           
}
       }
       else {
            
imagestring ($im, 1, 5, 20,"La table est vide", $text_color);
       }
       
       
       
/*Colonne pied de page*/
       
imagestring ($im, 2, 5, $pngy-27, "Total visiteurs: ".count($visiteurs)."         [POWERED By caudium pike]", $text_color);
       
       
       
/*TIME---------------*/
       
$tps_end = get_microtime();$tps = $tps_end - $tps_start;function rounder($value){$buffer = $value * 100;$rounded = round($buffer);$buffer = $rounded / 100;$point_pos = strpos($buffer, ".");if ($point_pos == FALSE) $buffer .= ".00";else {   if ((strlen($buffer) - $point_pos) == 2) $buffer .= "0";}return $buffer; }
       
$tps2=@rounder($tps);
       
/*<!-- FIN DE TIME---------------*/
       
       
imagestring ($im, 1, 5, $pngy-10, $__VERSION." Image généré en ".$tps2. " secondes ".$__COPYRIGHT, $text_color);

   }

   
/*Création puis envoi de l'image*/
   
imagepng($im);
   
imagedestroy($im);
?>


























<?php

/***************************************************************
                        Fonctions
/*****************************************************/



function ajouter_MYSQL() {
    
//Get all data.
    
$ip_get = $_SERVER['REMOTE_ADDR'];
    
$dns_get = gethostbyaddr($ip_get);
    
$useragent_get = $_SERVER['HTTP_USER_AGENT'];
    
$timeacces_get = mktime();



    if(
verifierSiUserExistant($ip_get)==true) {
        
incrementerIp($ip_get);
        
// print "incremente ip";
    
}
    else {
        
ajouterDansBDD($ip_get, $dns_get, $useragent_get, $timeacces_get);
        
// print "ajoute";
    
}

}

/***************************************************************
                        MYSQL Data Access (MYDAC) Fonctions
/*****************************************************/

/*On degage tout ce qui es trop vieux de la bdd.*/
/*SQL INJECTION WARNING*/
function degagerTropVieux($maxTime) {
    
    
    
mysql_query("DELETE FROM connected WHERE dernierefoisvu < '".(mktime()-$maxTime)."';");
    
    
    
}

/*Cette fonction va verifier si l'ip est déjà venue recemment.*/
/*SQL INJECTION WARNING*/
function verifierSiUserExistant($ip) {
   
$result = mysql_query ("SELECT ip FROM connected WHERE ip='".$ip."';");

   
$num_rows = mysql_num_rows($result);
//  print "////".$num_rows."////";
   
if($num_rows == 0) {
        return
false;
   }
   else {
       return
true;
   }
}


/*Met a jour les information (date, nbconnection) pour l'ip en paramètre.*/
/*SQL INJECTION WARNING*/
function incrementerIp($ip_set) {
    
mysql_query("UPDATE connected SET dernierefoisvu = '".mktime()."',nbhit = nbhit+1 WHERE ip='".
    
$ip_set."';"    );

}

function
dieImageMessage($message) {
    
$image = @imagecreate(500, 80);  
    
$coulFond = imagecolorallocate($image, 255, 255, 255);  
    
$couleur = imagecolorallocate($image, 0, 0, 0);  
    
imagestring ($image, 4,5, 30, $message, $couleur);  
    
imagepng($image);  
    
imagedestroy($image);
    die();
}


/*Il faut être déjà connecté ! */
/*SQL INJECTION WARNING*/
function ajouterDansBDD($ip_add,$dns_add,$useragent_add,$timeacces_get) {

    
mysql_query("INSERT INTO connected (ip, dns, useragent, dernierefoisvu)
                 VALUES ('"
.$ip_add."', '".$dns_add."', '".$useragent_add."', '".$timeacces_get."');"
    
);
    
//print "BDDDZDZA".$ip_add;

}

function
liredansBDD() {
    
//$toreturn = new array;
    
$iterateur=0;


    
$result = mysql_query ("SELECT ip,dns,useragent,dernierefoisvu FROM connected ORDER BY dernierefoisvu DESC;");
    if (
$row = mysql_fetch_array($result)) {
        do {
            
$toreturn[$iterateur][0] = $row["ip"];
            
$toreturn[$iterateur][1] = $row["dns"];
            
$toreturn[$iterateur][2] = $row["useragent"];
            
$toreturn[$iterateur][3] = $row["dernierefoisvu"];

            
$iterateur++;

        } while(
$row = mysql_fetch_array($result));
    }


    return
$toreturn;
}

function
connectDB() {
    
//Ou es la base, user de la bdd, pass du user.
    
mysql_connect (BDD_DNSLOCATION, BDD_LOGIN, BDD_PASSWORD)
    or
dieImageMessage ("Impossible de se connecter au serveur de bases de données.\nEg: Mauvais password, mauvais serveur etc...");

    
//Specifique mysql connection a un 'namespace'
    
mysql_select_db ("visiteurs")
    or
dieImageMessage ("Base de données non trouvée.");


}

/*Demande a mysql la taille de la table des ip.*/
function tailletotale() {
    
$result = mysql_query ("SELECT count(*) FROM connected;");
    if (
$row = mysql_fetch_array($result)) {
            return
$row["ip"];
    }
    
    return -
1;
    
}
/********************************************
/* FONCTIONS DIVERSES
/**********************************************/
function choisircouleur($timeori,$timecompare,$c1,$c2,$c3,$c4) {
    if(
$timeori < $timecompare + 500) {
        return
$c1;
    }
    if(
$timeori < $timecompare + 3000) {
        return
$c2;
    }
    if(
$timeori < $timecompare + 10000) {
        return
$c3;
    }
    if(
$timeori < $timecompare + 50000) {
        return
$c4;
    }
    return
$c4;
}


function
arrayTest() {
    return array (  
0 => array('40.43.32.10','id.akadns.org','IE6.0',1086472800),
                    
1 => array('192.168.1.28','tiger','Links',1086472900)
    );


}

function
tronquer_Texte($texte, $longeur_max)
{
    if (
strlen($texte) > $longeur_max) {
        
$texte = substr($texte, 0, $longeur_max);
        
$dernier_espace = strrpos($texte, "");
        
$texte = substr($texte, 0, $dernier_espace)."...";
    }

    return
$texte;
}

/*Fonction équivalente au iif en vb.*/
function iif($expression, $returntrue, $returnfalse = '') {
    return (
$expression ? $returntrue : $returnfalse);
}

function
testsGD() {
    if (!
function_exists('imagecreate')) {
        
dieHTML('<a href="http://www.boutell.com/gd/">PHP GD</a> Ne semble pas être disponible !');
    }
}

function
dieHTML($htmlmessage) {
    die(
'<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Erreur</title>
</head>
<body>
    <p>'
.
    
$htmlmessage.
    
'</p>
</body>
</html>'
);
}
/********************************************************************
               FILE DATA ACCESS FONCTION
********************************************************************/

function lirefichier_FILE() {
    
//dieImageMessage(file_get_contents(FILE_LOCATION));
    
$fich = fopen(FILE_LOCATION,'rb');
    
//Tant qu'on est pas a la fin on lit un ligne de taille maxi de 1024 bits en mode csv (les ; délimitent les élément et la ligne est un array)
    
$iterateur = 0;
    
    if (
$ligne = fgetcsv($fich, 1024,"|")) {
        do {
            
$toreturn[$iterateur][0] = $ligne[0]; //"ip"
            
$toreturn[$iterateur][1] = $ligne[1]; //"dns"
            
$toreturn[$iterateur][2] = $ligne[2]; //"useragent"
            
$toreturn[$iterateur][3] = $ligne[3]; //"dernierefoisvu"
            
            
            
$iterateur++;
            
        } while(
$ligne = fgetcsv($fich, 1024,"|"));
    }
    
fclose ($fich);
    return
$toreturn;
}

/* Cherche dans le tableau si l'ip et tout existe déjà, sinon l'ajoute a la fin*/
function ajouter_FILE($visiteur_local) {
    
//Get all data and store it.
    
    
$ip_get         = $_SERVER['REMOTE_ADDR'];    //ip
    
$dns_get         = gethostbyaddr($_SERVER['REMOTE_ADDR']); //"dns"
    
$useragent_get     = $_SERVER['HTTP_USER_AGENT']; //"useragent"
    
$timeacces_get    = mktime(); //"dernierefoisvu"
    /* NOTE: ! CRITICAL SECURITY ISSUE ! Remove | from above variables !  */
    
    
    
    
$trouve = false;
    
//Si l'ip est déjà la on l'incrémente sinon on l'ajoute dans le tableau.
    
if ($visiteur_local != null) {
        
//Pour tous les éléments du tableau cherche si l'ip existe
        
for($i=0;$i<count($visiteur_local);$i++) {
            if(
$visiteur_local[$i][0] == $_SERVER['REMOTE_ADDR']) {
                
$trouve = $i;
            }
        }
    }
    
/*if($trouve===false) dieImageMessage("FALSE");
    else dieImageMessage("TRUE");*/
    
if($trouve===false) {
        
$counted = count($visiteur_local);
        
$visiteur_local[$counted][0] = $ip_get;    //ip
        
$visiteur_local[$counted][1] = $dns_get; //"dns"
        
$visiteur_local[$counted][2] = $useragent_get; //"useragent"
        
$visiteur_local[$counted][3] = $timeacces_get; //"dernierefoisvu"
    
}
    else {
        
$visiteur_local[$trouve][0] = $ip_get;    //ip
        
$visiteur_local[$trouve][1] = $dns_get; //"dns"
        
$visiteur_local[$trouve][2] = $useragent_get; //"useragent"
        
$visiteur_local[$trouve][3] = $timeacces_get; //"dernierefoisvu"
    
}
    return
$visiteur_local;
}

/* Ecrit le fichier sur le disque */
function flush_FILE($visiteur_local) {
    
$fich = fopen(FILE_LOCATION,'wb');
    
    
/*Pour chaque element du tableau on va écrire un ligne CSV*/
    
for($i=0;$i<count($visiteur_local);$i++) {
        if(
fwrite($fich,
                  
$visiteur_local[$i][0]."|".
                  
$visiteur_local[$i][1]."|".
                  
$visiteur_local[$i][2]."|".
                  
$visiteur_local[$i][3]."\n")===false)
            
dieImageMessage("Impossible d'écrire dans le fichier.");
        
    }
    
    
fclose($fich);
}

/*On degage tout ce qui es trop vieux du tableau.*/
function degagerTropVieux_FILE($visiteurs_local) {
    
/* On commence a la fin pour éviter les tableau incohérents (voir plus bas explication)*/
    
for($i=(count($visiteurs_local)-1);i<1;i--) {
        if((
$visiteurs_local[$i][3]) < (mktime()-$maxTime)) {
            
/*Attention ne fonctionne que parce que les plus vieux sont a la fin sinon il faudrait combler les clefs manquante exemple:
            [0] = hier [1] 5 jour [2] 2 jour laisserait [0] et [2] et donc le tableau n'est plus cohérent pour le code or le code tri en cas de bug ne pas oublier ca
            */
            
unset($visiteurs_local[$i]);
        }
    }
}

/* Trie le tableau de visiteur fourni selon la date (rang 4)*/
/* NOTE: Algorithme tri bulle peu performant.
   http://lwh.free.fr/pages/algo/tri/tri_bulle.htm
*/
function triertableau_FILE($visiteurs_local) {
    
//debug note on suppose que php sait faire des copies profondes de tableaux avec =.
    
do {
        
$permut = false;
        for(
$i=0;i<count($visiteurs_local);i++) {
            if(
$visiteurs_local[$i] > $visiteurs_local[$i+1]) {
                
$swap = $visiteurs_local[$i];
                
$visiteurs_local[$i] = $visiteurs_local[$i+1];
                
$visiteurs_local[$i+1] = $swap;
                
                
$permut = true;
            }
        }
    }while(
$permut == true);
    
    return
$visiteurs_local;
}
?>