<?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;
}
?>