New file |
0,0 → 1,276 |
<?php |
/*vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +------------------------------------------------------------------------------------------------------+ |
// | PHP version 4.1 | |
// +------------------------------------------------------------------------------------------------------+ |
// | Copyright (C) 2004 Tela Botanica (accueil@tela-botanica.org) | |
// +------------------------------------------------------------------------------------------------------+ |
// | This library 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.1 of the License, or (at your option) any later version. | |
// | | |
// | This library 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 library; if not, write to the Free Software | |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
// +------------------------------------------------------------------------------------------------------+ |
// CVS : $Id: projet_statistiques.php,v 1.1 2008-03-27 09:15:36 j_grillot Exp $ |
/** |
* Application projet |
* |
* Script pour calculer les statistiques |
* |
*@package projet |
//Auteur original : |
*@author Alexandre Granier <alexandre@tela-botanica.org> |
//Autres auteurs : |
*@author Julien Grillot <julien.grillot@gmail.com> |
*@copyright Tela-Botanica 2000-2005 |
*@version $Revision: 1.1 $ |
// +------------------------------------------------------------------------------------------------------+ |
*/ |
|
// +------------------------------------------------------------------------------------------------------+ |
// | ENTETE du PROGRAMME | |
// +------------------------------------------------------------------------------------------------------+ |
|
|
include_once PROJET_CHEMIN_APPLI.'classes/ezmlmAccessObject.class.php'; |
include_once PROJET_CHEMIN_BIBLIOTHEQUE_API.'pear/XML/RSS.php'; |
|
// Ne pas changer : les groupes Yahoo se basent toujours sur la semaine |
define("NB_SEC_INSERT", 7*24*3600); |
define("NB_SEC_UPDATE", 2*3600); |
define("URL_WIKINI", "http://www.tela-botanica.org/wikini/"); |
|
/** |
* Retourne le contenu de la page $adresse de facon asynchrone |
* @param string $adresse URL de la page dont le contenu doit etre recupere |
* @param int timeout temps d'attente maximum avant abandon de la recuperation |
*/ |
function monFileGetContents($adresse, $timeout = 30){ |
$url = parse_url($adresse); |
$url['port'] = isset($url['port']) ? $url['port'] : '80'; |
$url['scheme'] = isset($url['scheme']) ? strtoupper($url['scheme']) : 'HTTP'; |
$fp = fsockopen($url['host'], $url['port'], $errno, $errstr, $timeout); |
if (!$fp) { |
echo "Erreur de socket: $errno - $errstr<br />\n"; |
return false; |
} else { |
$header = 'GET '.$url['path'].' '.$url['scheme']."/1.1\r\n"; |
|
$header .= "Host: www.yahoo.com\r\n"; |
$header .= "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20021204\r\n"; |
$header .= "Referer: http://www.yahoo.com/\r\n"; |
|
$header .= 'Connection: Close\r\n\r\n'; |
|
fputs($fp, $header); |
stream_set_timeout($fp, $timeout); |
while (!feof($fp)) { |
$page .= fread($fp, 262144); |
} |
$stream = stream_get_meta_data($fp); |
fclose($fp); |
if ($stream['timed_out']) { |
echo 'Le délai de réponse de la page <b>'.$adresse.'</b> a dépassé le timeout de <b>'.$timeout.'</b> sec.'; |
return false; |
}else{ |
return $page; |
} |
} |
} |
|
/** |
* Procedure retrouvant le nombre de contribution, de message et le contenu de la page a partir des informations de la BDD |
* @param object $ligne resultat d'un fetch row contenant l'url du document a analyser |
* @param int $nombre_contrib recupere le nombre de contributions du projet |
* @param int $nombre_message recupere le nombre de nouveaux messages du projet |
* @return false si la fonction echoue lors de la tentative de recuperation des donnees utiles |
*/ |
function analyser($ligne, &$nombre_contrib, &$nombre_message) { |
$nombre_contrib='0'; |
$nombre_msg='0'; |
$r=false; |
|
// Recuperation du nbre de message |
$xml_parser = &new ezmlmAccessObject('nombre_messages', $ligne->pl_domaine, $ligne->pl_nom_liste, $GLOBALS['lang']) ; |
$xml_parser->load(); |
|
ob_start(); |
$xml_parser->parse(); |
$nombre_message = ob_get_contents(); |
if(!$nombre_message)$nombre_message='0'; |
ob_end_clean(); |
|
// Si AGO_A_NOMGRP alors il n'y a pas de flux RSS (groupe Yahoo, cad pas Tela) |
if($ligne->AGO_A_NOMGRP) { |
$url='http://fr.groups.yahoo.com/group/'.$ligne->AGO_A_NOMGRP; |
|
// Recherche du schema retrouvant le nombre de nouveaux message dans la semaine |
$pattern='>([0-9]+)</span> nouveau'; |
|
// Quelques soucis avec la version asynchrone |
//$contenu=monFileGetContents($url); |
$contenu=file_get_contents($url); |
|
$r=($contenu?true:false); |
ereg($pattern, $contenu, $no); |
$nombre_message=$no[1]; |
|
|
} else { |
// Parse le flux RSS généré par wikini |
$rss =& new XML_RSS(URL_WIKINI.$ligne->p_wikini.'/wakka.php?wiki=DerniersChangementsRSS/xml'); |
$rss->parse(); |
|
// On va compter le nombre de modification depuis les x derniers jours (voirs constantes) |
foreach ($rss->getItems() as $item) { |
// Le script doit être compatiable avec plusieurs formats de date |
if ($item['pubDate']) { |
if (strtotime($item['pubDate'])>time()-NB_SEC_INSERT) $nombre_contrib++; |
|
} else { |
$date = substr($item['title'], strlen($item['title'])-18); |
if ($date>date("Y m d - H:i", time()-NB_SEC_INSERT)) $nombre_contrib++; |
} |
} |
|
$r=true; |
|
} |
|
return $r; |
} |
|
// Pour calculer le temps d'execution du script |
$start=microtime(true); |
|
|
// +------------------------------------------------------------------------------------------------------+ |
// | CORPS du PROGRAMME | |
// +------------------------------------------------------------------------------------------------------+ |
|
|
// requete pour recuperer la liste des projets |
$requete = 'select count(distinct psu_id_utilisateur) as nb_utilisateur, count(distinct pil_id_utilisateur) as nb_utilisateur_liste, count(distinct projet_documents.pd_id) as nb_doc, p_wikini, ' . |
'p_id, p_titre, p_resume, projet_lien_liste.pl_id_liste, pl_domaine,pl_nom_liste,AGO_A_NOMGRP ' . |
'from projet left join projet_lien_liste on p_id=projet_lien_liste.pl_id_projet ' . |
'left join projet_liste on projet_lien_liste.pl_id_liste=projet_liste.pl_id_liste ' . |
'left join projet_inscription_liste on (projet_inscription_liste.pil_id_liste=projet_liste.pl_id_liste and pil_date_inscription > date_sub(now(), interval 1 week)) ' . |
'left join projet_documents on (p_id=pd_ce_projet and pd_date_de_mise_a_jour > date_sub(now(), interval 1 week)) ' . |
'left join projet_statut_utilisateurs on p_id=psu_id_projet ' . |
'left join projet_lien_liste_externe on plle_id_projet=p_id ' . |
'left join agora on plle_id_liste=AGO_A_ID ' . |
'group by p_id order by p_titre' ; |
|
$resultat = $this->_db->query($requete) ; |
if (DB::isError($resultat)) { |
return ("Echec de la requete<br />".$resultat->getMessage()."<br />".$resultat->getDebugInfo()) ; |
} |
$res .= '<h1>Statistiques des projets</h1>'; |
|
// Un tableau c'est bien mais un beau tableau c'est mieux. |
$res .= '<style type="text/css">'; |
$res .= '.stats { border-spacing: 0px; }'; |
$res .= '.stats .stat_nb { text-align: center; }'; |
$res .= '.stats th { font-weight: bold; }'; |
$res .= '.stats td { border-bottom: 1px #ddd solid; }'; |
$res .= '.warning { color: #800; font-weight: bold; }'; |
$res .= '</style>'; |
|
$calculs=false; |
|
$res .= '<table cellspacing="0" class="stats" style="width: 100%"><tr><th>Nom du projet</th><th>Nom liste</th><th>Inscrits</th><th>Utilisateurs</th><th>Nb msg</th><th>Nb doc</th><th>Nb contrib</th></tr>'; |
|
$nombre_contrib = 0; |
$nombre_message = 0; |
|
while ($ligne = $resultat->fetchRow(DB_FETCHMODE_OBJECT)) { |
$nombre_contrib = 0; |
$nombre_message = 0; |
|
// On verifie la date de derniere mise à jour |
$requete_verif='SELECT * FROM projet_statistiques WHERE ps_ce_projet="'.$ligne->p_id.'" ORDER BY ps_date DESC LIMIT 1'; |
$resultat_verif = $this->_db->query($requete_verif); |
if (DB::isError($resultat_verif)) { |
return $resultat_verif->getMessage().$resultat_verif; |
} |
$ligne_verif = $resultat_verif->fetchRow(DB_FETCHMODE_OBJECT); |
|
// Si elle remonte a plus de deux heure, on sauvegarde, et a plus de 7 jours, on archive et créé une nouvelle entrée |
if($ligne_verif->ps_date > date("Y-m-d H:i:s", time()-NB_SEC_INSERT)) { |
if($ligne_verif->ps_maj < date("Y-m-d H:i:s", time()-NB_SEC_UPDATE)) { |
|
// Recupere nombre_contrib et nombre_message |
$calculs=analyser($ligne, $nombre_contrib, $nombre_message); |
|
$requete_maj = 'UPDATE projet_statistiques SET ps_msg_derniere_semaine="'.$nombre_message.'", ps_doc_derniere_semaine="'.$ligne->nb_doc.'", ps_nombre_inscrit="'.$ligne->nb_utilisateur.'", ps_nombre_inscrit_liste="'.$ligne->nb_utilisateur_liste.'", ps_modifwiki_derniere_semaine="'.$nombre_contrib.'", ps_maj=NOW() WHERE ps_ce_projet="'.$ligne->p_id.'" AND ps_date="'.$ligne->ps_date.'"'; |
$resultat_maj = $this->_db->query($requete_maj); |
if (DB::isError($resultat_maj)) { |
return $resultat_maj->getMessage().$requete_maj; |
} |
} else { |
|
$nombre_contrib = $ligne_verif->ps_modifwiki_derniere_semaine; |
$nombre_message = $ligne_verif->ps_msg_derniere_semaine; |
|
} |
|
} else { |
|
// Recupere nombre_contrib et nombre_message |
$calculs=analyser($ligne, $nombre_contrib, $nombre_message); |
|
$requete_maj = 'INSERT INTO projet_statistiques (ps_ce_projet, ps_msg_derniere_semaine, ps_doc_derniere_semaine, ps_nombre_inscrit, ps_nombre_inscrit_liste, ps_modifwiki_derniere_semaine, ps_date, ps_maj) '. |
'VALUES ("'.$ligne->p_id.'", "'.$nombre_message.'", "'.$ligne->nb_doc.'", "'.$ligne->nb_utilisateur.'", "'.$ligne->nb_utilisateur_liste.'", "'.$nombre_contrib.'", NOW(), NOW())'; |
$resultat_maj = $this->_db->query($requete_maj); |
if (DB::isError($resultat_maj)) { |
return $resultat_maj->getMessage().$requete_maj; |
} |
} |
|
// Et on affiche les stats courantes |
$res .= '<tr><td>'.$ligne->p_titre.'</td><td>'.($ligne->pl_nom_liste?$ligne->pl_nom_liste:$ligne->AGO_A_NOMGRP.' (Yahoo)').'</td><td class="stat_nb">'.$ligne->nb_utilisateur_liste.'</td><td class="stat_nb">'.$ligne->nb_utilisateur.'</td><td class="stat_nb">'.$nombre_message.'</td><td class="stat_nb">'.$ligne->nb_doc.'</td><td class="stat_nb">'.$nombre_contrib.'</td></tr>'; |
} |
$res .= '</table>'; |
|
// Met a jour les statistiques et somme d'activite |
$sql="update `projet_statistiques` set ps_somme=(ps_msg_derniere_semaine +ps_doc_derniere_semaine+ps_nombre_inscrit_liste+ps_modifwiki_derniere_semaine);"; |
$resultat = $this->_db->query($sql); |
if (DB::isError($resultat)) { |
return $resultat->getMessage().$sql; |
} |
|
// On cherche le max pour ponderer les sommes |
$sql='SELECT MAX( ps_somme ) AS max FROM projet_statistiques WHERE ps_date>=CURDATE()'; |
$resultat = $this->_db->query($sql); |
if (DB::isError($resultat)) { |
return $resultat->getMessage().$sql; |
} |
$tresultat = $resultat->fetchRow(DB_FETCHMODE_OBJECT); |
|
// On pondere |
$sql="UPDATE `projet_statistiques` SET ps_pourcent=ps_somme / ".($tresultat->max?$tresultat->max:1)." * 100 WHERE ps_date>=CURDATE();"; |
$resultat = $this->_db->query($sql); |
if (DB::isError($resultat)) { |
return $resultat->getMessage().$sql; |
} |
|
// On affiche quelques infos inutiles mais indispensables |
$res .= '<p>'; |
if(!$calculs)$res .= '<span class="warning">Les variables nb_msg et nb_contrib n\'ont pas été calculées (datent de moins de '.round(NB_SEC_UPDATE/3600).' heures)</span><br />'; |
$res .= 'Executé en '.(round((microtime(true)-$start)*1000)/1000).' secondes.</p>'; |
|
return $res; |
|
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log: not supported by cvs2svn $ |
* +--Fin du code ----------------------------------------------------------------------------------------+ |
*/ |
?> |