/branches/v1.7-oxygene/widget/modules/vote/bibliotheque/Cache.php |
---|
New file |
0,0 → 1,127 |
<?php |
class Cache { |
private $actif = null; |
private $dossier_stockage = null; |
private $duree_de_vie = null; |
public function __construct($dossier_stockage = null, $duree_de_vie = null, $activation = true) { |
$this->actif = ($activation) ? true : false; |
if ($this->actif) { |
$this->dossier_stockage = $dossier_stockage; |
if (is_null($dossier_stockage)) { |
$this->dossier_stockage = self::getDossierTmp(); |
} |
$this->duree_de_vie = $duree_de_vie; |
if (is_null($duree_de_vie)) { |
$this->duree_de_vie = 3600*24; |
} |
} |
} |
public function charger($id) { |
$contenu = false; |
if ($this->actif) { |
$chemin_fichier_cache = $this->dossier_stockage.DIRECTORY_SEPARATOR.$id.'.txt'; |
if (file_exists($chemin_fichier_cache ) && (time() - @filemtime($chemin_fichier_cache) < $this->duree_de_vie)) { |
$contenu = file_get_contents($chemin_fichier_cache); |
} |
} |
return $contenu; |
} |
public function sauver($id, $contenu) { |
if ($this->actif) { |
$chemin_fichier_cache = $this->dossier_stockage.DIRECTORY_SEPARATOR.$id.'.txt'; |
if (!file_exists($chemin_fichier_cache) || (time() - @filemtime($chemin_fichier_cache) > $this->duree_de_vie)) { |
$fh = fopen($chemin_fichier_cache,'w+'); |
if ($fh) { |
fputs($fh, $contenu); |
fclose($fh); |
} |
} |
} |
} |
/** |
* Détermine le dossier système temporaire et détecte si nous y avons accès en lecture et écriture. |
* |
* Inspiré de Zend_File_Transfer_Adapter_Abstract & Zend_Cache |
* |
* @return string|false le chemine vers le dossier temporaire ou false en cas d'échec. |
*/ |
private static function getDossierTmp() { |
$dossier_tmp = false; |
foreach (array($_ENV, $_SERVER) as $environnement) { |
foreach (array('TMPDIR', 'TEMP', 'TMP', 'windir', 'SystemRoot') as $cle) { |
if (isset($environnement[$cle])) { |
if (($cle == 'windir') or ($cle == 'SystemRoot')) { |
$dossier = realpath($environnement[$cle] . '\\temp'); |
} else { |
$dossier = realpath($environnement[$cle]); |
} |
if (self::etreAccessibleEnLectureEtEcriture($dossier)) { |
$dossier_tmp = $dossier; |
break 2; |
} |
} |
} |
} |
if ( ! $dossier_tmp) { |
$dossier_televersement_tmp = ini_get('upload_tmp_dir'); |
if ($dossier_televersement_tmp) { |
$dossier = realpath($dossier_televersement_tmp); |
if (self::etreAccessibleEnLectureEtEcriture($dossier)) { |
$dossier_tmp = $dossier; |
} |
} |
} |
if ( ! $dossier_tmp) { |
if (function_exists('sys_get_temp_dir')) { |
$dossier = sys_get_temp_dir(); |
if (self::etreAccessibleEnLectureEtEcriture($dossier)) { |
$dossier_tmp = $dossier; |
} |
} |
} |
if ( ! $dossier_tmp) { |
// Tentative de création d'un fichier temporaire |
$fichier_tmp = tempnam(md5(uniqid(rand(), TRUE)), ''); |
if ($fichier_tmp) { |
$dossier = realpath(dirname($fichier_tmp)); |
unlink($fichier_tmp); |
if (self::etreAccessibleEnLectureEtEcriture($dossier)) { |
$dossier_tmp = $dossier; |
} |
} |
} |
if ( ! $dossier_tmp && self::etreAccessibleEnLectureEtEcriture('/tmp')) { |
$dossier_tmp = '/tmp'; |
} |
if ( ! $dossier_tmp && self::etreAccessibleEnLectureEtEcriture('\\temp')) { |
$dossier_tmp = '\\temp'; |
} |
return $dossier_tmp; |
} |
/** |
* Vérifie si le fichier ou dossier est accessible en lecture et écriture. |
* |
* @param $ressource chemin vers le dossier ou fichier à tester |
* @return boolean true si la ressource est accessible en lecture et écriture. |
*/ |
protected static function etreAccessibleEnLectureEtEcriture($ressource){ |
$accessible = false; |
if (is_readable($ressource) && is_writable($ressource)) { |
$accessible = true; |
} |
return $accessible; |
} |
} |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/vote.tpl.html |
---|
New file |
0,0 → 1,113 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
<html xmlns="http://www.w3.org/1999/xhtml"> |
<head> |
<title>Votez !</title> |
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> |
<meta http-equiv="Content-style-type" content="text/css" /> |
<meta http-equiv="Content-script-type" content="text/javascript" /> |
<meta http-equiv="Content-language" content="fr" /> |
<meta name="revisit-after" content="15 days" /> |
<meta name="robots" content="index,follow" /> |
<meta name="author" content="Delphine Cauquil, Aurélien Peronnet" /> |
<meta name="keywords" content="Tela Botanica, photographie, DEL" /> |
<meta name="description" content="Widget de vote sur les dernières images proposées dans DEL" /> |
<!-- Spécial mobile --> |
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> |
<!-- Favicones --> |
<link rel="icon" type="image/png" href="http://resources.tela-botanica.org/tb/img/16x16/favicon.png" /> |
<link rel="shortcut icon" type="image/x-icon" href="http://resources.tela-botanica.org/tb/img/16x16/favicon.ico" /> |
<!-- Feuilles de styles --> |
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" /> |
<link rel="stylesheet" type="text/css" href="<?=$url_css?>vote.css" media="screen" /> |
<!-- Javascript : bibliothèques --> |
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script> |
<script type="text/Javascript"> |
</script> |
<script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script> |
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script> |
<!-- attention le script suivant a besoin des variables globales initialisées ci dessous, donc, ne rien utiliser |
avant le document.ready() --> |
<script src="<?=$url_js?>vote.js"></script> |
</head> |
<body> |
<!-- WIDGET:DEL:VOTE - DEBUT --> |
<div data-role="page"> |
<!-- Variables globales à réinjecter à chaque changement de page |
(hors jquery mobile ne recharge pas le contenu du header --> |
<script type="text/Javascript"> |
//<![CDATA[ |
var g_urlServiceVotes = "<?= $donnees['url_service_votes']; ?>"; |
var g_urlServiceUtilisateurs = "<?= $donnees['url_service_utilisateurs']; ?>"; |
var g_idObservation = "<?= $donnees['id_observation']; ?>"; |
<?= $donnees['votes_js']; ?>; |
//]]> |
</script> |
<!-- /navbar --> |
<div data-role="header" data-position="fixed"> |
<div data-role="navbar" > |
<ul> |
<?php if($donnees['urls_navigation']['url_precedent'] != null) { ?> |
<li><a id="url_precedent" href="<?= $donnees['urls_navigation']['url_precedent']; ?>" data-transition="reverse slide">Précédent</a></li> |
<?php } ?> |
<?php if($donnees['urls_navigation']['url_suivant'] != null) { ?> |
<li><a id="url_suivant" href="<?= $donnees['urls_navigation']['url_suivant']; ?>" data-transition="slide">Suivant</a></li> |
<?php } ?> |
</ul> |
</div> |
</div> |
<!-- /navbar --> |
<div class="del-vote-contenu"> |
<div class="images"> |
<div style="height:305px"> |
<img class="image_principale" src="<?= str_replace('XL', 'CRS', $donnees['url']); ?>" alt="image" /> |
</div> |
<div class="conteneur_image_secondaire"> |
<?php $premiere_image = true; ?> |
<?php foreach($donnees['images'] as $image) : ?> |
<img class="image_secondaire <?php if($premiere_image) { echo 'image_active';} ?>" src="<?= str_replace('XL', 'CRX2S', $image['binaire.href']); ?>" alt="image" /> |
<?php $premiere_image = false; ?> |
<?php endforeach ?> |
</div> |
</div> |
<div class="info_observation"> |
<?= $donnees['titre']; ?> |
</div> |
<ul class="ui-listview" data-role="listview"> |
<?php foreach($donnees['liste_votes_determination'] as $vote_determination) : ?> |
<li class="ui-li ui-li-static ui-body-c"> |
<div class="intitule_determination"> |
<div><?= $vote_determination['nom_sel']; ?></div> |
<div class="auteur_determination">Proposé par : <?= $vote_determination['auteur_intitule']; ?></div> |
</div> |
<div id="vote_determination_<?= $vote_determination['id_commentaire']; ?>" class="votes_determination"> |
<a href="#" class="bouton_vote bouton_vote_oui" data-role="button" data-mini="true" data-inline="true"> oui</a> |
<span class="nb_votes nb_votes_oui"> |
<?= $vote_determination['votes']['oui']; ?> |
</span> |
<a href="#" class="bouton_vote bouton_vote_non" data-role="button" data-mini="true" data-inline="true"> non</a> |
<span class="nb_votes nb_votes_non"> |
<?= $vote_determination['votes']['non']; ?> |
</span> |
</div> |
<hr style="visibility:hidden;clear:both" /> |
</li> |
<?php endforeach ?> |
</ul> |
</div> |
<div data-role="footer" data-theme="b"> |
<div data-role="navbar" > |
<ul> |
<li><a href="">Aide</a></li> |
<li><a href="">Se connecter</a></li> |
</ul> |
</div> |
</div> |
</div> |
<!-- WIDGET:DEL:VOTE - FIN --> |
</body> |
</html> |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/vote_ajax.tpl.html |
---|
New file |
0,0 → 1,54 |
<!-- WIDGET:DEL:VOTE - DEBUT --> |
<div id="contenu" data-role="page"> |
<!-- /navbar --> |
<div data-role="header" data-position="fixed"> |
<div data-role="navbar" > |
<ul> |
<?php if($donnees['urls_navigation']['url_precedent'] != null) { ?> |
<li><a href="<?= $donnees['urls_navigation']['url_precedent']; ?>" class="ui-btn-active">Précédent</a></li> |
<?php } ?> |
<?php if($donnees['urls_navigation']['url_suivant'] != null) { ?> |
<li><a href="<?= $donnees['urls_navigation']['url_suivant']; ?>">Suivant</a></li> |
<?php } ?> |
</ul> |
</div> |
</div> |
<!-- /navbar --> |
<div class="del-vote-contenu"> |
<img id="image_principale" src="<?= str_replace('XL', 'CRS', $donnees['url']); ?>" alt="image" /> |
<div class="conteneur_image_secondaire"> |
<?php $premiere_image = true; ?> |
<?php foreach($donnees['images'] as $image) : ?> |
<img class="image_secondaire <?php if($premiere_image) { echo 'image_active';} ?>" src="<?= str_replace('XL', 'CRX2S', $image['binaire.href']); ?>" alt="image" /> |
<?php $premiere_image = false; ?> |
<?php endforeach ?> |
</div> |
<div class="info_observation"> |
<?= $donnees['titre']; ?> |
</div> |
<ul class="ui-listview" data-role="listview"> |
<?php foreach($donnees['liste_votes_determination'] as $vote_determination) : ?> |
<li class="ui-li ui-li-static ui-body-c"> |
<div class="intitule_determination"> |
<div><?= $vote_determination['nom_sel']; ?></div> |
<div class="auteur_determination">Proposé par : <?= $vote_determination['auteur_intitule']; ?></div> |
</div> |
<div id="vote_determination_<?= $vote_determination['id_commentaire']; ?>" class="votes_determination"> |
<a href="#" class="bouton_vote bouton_vote_oui" data-role="button" data-mini="true" data-inline="true"> oui</a> |
<span class="nb_votes nb_votes_oui"> |
<?= $vote_determination['votes']['oui']; ?> |
</span> |
<a href="#" class="bouton_vote bouton_vote_non" data-role="button" data-mini="true" data-inline="true"> non</a> |
<span class="nb_votes nb_votes_non"> |
<?= $vote_determination['votes']['non']; ?> |
</span> |
</div> |
<hr style="visibility:hidden;clear:both" /> |
</li> |
<?php endforeach ?> |
</ul> |
</div> |
<div data-role="footer" data-theme="b" data-position="fixed"> |
</div> |
</div> |
<!-- WIDGET:DEL:VOTE - FIN --> |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/aide.tpl.html |
---|
New file |
0,0 → 1,60 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
<html xmlns="http://www.w3.org/1999/xhtml"> |
<head> |
<title>Votez !</title> |
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> |
<meta http-equiv="Content-style-type" content="text/css" /> |
<meta http-equiv="Content-script-type" content="text/javascript" /> |
<meta http-equiv="Content-language" content="fr" /> |
<meta name="revisit-after" content="15 days" /> |
<meta name="robots" content="index,follow" /> |
<meta name="author" content="Delphine Cauquil, Aurélien Peronnet" /> |
<meta name="keywords" content="Tela Botanica, photographie, DEL" /> |
<meta name="description" content="Widget de vote sur les dernières images proposées dans DEL" /> |
<!-- Spécial mobile --> |
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> |
<!-- Favicones --> |
<link rel="icon" type="image/png" href="http://resources.tela-botanica.org/tb/img/16x16/favicon.png" /> |
<link rel="shortcut icon" type="image/x-icon" href="http://resources.tela-botanica.org/tb/img/16x16/favicon.ico" /> |
<!-- Feuilles de styles --> |
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" /> |
<link rel="stylesheet" type="text/css" href="<?=$url_css?>vote.css" media="screen" /> |
<!-- Javascript : bibliothèques --> |
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script> |
<script type="text/Javascript"> |
//<![CDATA[ |
$(document).bind("mobileinit", function(){ |
$.extend( $.mobile , { |
ajaxEnabled: false |
}); |
}); |
//]]> |
</script> |
<script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script> |
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script> |
<script src="<?=$url_js?>vote.js"></script> |
</head> |
<body> |
<!-- WIDGET:DEL:VOTE - DEBUT --> |
<div data-role="page"> |
<div class="aide-contenu"> |
À rédiger ! |
</div> |
<div data-role="footer" data-theme="b" data-position="fixed"> |
<div data-role="navbar" > |
<ul> |
<li><a href="">Aide</a></li> |
<li><a href="">Se connecter</a></li> |
</ul> |
</div> |
</div> |
</div> |
<!-- WIDGET:DEL:VOTE - FIN --> |
</body> |
</html> |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/chargement.gif |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/chargement.gif |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/fermeture.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = image/png |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/fermeture.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+image/png |
\ No newline at end of property |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/tri.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = image/png |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/tri.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+image/png |
\ No newline at end of property |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/ouverture.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = image/png |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/ouverture.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+image/png |
\ No newline at end of property |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/tri_croissant.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = image/png |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/tri_croissant.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+image/png |
\ No newline at end of property |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/information.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = image/png |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/information.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+image/png |
\ No newline at end of property |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/tri_decroissant.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = image/png |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/images/tri_decroissant.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+image/png |
\ No newline at end of property |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/scripts/vote.js |
---|
New file |
0,0 → 1,162 |
/**----------------------------------------------------------------------------------------------------------*/ |
/** Variables globales et initialisation |
* Variables crées par php dans le squelettes |
* |
* var g_idObservation : id de l'observation en cours de consultation |
* var g_urlServiceVotes : url du service web des votes à appeler |
* var g_urlServiceUtilisateurs : url du service web utilisateur à appeler |
* var g_votes : tableau des votes |
* |
*/ |
var boutonClique = null; |
var g_idUtilisateur = null; |
$(document).ready(function() { |
getIdUtilisateur(); |
gererEvenementsClicsVotes(); |
gererEvenementClicImageSecondaire(); |
}); |
$(document).bind('pageload', function() { |
gererEvenementsClicsVotes(); |
mettreEnValeurVotesUtilisateur(); |
}); |
function getIdUtilisateur() { |
$.getJSON(g_urlServiceUtilisateurs, function(data) { |
g_idUtilisateur = data.id_utilisateur; |
mettreEnValeurVotesUtilisateur(); |
}); |
} |
function gererEvenementsClicsVotes() { |
$('.bouton_vote').unbind('click'); |
$('.bouton_vote').click(function(event) { |
boutonClique = $(this); |
voter(getValeurVote()); |
}); |
} |
function gererEvenementClicImageSecondaire() { |
$('.image_secondaire').live('click', function(event) { |
$('.image_secondaire').removeClass('image_active'); |
var urlImageSecondaire = $(this).attr('src'); |
urlImageSecondaireAgrandie = urlImageSecondaire.replace('CRX2S','CRS'); |
var urlImagePrincipale = $('.image_principale').attr('src'); |
urlImagePrincipaleMiniature = urlImagePrincipale.replace('CRS','CRX2S'); |
$(this).addClass('image_active'); |
$('.image_principale').attr('src', urlImageSecondaireAgrandie); |
}); |
} |
function getValeurVote() { |
valeur = 0; |
if(boutonClique.hasClass('bouton_vote_oui')) { |
valeur = 1; |
} |
return valeur; |
} |
function getIdProposition() { |
var chaineProposition = boutonClique.parent().attr('id'); |
return chaineProposition.replace('vote_determination_', ''); |
} |
/**----------------------------------------------------------------------------------------------------------*/ |
/** Affichage **/ |
function mettreEnValeurBoutonClique() { |
boutonClique.parent().find(".bouton_vote").removeClass("bouton_selectionne"); |
boutonClique.effect("highlight", {}, 500, function() {$(this).addClass("bouton_selectionne");}); |
} |
function mettreEnValeurVotesUtilisateur() { |
$('.votes_determination').each(function() { |
var id_proposition = $(this).attr('id').replace('vote_determination_', ''); |
if(g_votes[id_proposition] != undefined && g_votes[id_proposition][g_idUtilisateur] != undefined) { |
if(g_votes[id_proposition][g_idUtilisateur] == 1) { |
$(this).children('.bouton_vote_oui').addClass("bouton_selectionne"); |
} else { |
$(this).children('.bouton_vote_non').addClass("bouton_selectionne"); |
} |
} |
}); |
} |
function mettreAJourAffichageNbVotes(idProposition) { |
affichageVotes = boutonClique.parent().find(".nb_votes"); |
affichageVotes.each(function() { |
if($(this).hasClass("nb_votes_oui")) { |
$(this).html(calculerVotes(idProposition,1)); |
} |
if($(this).hasClass("nb_votes_non")) { |
$(this).html(calculerVotes(idProposition,0)); |
} |
}); |
} |
/**----------------------------------------------------------------------------------------------------------*/ |
/** Requetes **/ |
function getUrlVoteProposition(idProposition) { |
return g_urlServiceVotes+'/'+idProposition+'/vote/'; |
} |
function getMethodeRequete(idProposition, idUtilisateur) { |
var methode = "PUT"; |
if(g_votes[idProposition] != undefined && g_votes[idProposition] != null && |
g_votes[idProposition][idUtilisateur] != undefined && g_votes[idProposition][idUtilisateur] != null) { |
methode = "POST"; |
} |
return methode; |
} |
function voter(ouiOuNon) { |
var idProposition = getIdProposition(); |
var urlVote = getUrlVoteProposition(idProposition); |
var type = getMethodeRequete(idProposition, g_idUtilisateur); |
if(!voteEstIdentique(idProposition, g_idUtilisateur, ouiOuNon)) { |
$.ajax({ |
url : urlVote, |
type: type, |
data: "utilisateur="+g_idUtilisateur+"&valeur="+ouiOuNon |
}).done(function(data) { |
mettreAjourTableauVotes(idProposition, g_idUtilisateur, ouiOuNon); |
mettreAJourAffichageNbVotes(idProposition); |
mettreEnValeurBoutonClique(); |
boutonClique = null; |
}); |
} |
} |
/**----------------------------------------------------------------------------------------------------------*/ |
/** Mise à jour et accès au tableau des votes **/ |
function mettreAjourTableauVotes(idProposition, idUtilisateur, valeurVote) { |
if(g_votes[idProposition] == undefined) { |
g_votes[idProposition] = new Array(); |
} |
g_votes[idProposition][idUtilisateur] = valeurVote; |
} |
function calculerVotes(id_proposition, ouiOuNon) { |
var nb = 0; |
for (var votant in g_votes[id_proposition]) { |
if(g_votes[id_proposition][votant] == ouiOuNon) { |
nb++; |
} |
} |
return nb; |
} |
function voteEstIdentique(id_proposition, id_utilisateur, ouiOuNon) { |
return (g_votes[id_proposition] != undefined && |
g_votes[id_proposition][id_utilisateur] != undefined && |
g_votes[id_proposition][id_utilisateur] == ouiOuNon); |
} |
/branches/v1.7-oxygene/widget/modules/vote/squelettes/css/vote.css |
---|
New file |
0,0 → 1,53 |
@charset "UTF-8"; |
/*+-----------------------------------------------------------------------------------------------------------------+*/ |
/* Widget */ |
.intitule_determination { |
float:left; |
} |
.votes_determination { |
float:right; |
} |
.auteur_determination { |
font-style:italic; |
} |
.image_secondaire { |
height: 40px; |
cursor:pointer; |
} |
.nb_votes { |
position: relative; |
top: -12px; |
} |
.image_active { |
border: solid 1px black; |
} |
.bouton_selectionne > * { |
background-color: #BBBBBB; |
cursor: default; |
} |
.bouton_selectionne { |
cursor: default; |
} |
.lien_connexion { |
float: right; |
} |
.info_observation { |
font-size: 14px; |
font-weight: bold; |
padding-bottom: 5px; |
padding-left: 10px; |
padding-top: 5px; |
} |
.images { |
text-align: center; |
} |
/branches/v1.7-oxygene/widget/modules/vote/Vote.php |
---|
New file |
0,0 → 1,231 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Service affichant les dernières photo publiques du CEL ouvrable sous forme de diaporama. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* Cas d'utilisation et documentation : |
* @link http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=AideCELWidgetPhoto |
* |
* Paramètres : |
* ===> extra = booléen (1 ou 0) [par défaut : 1] |
* Affiche / Cache la vignette en taille plus importante au bas du widget. |
* ===> vignette = [0-9]+,[0-9]+ [par défaut : 4,3] |
* Indique le nombre de vignette par ligne et le nombre de ligne. |
* |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org) |
*/ |
class Vote extends WidgetCommun { |
const DS = DIRECTORY_SEPARATOR; |
const SERVICE_DEFAUT = 'photo'; |
private $ce_img_url_tpl = null; |
private $del_url_service_tpl = null; |
private $id_observation = null; |
/** |
* Méthode appelée par défaut pour charger ce widget. |
*/ |
public function executer() { |
$this->del_url_service_tpl = $this->config['vote']['baseURLServicesDelTpl']; |
$this->ce_img_url_tpl = $this->config['vote']['celImgUrlTpl']; |
$this->collecterParametres(); |
$ids_observations = $this->obtenirIdsObservation(); |
$donnees = $this->obtenirDonnees($this->id_observation); |
$widget['donnees']['id_observation'] = $this->id_observation; |
$widget['donnees']['titre'] = $this->construireTitreImage($donnees); |
$widget['donnees']['url'] = $this->obtenirUrlImage($donnees['images']); |
$widget['donnees']['images'] = $donnees['images']; |
$widget['donnees']['liste_votes_determination'] = $this->formaterDeterminations($donnees); |
$widget['donnees']['url_css'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/vote/squelettes/css/'); |
$widget['donnees']['url_js'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/vote/squelettes/scripts/'); |
$widget['donnees']['votes_js'] = $this->convertirTableauVotesEnJs($donnees['commentaires']); |
$widget['donnees']['url_service_votes'] = $this->del_url_service_tpl.'observations/'.$this->id_observation; |
$widget['donnees']['url_service_utilisateurs'] = $this->del_url_service_tpl.'utilisateurs/'; |
$widget['donnees']['urls_navigation'] = $this->construireUrlsSuivantesEtPrecedentes($ids_observations); |
if (isset($this->parametres['mode']) && $this->parametres['mode'] == 'ajax') { |
$squelette = dirname(__FILE__).self::DS.'squelettes'.self::DS.'vote_ajax.tpl.html'; |
} else { |
$squelette = dirname(__FILE__).self::DS.'squelettes'.self::DS.'vote.tpl.html'; |
} |
$contenu = $this->traiterSquelettePhp($squelette, $widget['donnees']); |
$this->envoyer($contenu); |
} |
private function collecterParametres() { |
$this->id_observation = (isset($_GET['id_observation'])) ? $_GET['id_observation'] : null; |
unset($_GET['id_observation']); |
$this->parametres = $_GET; |
} |
private function convertirParametresEnChaineRequeteService() { |
$parametresWs = array(); |
$mapping = $this->transformerEnTableau($this->config['vote']['mapping_masque']); |
if (!empty($this->parametres)) { |
foreach ($this->parametres as $parametre => $valeur) { |
if (isset($mapping[$parametre])) { |
$parametresWs[] = $mapping[$parametre].'='.urlencode($valeur); |
} |
} |
} |
$requete = (!empty($parametresWs)) ? '?'.implode('&', $parametresWs) : ''; |
return $requete; |
} |
private function convertirParametresEnChaineRequete() { |
$requete = str_replace('masque_','masque.',http_build_query($this->parametres)); |
if(!empty($this->parametres)) { |
$requete = '&'.$requete; |
} |
return $requete; |
} |
private function obtenirIdsObservation() { |
$url = $this->del_url_service_tpl.'observations'.$this->convertirParametresEnChaineRequeteService(); |
//exit('<pre>'.print_r($url, true).'</pre>'); |
$infos = json_decode(file_get_contents($url), true); |
//exit('<pre>'.print_r($infos, true).'</pre>'); |
$ids = array(); |
foreach ($infos['resultats'] as $resultat) { |
if ($this->id_observation == null) { |
$this->id_observation = $resultat['id_observation']; |
} |
$ids[] = $resultat['id_observation']; |
} |
return $ids; |
} |
private function obtenirUrlBaseWidget() { |
return $this->config['chemins']['baseURL'].'vote'; |
} |
private function construireUrlsSuivantesEtPrecedentes($tableau_id_observation) { |
$indices_id_obs = array_flip($tableau_id_observation); |
$indice_obs_courante = $indices_id_obs[$this->id_observation]; |
$url_base = $this->obtenirUrlBaseWidget(); |
$indice_predecent = isset($tableau_id_observation[$indice_obs_courante - 1]) ? $tableau_id_observation[$indice_obs_courante - 1] : ''; |
$indice_suivant = isset($tableau_id_observation[$indice_obs_courante + 1]) ? $tableau_id_observation[$indice_obs_courante + 1] : ''; |
$url_suivant = isset($tableau_id_observation[$indice_obs_courante + 1]) ? $url_base.'?id_observation='.$tableau_id_observation[$indice_obs_courante + 1].$this->convertirParametresEnChaineRequete() : null; |
$url_precedent = isset($tableau_id_observation[$indice_obs_courante - 1]) ? $url_base.'?id_observation='.$tableau_id_observation[$indice_obs_courante - 1].$this->convertirParametresEnChaineRequete() : null; |
return array('url_suivant' => $url_suivant, 'url_precedent' => $url_precedent); |
} |
private function obtenirDonnees($id_observation) { |
$donnees = json_decode(file_get_contents($this->del_url_service_tpl.'observations/'.$id_observation), true); |
//exit('<pre>'.print_r($donnees, true).'</pre>'); |
return $donnees; |
} |
private function construireTitreImage($donnees) { |
return 'Pris par '.$donnees['auteur.prenom'].' '.$donnees['auteur.nom'].' à '.$donnees['zone_geo'].' le '.$this->formaterDate($donnees['date_observation'],'%d/%m/%Y'); |
} |
private function obtenirUrlImage($images) { |
return $images[0]['binaire.href']; |
} |
private function formaterDeterminations($observation) { |
$liste_determinations = $observation['commentaires']; |
$liste_determinations_formatees = array(); |
$creerPropositionAPartirObservation = true; |
foreach ($liste_determinations as $determination) { |
if ($determination['nom_sel'] != null && $determination['nom_sel'] != '') { |
$liste_determinations_formatees[] = $this->formaterDetermination($determination); |
} |
if ($determination['nom_sel'] == $observation['determination.ns'] && |
$determination['auteur.id'] == $observation['auteur.id']) { |
$creerPropositionAPartirObservation = false; |
} |
} |
if ($creerPropositionAPartirObservation) { |
$liste_determinations_formatees[] = $this->creerDeterminationAPartirObservation($observation); |
} |
return $liste_determinations_formatees; |
} |
private function formaterDetermination($infos) { |
//exit('<pre>'.print_r($infos, true).'</pre>'); |
$determination = array( |
"id_commentaire" => $infos['id_commentaire'], |
"observation" => $infos['observation'], |
"proposition" => $infos['proposition'], |
"id_parent" => $infos['id_parent'], |
"texte" => $infos['texte'], |
"date" => $infos['date_observation'], |
"nom_sel" => $infos['nom_sel'], |
"auteur_intitule" => $this->formaterIntituleAuteur($infos), |
"votes" => $this->formaterVotes($infos['votes']) |
); |
return $determination; |
} |
private function creerDeterminationAPartirObservation($observation) { |
$determination = array( |
"id_commentaire" => "0", |
"observation" => $observation['id_observation'], |
"proposition" => "0", |
"id_parent" => "0", |
"texte" => null, |
"date" => $observation['date_observation'], |
"nom_sel" => $observation['determination.ns'], |
"auteur_intitule" => $this->formaterIntituleAuteur($observation), |
"votes" => array('oui' => 0, 'non' => 0) |
); |
return $determination; |
} |
private function formaterIntituleAuteur($donnees) { |
$intitule = 'Anonyme'; |
// TODO : si auteur.id existe, appelé le WS de l'annuaire... |
if (!empty($donnees['auteur.prenom']) && !empty($donnees['auteur.nom'])) { |
$intitule = $donnees['auteur.prenom'].' '.$donnees['auteur.nom']; |
} else if (!empty($donnees['auteur.courriel'])) { |
$intitule = strstr($donnees['auteur.courriel'], '@').'@...'; |
} |
return $intitule; |
} |
private function formaterVotes($liste_votes) { |
$liste_votes_formates = array('oui' => 0, 'non' => 0); |
foreach($liste_votes as $vote) { |
if($vote['vote'] == 1) { |
$liste_votes_formates['oui']++; |
} else { |
$liste_votes_formates['non']++; |
} |
} |
return $liste_votes_formates; |
} |
private function convertirTableauVotesEnJs($liste_commentaires) { |
$tableau_js = "var g_votes = new Array();"; |
foreach($liste_commentaires as $commentaire) { |
$tableau_js .= 'g_votes["'.$commentaire['id_commentaire'].'"] = new Array();'; |
if(isset($commentaire['votes'])) { |
foreach($commentaire['votes'] as $vote) { |
$tableau_js .= 'g_votes["'.$commentaire['id_commentaire'].'"]["'.$vote['auteur.id'].'"] = '.$vote['vote'].';'; |
} |
} |
} |
return $tableau_js; |
} |
} |
/branches/v1.7-oxygene/widget/modules/vote/config.defaut.ini |
---|
New file |
0,0 → 1,24 |
[vote] |
; URL de base des services web de DEL (avec le / final) |
baseURLServicesDelTpl = "http://api.tela-botanica.org/service:del:0.1/" |
; Squelette d'Url permettant d'afficher une image du CEL (remplace %s par l'id de l'image sans underscore) |
celImgUrlTpl = "http://api.tela-botanica.org/img:%s.jpg" |
; Mapping entre les paramètres d'appel de ce widget et les paramètres d'appel du ws «observations» de DEL |
mapping_masque = " |
filtre = masque, |
famille = masque.famille, |
genre = masque.genre, |
referentiel = masque.referentiel, |
ns = masque.ns, |
nn = masque.nn, |
auteur = masque.auteur, |
date-obs = masque.date, |
commune = masque.commune, |
dept = masque.departement, |
tag-cel = masque.tag_cel, |
sp = masque.espece, |
depart = navigation.depart, |
limite = navigation.limite, |
tri = tri, |
ordre = ordre, |
type = masque.type" |
/branches/v1.7-oxygene/widget/modules/vote |
---|
New file |
Property changes: |
Added: svn:ignore |
+config.ini |
/branches/v1.7-oxygene/widget/modules/statistiques/Statistiques.php |
---|
New file |
0,0 → 1,108 |
<?php |
/** |
* Widget fournissant des stats graphiques du CEL. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* @author Jean-Pascal MILCENT <jpm@clapas.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2010, Jean-Pascal MILCENT |
*/ |
restore_error_handler(); |
restore_exception_handler(); |
error_reporting(E_ALL); |
ini_set("display_errors", "1"); |
class Statistiques extends WidgetCommun { |
const DS = DIRECTORY_SEPARATOR; |
const PAGE_DEFAUT = 'defaut'; |
private $page; |
private $annee; |
/** |
* Méthode appelée avec une requête de type GET. |
*/ |
public function executer() { |
$retour = null; |
extract($this->parametres); |
$this->page = (isset($page)) ? $page : self::PAGE_DEFAUT; |
$this->annee = (isset($annee)) ? $annee : null; |
$methode = $this->traiterNomMethodeExecuter($this->page); |
if (method_exists($this, $methode)) { |
$retour = $this->$methode(); |
} else { |
$this->messages[] = "Le type de statistiques '$methode' n'est pas disponible."; |
} |
if (is_null($retour)) { |
$info = 'Un problème est survenu : '.print_r($this->messages, true); |
$this->envoyer($info); |
} else if (is_array($retour) && isset($retour['squelette'])) { // compatibilité avec un retour de HTML direct |
$squelette = dirname(__FILE__).DIRECTORY_SEPARATOR.'squelettes'.DIRECTORY_SEPARATOR.$retour['squelette'].'.tpl.html'; |
$html = $this->traiterSquelettePhp($squelette, $retour['donnees']); |
$this->envoyer($html); |
} else { |
$this->envoyer($retour); |
} |
} |
/** |
* Stats par défaut - exécute tout et met ça dans un squelette Bootstrap |
*/ |
public function executerDefaut() { |
$widget = null; |
$widget['squelette'] = 'stats_tout'; // squelette bootstrap unifié |
if (!is_null($widget)) { |
$widget['donnees']['url_css'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/statistiques/squelettes/css/stats_tout.css'); |
$widget['donnees']['url_js'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/statistiques/squelettes/js/defaut.js'); |
$widget['donnees']['url_script_navigation'] = sprintf($this->config['chemins']['baseURLRessources'], 'tb/reseau/navigation.js'); |
$widget['donnees']['url_js_bootstrap'] = sprintf($this->config['chemins']['baseURLRessources'], 'bootstrap/3.1.0/js/bootstrap.min.js'); |
$widget['donnees']['url_css_bootstrap'] = sprintf($this->config['chemins']['baseURLRessources'], 'bootstrap/3.1.0/css/bootstrap.min.css'); |
$widget['donnees']['url_image_chargement'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/statistiques/squelettes/img/chargement.gif'); |
$widget['donnees']['mode_serveur'] = $this->config['parametres']['modeServeur']; |
$widget['donnees']['url_widget'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'statistiques'); |
$widget['donnees']['url_service'] = sprintf($this->config['chemins']['baseURLServicesDelTpl'], 'CelStatistique'); |
$widget['donnees']['filtres'] = $this->parametres; |
$widget['donnees']['annee'] = $this->annee; |
} |
return $widget; |
} |
public function executerObservations() { |
$widget = null; |
$widget['donnees'] = (array) $this->statsObservations(); |
if (!is_null($widget)) { |
$widget['squelette'] = 'observations'; |
$widget['donnees']['annee'] = $this->annee; |
} |
return $widget; |
} |
private function statsObservations() { |
// Récupération des données au format Json |
$service = "statistiques/observations"; |
$parametres = array(); |
if (isset($this->parametres['annee'])) { |
$parametres[] = 'annee='.$this->parametres['annee']; |
} |
$service .= (count($parametres) > 0) ? '?'.implode('&', $parametres) : ''; |
$url = sprintf($this->config['chemins']['baseURLServicesDelTpl'], $service); |
$json = $this->getDao()->consulter($url); |
return (array) json_decode($json); |
} |
} |
/branches/v1.7-oxygene/widget/modules/statistiques/squelettes/css/stats_tout.css |
---|
New file |
0,0 → 1,83 |
/* Copié depuis http://getbootstrap.com/examples/dashboard/ */ |
.sub-header { |
border-bottom: 1px solid #EEEEEE; |
padding-bottom: 10px; |
} |
.sidebar { |
display: none; |
} |
.sidebar { |
background-color: #F5F5F5; |
border-right: 1px solid #EEEEEE; |
bottom: 0; |
display: block; |
left: 0; |
overflow-x: hidden; |
overflow-y: auto; |
padding: 20px; |
padding-top: 10px; |
position: fixed; |
top: 51px; |
z-index: 1000; |
} |
.nav-sidebar { |
margin-bottom: 20px; |
margin-left: -20px; |
margin-right: -21px; |
} |
.nav-sidebar > li > a { |
padding-left: 20px; |
padding-right: 20px; |
} |
.nav-sidebar > .active > a { |
background-color: #428BCA; |
color: #FFFFFF; |
} |
.nav-sidebar > li.separateur { |
padding-left: 20px; |
padding-right: 20px; |
font-size: 24px; |
height: 40px; |
line-height: 40px; |
} |
.main { |
padding: 20px; |
} |
@media (min-width: 768px) { |
.main { |
padding-left: 40px; |
padding-right: 40px; |
} |
} |
.main .page-header { |
margin-top: 0; |
} |
.placeholders { |
margin-bottom: 30px; |
text-align: center; |
} |
.placeholders h4 { |
margin-bottom: 0; |
} |
.placeholder { |
margin-bottom: 20px; |
} |
.placeholder img { |
border-radius: 50%; |
display: inline-block; |
} |
/* Styles non liés à bootstrap */ |
.flottant-gauche, .flottant-gauche img { |
float: left; |
} |
img.stats { |
border: 1px solid #000000; |
display: block; |
margin: 0.5em; |
} |
/branches/v1.7-oxygene/widget/modules/statistiques/squelettes/stats_tout.tpl.html |
---|
New file |
0,0 → 1,123 |
<!doctype html> |
<html lang="fr"> |
<head> |
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> |
<meta http-equiv="Content-style-type" content="text/css" /> |
<meta http-equiv="Content-script-type" content="text/javascript" /> |
<meta http-equiv="Content-language" content="fr" /> |
<meta name="revisit-after" content="15 days" /> |
<meta name="robots" content="index,follow" /> |
<meta name="author" content="Tela Botanica" /> |
<meta name="keywords" content="Statistiques, Identiplante, Pictoflora, Tela Botanica, graphiques" /> |
<meta name="description" content="Graphiques et statistiques sur Identiplante et Pictoflora" /> |
<!-- OpenGraph pour Facebook, Pinterest, Google+ --> |
<meta property="og:type" content="website" /> |
<meta property="og:title" content="Statistiques d'Identiplante et Pictoflora" /> |
<meta property="og:site_name" content="Tela Botanica" /> |
<meta property="og:description" content="Statistiques sur les données d'Identiplante et Pictoflora" /> |
<meta property="og:image" content="http://resources.tela-botanica.org/tb/img/256x256/carre_englobant.png" /> |
<meta property="og:image:type" content="image/png" /> |
<meta property="og:image:width" content="256" /> |
<meta property="og:image:height" content="256" /> |
<meta property="og:locale" content="fr_FR" /> |
<link rel="stylesheet" type="text/css" href="http://resources.tela-botanica.org/bootstrap/3.1.0/css/bootstrap.min.css" /> |
<link rel="stylesheet" type="text/css" href="<?=$url_css?>" media="screen" /> |
<script src="http://resources.tela-botanica.org/jquery/1.9.1/jquery.min.js"></script> |
<script src="http://resources.tela-botanica.org/bootstrap/3.1.0/js/bootstrap.min.js"></script> |
<script src="<?=$url_js?>"></script> |
<script src="<?=$url_script_navigation?>"></script> |
<title>Statistiques Identiplante / Pictoflora</title> |
<!-- Stats : Google Analytics --> |
<script type="text/javascript"> |
//<![CDATA[ |
var _gaq = _gaq || []; |
_gaq.push(['_setAccount', 'UA-20092557-1']); |
_gaq.push(['_trackPageview']); |
(function() { |
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; |
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; |
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); |
})(); |
//]]> |
</script> |
</head> |
<body> |
<div id="tb-navigation" data-courant="widget-del-statistiques" data-squelette="bootstrap3" data-mode="<?=$mode_serveur?>"> |
<!-- Contenu qui sera reporté dans la barre de navigation --> |
<form class="navbar-form navbar-left"> |
<select id="annee" name="annee" class="form-control"> |
<option value="">Année (toutes)</option> |
<?php foreach(range(date("Y"), 2010, -1) as $annee_possible): ?> |
<?php if ($annee == $annee_possible): ?> |
<option selected="selected" value="<?=$annee_possible?>"> |
<?php else: ?> |
<option value="<?=$annee_possible?>"> |
<?php endif; ?> |
<?=$annee_possible?></option> |
<?php endforeach; ?> |
</select> |
<button type="submit" class="btn btn-success">Go</button> |
</form> |
</div> |
<div class="container-fluid"> |
<div class="col-sm-3 col-md-2 sidebar" id="colonne-menu" data-url-widget="<?=$url_widget?>"> |
<ul class="nav nav-sidebar"> |
<li class="separateur"># Identiplante</li> |
<li class="active"><a href="#" data-portion="observations">Observations</a></li> |
<li><a href="#" data-portion="identifications">Identifications</a></li> |
<li><a href="#" data-portion="utilisateurs-ip">Utilisateurs</a></li> |
<li><a href="#" data-portion="frequentation-ip">Fréquentation</a></li> |
<li><a href="#" data-portion="listemeilleursproposeurs">Utilisateurs dont les propositions ont été votées positivement</a></li> |
<br/> |
<li class="separateur"># Pictoflora</li> |
<li><a href="#" data-portion="images">Images</a></li> |
<li><a href="#" data-portion="tags">Mots-clés</a></li> |
<li><a href="#" data-portion="utilisateurs-pf">Utilisateurs</a></li> |
<li><a href="#" data-portion="frequentation-pf">Fréquentation</a></li> |
<li><a href="#" data-portion="listemeilleurstags">Mots-clés les plus ajoutés</a></li> |
</ul> |
</div> |
<div class="col-md-offset-2 main"> |
<h1 class="page-header">Statistiques Identiplante / Pictoflora</h1> |
<div id="zone-chargement"> |
<img src="<?=$url_image_chargement?>" /> |
</div> |
<div class="resultat" id="emplacement-resultat-observations"> |
</div> |
<div class="resultat" id="emplacement-resultat-identifications"> |
</div> |
<div class="resultat" id="emplacement-resultat-utilisateurs-ip"> |
</div> |
<div class="resultat" id="emplacement-resultat-frequentation-ip"> |
</div> |
<div class="resultat" id="emplacement-resultat-listemeilleursproposeurs"> |
</div> |
<div class="resultat" id="emplacement-resultat-images"> |
</div> |
<div class="resultat" id="emplacement-resultat-tags"> |
</div> |
<div class="resultat" id="emplacement-resultat-utilisateurs-pf"> |
</div> |
<div class="resultat" id="emplacement-resultat-frequentation-pf"> |
</div> |
<div class="resultat" id="emplacement-resultat-listemeilleurstags"> |
</div> |
</div> |
</div> |
</body> |
</html> |
/branches/v1.7-oxygene/widget/modules/statistiques/squelettes/img/chargement.gif |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/v1.7-oxygene/widget/modules/statistiques/squelettes/img/chargement.gif |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/v1.7-oxygene/widget/modules/statistiques/squelettes/js/defaut.js |
---|
New file |
0,0 → 1,62 |
$(document).ready(function() { |
// config depuis PHP |
var urlWidget = $('#colonne-menu').data('url-widget'), |
annee = $('select#annee').val(); |
$('#zone-chargement').hide(); |
// écouteurs de clics sur le menu |
$('#colonne-menu .nav-sidebar a').click(function() { |
var portion = $(this).data('portion'), |
idEmplacement = '#emplacement-resultat-' + portion; |
// attente |
$('#zone-chargement').show(); |
masquerZonesResultat(); |
// rendu du contenu |
//alert('déjà chargé? : ' + $(idEmplacement).data('charge') + ' (' + ($(idEmplacement).data('charge') === true) + ')'); |
if ($(idEmplacement).data('charge')) { |
postChargement(idEmplacement, portion); |
} else { |
// rendu de la portion par le widget |
urlPortion = urlWidget + '?page=' + portion; |
if (annee) { |
urlPortion += '&annee=' + annee; |
} |
rendu = $.ajax({ |
url: urlPortion, |
type: 'get', |
success: function(data) { |
$(idEmplacement).html(data); |
postChargement(idEmplacement, portion); |
$(idEmplacement).data('charge', 'true'); |
}, |
error: function() { |
$(idEmplacement).html('Erreur: impossible de charger les statistiques'); |
postChargement(idEmplacement, portion); |
} |
}); |
} |
// interface |
$(this).parent().parent().find('li.active').removeClass('active'); |
$(this).parent().addClass('active'); |
return false; |
}); |
function postChargement(idEmplacement, portion) { |
$('#zone-chargement').hide(); |
// affichage de la portion demandée et masquage des autres |
masquerZonesResultat(); |
$(idEmplacement).show(); |
} |
function masquerZonesResultat() { |
$('div.resultat').hide(); |
} |
// chargement par défaut |
$('#colonne-menu a[data-portion="observations"]').trigger('click'); |
}); |
/branches/v1.7-oxygene/widget/modules/statistiques/squelettes/observations.tpl.html |
---|
New file |
0,0 → 1,10 |
<h2>Observations</h2> |
<?=(isset($annee) ? "<h4>Pour l'année " . $annee . "</h4>" : "")?> |
<ul> |
<li>Nombre moyen d'observations non identifiées soumises chaque mois : <strong><?=$moyenneObsSansNomParMois ?></strong></li> |
<li>Nombre moyen d'observations identifiées chaque mois : <strong><?=$moyenneObsIdentifieesParMois ?></strong></li> |
<li>Pourcentage des observations identifiees et validées à la fin de l'annee : <strong><?=number_format($pourcentageObsIdentifieesEnFinDAnnee, 0, ',', ' ') ?> %</strong></li> |
<li>Pourcentage des observations ayant atteint un consensus à la fin de l'annee : <strong><?=number_format($pourcentageObsIdentifieesEnFinDAnneePlusPlus, 0, ',', ' ') ?> %</strong></li> |
<li>Nombre moyen d'actions (commentaires et votes) par jour : <strong><?=$moyenneActionsParJour ?></strong></li> |
<li>Nombre de personnes envoyant au moins une proposition par mois : <strong><?=$personnesEnvoyantUnePropositionParMois ?></strong></li> |
</ul> |
/branches/v1.7-oxygene/widget/modules/statistiques |
---|
New file |
Property changes: |
Added: svn:ignore |
+config.ini |
/branches/v1.7-oxygene/widget/Widget.php |
---|
New file |
0,0 → 1,160 |
<?php |
// In : utf8 url_encoded (get et post) |
// Out : utf8 |
/** |
* La classe Widget analyser l'url et chage le widget correspondant. |
* Format d'url : |
* /widget/nom_du_widget?parametres1=ma_valeur1¶metre2=ma_valeur2 |
* Les widget sont dans des dossiers en minuscule correspondant au nom de la classe du widget. |
* Exemple : /widget/carto avec la classe Carto.php dans le dossier carto. |
* |
* |
* @author jpm |
* |
*/ |
class Widget { |
/** Les paramètres de configuration extrait du fichier .ini */ |
private static $config; |
/** Le nom du widget demandé. */ |
private $widget = null; |
/** Les chemins où l'autoload doit chercher des classes. */ |
private static $autoload_chemins = array(); |
/** Les paramètres de l'url $_GET nettoyés. */ |
private $parametres = null; |
/** |
* Constructeur. |
* Parse le fichier de configuraion "widget.ini" et parse l'url à la recherche du widget demandé. |
* @param str iniFile Configuration file to use |
*/ |
public function __construct($fichier_ini = 'widget.ini.php') { |
// Chargement de la configuration |
self::$config = parse_ini_file($fichier_ini, TRUE); |
// Paramêtres de config dynamiques |
self::$config['chemins']['baseURLAbsoluDyn'] = 'http://'.$_SERVER['SERVER_NAME'].self::$config['chemins']['baseURL'].'%s'; |
// Gestion de la mémoire maximum allouée aux services |
ini_set('memory_limit', self::$config['parametres']['limiteMemoire']); |
// Réglages de PHP |
setlocale(LC_ALL, self::$config['parametres']['locale']); |
date_default_timezone_set(self::$config['parametres']['fuseauHoraire']); |
// Gestion des erreurs |
error_reporting(self::$config['parametres']['erreurNiveau']); |
if (isset($_SERVER['REQUEST_URI']) && isset($_SERVER['QUERY_STRING'])) { |
$url_morceaux = $this->parserUrl(); |
if (isset($url_morceaux[0])) { |
$this->widget = $url_morceaux[0]; |
self::$config['chemins']['widgetCourantDossier'] = self::$config['chemins']['widgetsDossier'].strtolower($this->widget).DIRECTORY_SEPARATOR; |
$this->chargerWidgetConfig(); |
} |
// Chargement des chemins pour l'autoload |
$this->chargerCheminAutoload(); |
// Enregistrement de la méthode gérant l'autoload des classes |
spl_autoload_register(array('Widget', 'chargerClasse')); |
// Nettoyage du $_GET (sécurité) |
$this->collecterParametres(); |
} else { |
$e = 'Les widget nécessite les variables serveurs suivantes pour fonctionner : REQUEST_URI et QUERY_STRING.'; |
trigger_error($e, E_USER_ERROR); |
} |
} |
private function parserUrl() { |
if (strlen($_SERVER['QUERY_STRING']) == 0) { |
$len = strlen($_SERVER['REQUEST_URI']); |
} else { |
$len = -(strlen($_SERVER['QUERY_STRING']) + 1); |
} |
$url = substr($_SERVER['REQUEST_URI'], strlen(self::$config['chemins']['baseURL']), $len); |
$url_morceaux = explode('/', $url); |
return $url_morceaux; |
} |
private function collecterParametres() { |
if (isset($_GET) && $_GET != '') { |
$this->nettoyerGet(); |
$this->parametres = $_GET; |
} |
} |
private function nettoyerGet() { |
foreach ($_GET as $cle => $valeur) { |
$verifier = array('NULL', "\n", "\r", "\\", '"', "\x00", "\x1a", ';'); |
$_GET[$cle] = strip_tags(str_replace($verifier, '', $valeur)); |
} |
} |
private function chargerCheminAutoload() { |
$chemins_communs = explode(';', self::$config['chemins']['autoload']); |
$chemins_communs = array_map('trim', $chemins_communs); |
array_unshift($chemins_communs, ''); |
$chemins_widget = array(); |
if (isset(self::$config[$this->widget]['autoload'])) { |
$chemins_widget = explode(';', self::$config[$this->widget]['autoload']); |
foreach ($chemins_widget as $cle => $chemin) { |
$chemins_widget[$cle] = self::$config['chemins']['widgetCourantDossier'].trim($chemin); |
} |
} |
self::$autoload_chemins = array_merge($chemins_communs, $chemins_widget); |
} |
/** |
* La méthode chargerClasse() charge dynamiquement les classes trouvées dans le code. |
* Cette fonction est appelée par php5 quand il trouve une instanciation de classe dans le code. |
* |
*@param string le nom de la classe appelée. |
*@return void le fichier contenant la classe doit être inclu par la fonction. |
*/ |
public static function chargerClasse($classe) { |
if (class_exists($classe)) { |
return null; |
} |
foreach (self::$autoload_chemins as $chemin) { |
$chemin = $chemin.$classe.'.php'; |
if (file_exists($chemin)) { |
require_once $chemin; |
} |
} |
} |
/** |
* Execute le widget. |
*/ |
function executer() { |
if (!is_null($this->widget)) { |
$classe_widget = ucfirst($this->widget); |
$fichier_widget = self::$config['chemins']['widgetCourantDossier'].$classe_widget.'.php'; |
if (file_exists($fichier_widget)) { |
include_once $fichier_widget; |
if (class_exists($classe_widget)) { |
$widget = new $classe_widget(self::$config, $this->parametres); |
$widget->executer(); |
} |
} |
} |
} |
/** |
* Charge le fichier de config spécifique du wiget et fusionne la config avec celle partagés par l'ensemble des widgets. |
*/ |
private function chargerWidgetConfig() { |
$widget_config_ini_fichier = self::$config['chemins']['widgetCourantDossier'].'config.ini'; |
if (file_exists($widget_config_ini_fichier)) { |
$widget_config = parse_ini_file($widget_config_ini_fichier, TRUE); |
self::$config = array_merge(self::$config, $widget_config); |
} |
} |
} |
/branches/v1.7-oxygene/widget/.htaccess |
---|
New file |
0,0 → 1,13 |
<files *.ini> |
order deny,allow |
deny from all |
</files> |
#AddHandler x-httpd-php5 .php |
AddDefaultCharset UTF-8 |
RewriteEngine On |
# Redirections générale vers le fichier principal de Widget. |
RewriteCond %{REQUEST_FILENAME} !-d |
RewriteCond %{REQUEST_FILENAME} !-f |
RewriteRule ^.*$ index.php/ |
/branches/v1.7-oxygene/widget/bibliotheque/WidgetCommun.php |
---|
New file |
0,0 → 1,409 |
<?php |
abstract class WidgetCommun { |
protected $config = null; |
protected $parametres = null; |
protected $messages = array(); |
protected $debug = array(); |
public function __construct($config, $parametres) { |
$this->config = $config; |
$this->parserFichierIni($config['chemins']['widgetCourantDossier'].'config.ini'); |
$this->parametres = $parametres; |
} |
/** |
* Transformer une chaine en tableau si elle est de la forme : |
* - "cle=valeur,cle=valeur,..." : tableau associatif |
* - "valeur, valeur,..." : tableau |
* |
* @param String $chaine la chaine à transformer |
* @return le tableau issu de la chaine. |
*/ |
public function transformerEnTableau($chaine) { |
$tableau = array(); |
if (empty($chaine) === false) { |
$tableauPartiel = explode(',', $chaine); |
foreach ($tableauPartiel as $champ) { |
if (strpos($champ, '=') === false) { |
$tableau[] = trim($champ); |
} else { |
list($cle, $val) = explode('=', $champ); |
$tableau[trim($cle)] = trim($val); |
} |
} |
} |
return $tableau; |
} |
/** |
* Parse le fichier ini donné en paramètre |
* @param string $fichier_ini nom du fichier ini à parser |
* @return boolean true si le fichier ini a été trouvé. |
*/ |
private function parserFichierIni($fichier_ini) { |
$retour = false; |
if (file_exists($fichier_ini)) { |
$ini = parse_ini_file($fichier_ini, true); |
$this->fusionner($ini); |
$retour = true; |
} |
return $retour; |
} |
/** |
* fusionne un tableau de paramètres avec le tableau de config global |
* @param array $ini le tableau à fusionner |
*/ |
private function fusionner(array $ini) { |
$this->config = array_merge($this->config, $ini); |
} |
protected function traiterNomMethodeExecuter($nom) { |
$methode = 'executer'; |
$methode .= str_replace(' ', '', ucwords(str_replace('-', ' ', strtolower($nom)))); |
return $methode; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION des CLASSES CHARGÉES à la DEMANDE |
protected function getDao() { |
if (! isset($this->dao)) { |
$this->dao = new Dao(); |
} |
return $this->dao; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION DE MÉTHODES COMMUNES ENTRE LES SERVICES |
protected function getUrlImage($id, $format = 'L') { |
$url_tpl = $this->config['chemins']['celImgUrlTpl']; |
$id = sprintf('%09s', $id).$format; |
$url = sprintf($url_tpl, $id); |
return $url; |
} |
protected function encoderMotCle($mot_cle) { |
return md5(mb_strtolower($mot_cle)); |
} |
private function protegerMotsCles($mots_cles, $type) { |
$separateur = ($type == self::TYPE_IMG) ? ',' : ';' ; |
$mots_cles_a_proteger = explode($separateur,rtrim(trim($mots_cles), $separateur)); |
foreach ($mots_cles_a_proteger as $mot) { |
$mots_cles_proteges[] = $this->bdd->quote($mot); |
} |
$mots_cles = implode(',', $mots_cles_proteges); |
return $mots_cles; |
} |
protected function tronquerCourriel($courriel) { |
$courriel = preg_replace('/[^@]+$/i', '...', $courriel); |
return $courriel; |
} |
protected function nettoyerTableau($tableau) { |
foreach ($tableau as $cle => $valeur) { |
if (is_array($valeur)) { |
$valeur = $this->nettoyerTableau($valeur); |
} else { |
$valeur = $this->nettoyerTexte($valeur); |
} |
$tableau[$cle] = $valeur; |
} |
return $tableau; |
} |
protected function nettoyerTexte($txt) { |
$txt = preg_replace('/&(?!([a-z]+|#[0-9]+|#x[0-9][a-f]+);)/i', '&', $txt); |
$txt = preg_replace('/^(?:000null|null)$/i', '', $txt); |
return $txt; |
} |
protected function etreVide($valeur) { |
$vide = false; |
if ($valeur == '' || $valeur == 'null'|| $valeur == '000null' || $valeur == '0') { |
$vide = true; |
} |
return $vide; |
} |
protected function formaterDate($date_heure_mysql, $format = '%A %d %B %Y à %H:%M') { |
$date_formatee = ''; |
if (!$this->etreVide($date_heure_mysql)) { |
$timestamp = $this->convertirDateHeureMysqlEnTimestamp($date_heure_mysql); |
$date_formatee = strftime($format, $timestamp); |
} |
return $date_formatee; |
} |
protected function convertirDateHeureMysqlEnTimestamp($date_heure_mysql){ |
$val = explode(' ', $date_heure_mysql); |
$date = explode('-', $val[0]); |
$heure = explode(':', $val[1]); |
return mktime((int) $heure[0], (int) $heure[1], (int) $heure[2], (int) $date[1], (int) $date[2], (int) $date[0]); |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION DE L'IDENTIFICATION et des UTILISATEURS |
protected function getAuthIdentifiant() { |
$id = (isset($_SERVER['PHP_AUTH_USER'])) ? $_SERVER['PHP_AUTH_USER'] : null; |
return $id; |
} |
protected function getAuthMotDePasse() { |
$mdp = (isset($_SERVER['PHP_AUTH_PW'])) ? $_SERVER['PHP_AUTH_PW'] : null; |
return $mdp; |
} |
protected function authentifierAdmin() { |
$message_accueil = "Veuillez vous identifier avec votre compte Tela Botanica."; |
$message_echec = "Accès limité aux administrateurs du CEL.\n". |
"Votre tentative d'identification a échoué.\n". |
"Actualiser la page pour essayer à nouveau si vous êtes bien inscrit comme administrateur."; |
return $this->authentifier($message_accueil, $message_echec, 'Admin'); |
} |
protected function authentifierUtilisateur() { |
$message_accueil = "Veuillez vous identifier avec votre compte Tela Botanica."; |
$message_echec = "Accès limité aux utilisateur du CEL.\n". |
"Inscrivez vous http://www.tela-botanica.org/page:inscription pour le devenir.\n". |
"Votre tentative d'identification a échoué.\n". |
"Actualiser la page pour essayer à nouveau si vous êtes déjà inscrit ou contacter 'accueil@tela-botanica.org'."; |
return $this->authentifier($message_accueil, $message_echec, 'Utilisateur'); |
} |
private function authentifier($message_accueil, $message_echec, $type) { |
$id = $this->getAuthIdentifiant(); |
if (!isset($id)) { |
$this->envoyerAuth($message_accueil, $message_echec); |
} else { |
if ($type == 'Utilisateur' && $this->getAuthMotDePasse() == 'debug') { |
$autorisation = true; |
} else { |
$methodeAutorisation = "etre{$type}Autorise"; |
$autorisation = $this->$methodeAutorisation(); |
} |
if ($autorisation == false) { |
$this->envoyerAuth($message_accueil, $message_echec); |
} |
} |
return true; |
} |
protected function etreUtilisateurAutorise() { |
$identifiant = $this->getAuthIdentifiant(); |
$mdp = md5($this->getAuthMotDePasse()); |
$url = sprintf($this->config['authentification']['serviceUrlTpl'], $identifiant, $mdp); |
$json = $this->getDao()->consulter($url); |
$existe = json_decode($json); |
$autorisation = (isset($existe) && $existe) ? true :false; |
return $autorisation; |
} |
protected function etreAdminAutorise($identifiant) { |
$identifiant = $this->getAuthIdentifiant(); |
$autorisation = ($this->etreUtilisateurAutorise() && $this->etreAdminCel($identifiant)) ? true : false; |
return $autorisation; |
} |
protected function etreAdminCel($courriel) { |
$admins = $this->config['authentification']['administrateurs']; |
$courriels_autorises = explode(',', $admins); |
$autorisation = (in_array($courriel, $courriels_autorises)) ? true : false ; |
return $autorisation; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION de l'ENVOIE au NAVIGATEUR |
protected function envoyerJsonp($donnees = null, $encodage = 'utf-8') { |
$contenu = $_GET['callback'].'('.json_encode($donnees).');'; |
$this->envoyer($contenu, 'text/html', $encodage); |
} |
protected function envoyer($donnees = null, $mime = 'text/html', $encodage = 'utf-8') { |
// Traitements des messages d'erreurs et données |
if (count($this->messages) != 0) { |
header('HTTP/1.1 500 Internal Server Error'); |
$mime = 'text/html'; |
$encodage = 'utf-8'; |
$sortie = '<html>'. |
'<head><title>Messages</title></head>'. |
'<body><pre>'.implode("\n", $this->messages).'</pre><body>'. |
'</html>'; |
} else { |
$sortie = $donnees; |
if (is_null($donnees)) { |
$sortie = 'OK'; |
} |
} |
// Gestion de l'envoie du déboguage |
$this->envoyerDebogage(); |
// Envoie sur la sortie standard |
$this->envoyerContenu($encodage, $mime, $sortie); |
} |
private function envoyerDebogage() { |
if (!is_array($this->debug)) { |
$this->debug[] = $this->debug; |
} |
if (count($this->debug) != 0) { |
foreach ($this->debug as $cle => $val) { |
if (is_array($val)) { |
$this->debug[$cle] = print_r($val, true); |
} |
} |
header('X-DebugJrest-Data:'.json_encode($this->debug)); |
} |
} |
private function envoyerContenu($encodage, $mime, $contenu) { |
if (!is_null($mime) && !is_null($encodage)) { |
header("Content-Type: $mime; charset=$encodage"); |
} else if (!is_null($mime) && is_null($encodage)) { |
header("Content-Type: $mime"); |
} |
print_r($contenu); |
} |
private function envoyerAuth($message_accueil, $message_echec) { |
header('HTTP/1.0 401 Unauthorized'); |
header('WWW-Authenticate: Basic realm="'.mb_convert_encoding($message_accueil, 'ISO-8859-1', 'UTF-8').'"'); |
header('Content-type: text/plain; charset=UTF-8'); |
print $message_echec; |
exit(0); |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION DES SQUELETTES (PHP, TXT...) |
/** |
* Méthode prenant en paramètre un tableau associatif, les clés seront recherchées dans le texte pour être |
* remplacer par la valeur. Dans le texte, les clés devront être entre accolades : {} |
* |
* @param String $txt le texte où chercher les motifs. |
* @param Array $donnees un tableau associatif contenant les motifs à remplacer. |
* |
* @return String le texte avec les motifs remplacer par les valeurs du tableau. |
*/ |
protected static function traiterSqueletteTxt($txt, Array $donnees = array()) { |
$motifs = array(); |
$valeurs = array(); |
foreach ($donnees as $cle => $valeur) { |
if (strpos($cle, '{') === false && strpos($cle, '}') === false) { |
$motifs = '{'.$cle.'}'; |
$valeurs = $valeur; |
} |
} |
$txt = str_replace($motifs, $valeurs, $txt); |
return $txt; |
} |
/** |
* Méthode prenant en paramètre un chemin de fichier squelette et un tableau associatif de données, |
* en extrait les variables, charge le squelette et retourne le résultat des deux combinés. |
* |
* @param String $fichier le chemin du fichier du squelette |
* @param Array $donnees un tableau associatif contenant les variables a injecter dans le squelette. |
* |
* @return boolean false si le squelette n'existe pas, sinon la chaine résultat. |
*/ |
protected static function traiterSquelettePhp($fichier, Array $donnees = array()) { |
$sortie = false; |
if (file_exists($fichier)) { |
// Extraction des variables du tableau de données |
extract($donnees); |
// Démarage de la bufferisation de sortie |
ob_start(); |
// Si les tags courts sont activés |
if ((bool) @ini_get('short_open_tag') === true) { |
// Simple inclusion du squelette |
include $fichier; |
} else { |
// Sinon, remplacement des tags courts par la syntaxe classique avec echo |
$html_et_code_php = self::traiterTagsCourts($fichier); |
// Pour évaluer du php mélangé dans du html il est nécessaire de fermer la balise php ouverte par eval |
$html_et_code_php = '?>'.$html_et_code_php; |
// Interprétation du html et du php dans le buffer |
echo eval($html_et_code_php); |
} |
// Récupèration du contenu du buffer |
$sortie = ob_get_contents(); |
// Suppression du buffer |
@ob_end_clean(); |
} else { |
$msg = "Le fichier du squelette '$fichier' n'existe pas."; |
trigger_error($msg, E_USER_WARNING); |
} |
// Retourne le contenu |
return $sortie; |
} |
/** |
* Fonction chargeant le contenu du squelette et remplaçant les tags court php (<?= ...) par un tag long avec echo. |
* |
* @param String $chemin_squelette le chemin du fichier du squelette |
* |
* @return string le contenu du fichier du squelette php avec les tags courts remplacés. |
*/ |
private static function traiterTagsCourts($chemin_squelette) { |
$contenu = file_get_contents($chemin_squelette); |
// Remplacement de tags courts par un tag long avec echo |
$contenu = str_replace('<?=', '<?php echo ', $contenu); |
// Ajout systématique d'un point virgule avant la fermeture php |
$contenu = preg_replace("/;*\s*\?>/", "; ?>", $contenu); |
return $contenu; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// UTILITAIRES |
/** |
* Permet de trier un tableau multi-dimenssionnel en gardant l'ordre des clés. |
* |
* @param Array $array le tableau à trier |
* @param Array $cols tableau indiquant en clé la colonne à trier et en valeur l'ordre avec SORT_ASC ou SORT_DESC |
* @author cagret at gmail dot com |
* @see http://fr.php.net/manual/fr/function.array-multisort.php Post du 21-Jun-2009 12:38 |
*/ |
public static function trierTableauMd($array, $cols) { |
$colarr = array(); |
foreach ($cols as $col => $order) { |
$colarr[$col] = array(); |
foreach ($array as $k => $row) { |
$colarr[$col]['_'.$k] = strtolower($row[$col]); |
} |
} |
$params = array(); |
foreach ($cols as $col => $order) { |
$params[] =& $colarr[$col]; |
$params = array_merge($params, (array)$order); |
} |
call_user_func_array('array_multisort', $params); |
$ret = array(); |
$keys = array(); |
$first = true; |
foreach ($colarr as $col => $arr) { |
foreach ($arr as $k => $v) { |
if ($first) { |
$keys[$k] = substr($k,1); |
} |
$k = $keys[$k]; |
if (!isset($ret[$k])) { |
$ret[$k] = $array[$k]; |
} |
$ret[$k][$col] = $array[$k][$col]; |
} |
$first = false; |
} |
return $ret; |
} |
} |
/branches/v1.7-oxygene/widget/bibliotheque/Dao.php |
---|
New file |
0,0 → 1,155 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe modèle spécifique à l'application, donc d'accés au données, elle ne devrait pas être appelée de l'extérieur. |
* |
* @category php5 |
* @package Widget |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version SVN: $Id$ |
*/ |
class Dao { |
const HTTP_URL_REQUETE_SEPARATEUR = '&'; |
const HTTP_URL_REQUETE_CLE_VALEUR_SEPARATEUR = '='; |
private $http_methodes = array('GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'CONNECT', 'TRACE'); |
protected $parametres = null; |
private $url = null; |
private $reponse_entetes = null; |
//+----------------------------------------------------------------------------------------------------------------+ |
// ACCESSEURS |
public function getReponseEntetes($cle) { |
return $this->reponse_entetes; |
} |
public function getParametre($cle) { |
$valeur = (isset($this->parametres[$cle])) ? $this->parametres[$cle] : null; |
return $valeur; |
} |
public function ajouterParametre($cle, $valeur) { |
$this->parametres[$cle] = $valeur; |
} |
public function supprimerParametre($cle) { |
unset($this->parametres[$cle]); |
} |
public function nettoyerParametres() { |
$this->parametres = null; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// MÉTHODES |
public function consulter($url) { |
$retour = $this->envoyerRequete($url, 'GET'); |
return $retour; |
} |
public function ajouter($url, Array $donnees) { |
$retour = $this->envoyerRequete($url, 'PUT', $donnees); |
return $retour; |
} |
public function modifier($url, Array $donnees) { |
$retour = $this->envoyerRequete($url, 'POST', $donnees); |
return $retour; |
} |
public function supprimer($url) { |
$retour = $this->envoyerRequete($url, 'DELETE'); |
return $retour; |
} |
public function envoyerRequete($url, $mode, Array $donnees = array()) { |
$this->url = $url; |
$contenu = false; |
if (! in_array($mode, $this->http_methodes)) { |
$e = "Le mode de requête '$mode' n'est pas accepté!"; |
trigger_error($e, E_USER_WARNING); |
} else { |
if ($mode == 'GET') { |
$this->traiterUrlParametres(); |
} |
$contexte = stream_context_create(array( |
'http' => array( |
'method' => $mode, |
'header' => "Content-type: application/x-www-form-urlencoded\r\n", |
'content' => http_build_query($donnees, null, self::HTTP_URL_REQUETE_SEPARATEUR)))); |
$flux = @fopen($this->url, 'r', false, $contexte); |
if (!$flux) { |
$this->reponse_entetes = $http_response_header; |
$e = "L'ouverture de l'url '{$this->url}' par la méthode HTTP '$mode' a échoué!"; |
trigger_error($e, E_USER_WARNING); |
} else { |
// Informations sur les en-têtes et métadonnées du flux |
$this->reponse_entetes = stream_get_meta_data($flux); |
// Contenu actuel de $url |
$contenu = stream_get_contents($flux); |
fclose($flux); |
} |
$this->traiterEntete(); |
} |
$this->reinitialiser(); |
return $contenu; |
} |
private function traiterUrlParametres() { |
$parametres = array(); |
if (count($this->parametres) > 0) { |
foreach ($this->parametres as $cle => $valeur) { |
$cle = rawurlencode($cle); |
$valeur = rawurlencode($valeur); |
$parametres[] = $cle.self::HTTP_URL_REQUETE_CLE_VALEUR_SEPARATEUR.$valeur; |
} |
$url_parametres = implode(self::HTTP_URL_REQUETE_SEPARATEUR, $parametres); |
$this->url = $this->url.'?'.$url_parametres; |
} |
} |
private function traiterEntete() { |
$infos = $this->analyserEntete(); |
$this->traiterEnteteDebogage($infos); |
} |
private function analyserEntete() { |
$entetes = $this->reponse_entetes; |
$infos = array('date' => null, 'uri' => $this->url, 'debogages' => null); |
if (isset($entetes['wrapper_data'])) { |
$entetes = $entetes['wrapper_data']; |
} |
foreach ($entetes as $entete) { |
if (preg_match('/^X_REST_DEBOGAGE_MESSAGES: (.+)$/', $entete, $match)) { |
$infos['debogages'] = json_decode($match[1]); |
} |
if (preg_match('/^Date: .+ ([012][0-9]:[012345][0-9]:[012345][0-9]) .*$/', $entete, $match)) { |
$infos['date'] = $match[1]; |
} |
} |
return $infos; |
} |
private function traiterEnteteDebogage($entetes_analyses) { |
if (isset($entetes['debogages'])) { |
$date = $entetes['date']; |
$uri = $entetes['uri']; |
$debogages = $entetes['debogages']; |
foreach ($debogages as $debogage) { |
$e = "DEBOGAGE : $date - $uri :\n$debogage"; |
trigger_error($e, E_USER_NOTICE); |
} |
} |
} |
private function reinitialiser() { |
$this->nettoyerParametres(); |
} |
} |
/branches/v1.7-oxygene/widget/index.php |
---|
New file |
0,0 → 1,4 |
<?php |
require 'Widget.php'; |
$widget = new Widget(); |
$widget->executer(); |
/branches/v1.7-oxygene/widget/widget.ini.defaut.php |
---|
New file |
0,0 → 1,43 |
;<?/* |
[parametres] |
;Memoire maxi pour les services : 128Mo = 134217728 ; 256Mo = 268435456 ; 512Mo = 536870912 ; 1Go = 1073741824 |
limiteMemoire = "512M" |
; Niveau d'erreur PHP |
erreurNiveau = 30719 ; E_ALL = 30719 |
; Séparateur d'url en entrée |
argSeparatorInput = "&" |
; Indication de la locale (setLocale(LC_ALL, ?)) pour les classes appelées par Widget.php |
locale = "fr_FR.UTF-8" |
; Indication du fuseau horraire par défaut date_default_timezone_set(?)pour les classes appelées par Widget.php |
fuseauHoraire = "Europe/Paris" |
; Mode (serveur) : "prod", "test" ou "local" |
modeServeur = "prod" |
[chemins] |
; Chemins à utiliser dans la méthode autoload des widgets |
autoload = "bibliotheque/" |
; Dossier contenant les widgets |
widgetsDossier = "modules/" |
; Dossier contenant le widget demandé construit dynamiquement dans le fichier Widget.php |
widgetCourantDossier = "" |
; Dossier contenant les fichiers des bibliothèques tierces |
bibliothequeDossier = "bibliotheque/" |
; Base de l'url servant à appeler les widgets |
baseURL = "/widget:del:" |
; URL de base absolue des Widgets du CEL construit dynamiquement dans le fichier WidgetCommun.php |
baseURLAbsoluDyn = "" |
; URL des services web du CEL sous forme de template à utiliser avec sprintf |
baseURLServicesDelTpl = "http://api.tela-botanica.org/service:del:0.1/%s" |
; URL des services web du CEL sous forme de template à utiliser avec sprintf |
baseURLServicesAnnuaireTpl = "http://www.tela-botanica.org/service:annuaire:%s" |
; Squelette d'Url permettant d'afficher une image du CEL (remplace %s par l'id de l'image sans underscore) |
celImgUrlTpl = "http://api.tela-botanica.org/img:%s.jpg" |
; Squelette d'URL pour les services web d'eFlore. |
baseURLServicesEfloreTpl = "http://www.tela-botanica.org/service:eflore:{projetCode}/{apiVersion}/{serviceNom}" |
; URL de base du dépôt de ressources |
baseURLRessources = "http://resources.tela-botanica.org/%s" |
[authentification] |
serviceUrlTpl = "http://www.tela-botanica.org/service:annuaire:TestLoginMdp/%s/%s" |
administrateurs = aurelien@tela-botanica.org,david.delon@clapas.net,jpm@tela-botanica.org,marie@tela-botanica.org |
;*/?> |
/branches/v1.7-oxygene/widget/. |
---|
New file |
Property changes: |
Added: svn:ignore |
+widget.ini.php |