//
// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License. //
// To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/1.0/ //
// or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. //
// Francais (brouillon): http://creativecommons.org/projects/international/fr/translated-license //
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Rendu des pages
// v0.2.40
class rendu
{
var $err = array(
"stop" => "oui",
"log" => "oui",
"debug" => "oui");
var $chemin = "../datas/";
var $types_boucles = array("ecrits","mois","forums","forums_mois");
// Gestion des erreurs
function _err($err,$debug="") {
// Si le debug est activé
if($this->err[debug] == "oui" && !empty($debug)) $err.= "\n// DEBUG //\n".$debug;
// Si on log les erreurs
if($this->err[log] == "oui") $this->erreurs[] = $err;
// Si on s'arrête sur les erreurs
if($this->err[stop] == "oui") {
echo "
".htmlentities(stripslashes($err))."
";
exit;
}
$this->erreur = $err;
return FALSE;
}
// Traite les balises genre "#TITRE"
// Options possibles: [Texte optionnel(#TITRE)texte optionnel]
// Ou: (#TITRE|fonction_php)
// Ou encore: (#TITRE|fonction1{argument1,argument2...}|fonction2...)
function balise($tag,$valeur,$entree)
{
$sortie = $entree;
preg_match_all("/\[([^\[\n]*)\(".$tag."(\*)?((\|[^\]]+)+)\)([^\]\n]*)\]/Ui",$sortie,$out,PREG_SET_ORDER);
// Pour chaque balise récupérée dans le texte
for($i=0; $i < count($out); $i++)
{
if(empty($valeur)) {
$sortie = str_replace($out[$i][0],"",$sortie);
break;
}
// On récupère le nom des fonctions
$fonctions = $out[$i][4];
$fonctions = substr($fonctions,1);
$fonctions = explode("|",$fonctions);
$clef = $out[$i][0];
if(empty($out[$i][2])) {
$valeur_boucle = htmlentities(stripslashes($valeur));
}
else $valeur_boucle = $valeur;
// On traite la balise avec chaque fonction
for($j = 0; $j < count($fonctions); $j++) {
// On regarde si la fonction a des paramètres en entrée
$params = array();
if($pos = strpos($fonctions[$j],"{")) {
$params = substr($fonctions[$j],$pos+1,-1);
$fonctions[$j] = substr($fonctions[$j],0,$pos);
$params = explode(",",$params);
}
// On ajoute la valeur de la balise au début du tableau des paramètres
array_unshift($params,$valeur_boucle);
if(!empty($valeur_boucle)) {
$valeur3 = call_user_func_array($fonctions[$j],$params);
$sortie = str_replace($clef,$valeur3,$sortie);
$clef = $valeur3;
$valeur_boucle = $valeur3;
}
// Si éléments optionnels avant/après on le remet
$sortie = str_replace($clef,$out[$i][1].$valeur3.$out[$i][5],$sortie);
unset($params);
}
}
preg_match_all("/\(".$tag."(\*)?((\|[^\]]+)+)\)/Ui",$sortie,$out2,PREG_SET_ORDER);
for($i=0; $i < count($out2); $i++)
{
// On récupère le nom des fonctions
$fonctions = $out2[$i][2];
$fonctions = substr($fonctions,1);
$fonctions = explode("|",$fonctions);
$clef = $out2[$i][0];
if(empty($out[$i][1])) {
$valeur_boucle = htmlentities(stripslashes($valeur));
}
else $valeur_boucle = $valeur;
// On traite la balise avec chaque fonction
for($j = 0; $j < count($fonctions); $j++) {
// On regarde si la fonction a des paramètres en entrée
$params = array();
if($pos = strpos($fonctions[$j],"{")) {
$params = substr($fonctions[$j],$pos+1,-1);
$fonctions[$j] = substr($fonctions[$j],0,$pos);
$params = explode(",",$params);
}
// On ajoute la valeur de la balise au début du tableau des paramètres
array_unshift($params,$valeur_boucle);
if(!empty($valeur_boucle)) {
$valeur2 = call_user_func_array($fonctions[$j],$params);
}
$sortie = str_replace($clef,$valeur2,$sortie);
$clef = $valeur2;
$valeur_boucle = $valeur2;
unset($params);
}
}
preg_match_all("/\[([^\[\n]*)\(".$tag."(\*)?\)([^\]\n]*)\]/Ui",$sortie,$outt,PREG_SET_ORDER);
for($i = 0; $i < count($outt); $i++) {
if(empty($valeur)) $sortie = str_replace($outt[$i][0],"",$sortie);
else $sortie = str_replace($outt[$i][0],$outt[$i][1].$valeur.$outt[$i][3],$sortie);
}
preg_match_all("/\(".$tag."(\*)?\)/Ui",$sortie,$out4,PREG_SET_ORDER);
for($i = 0; $i < count($out4); $i++) {
if(empty($valeur)) $sortie = str_replace($out4[$i][0],"",$sortie);
else $sortie = str_replace($out4[$i][0],$valeur,$sortie);
}
// Sinon
$sortie = str_replace($tag,htmlentities(stripslashes($valeur)),$sortie);
return $sortie;
}
// Retourne le contenu d'une boucle dans un tableau
function decoupe_boucle($texte,$b)
{
$pos_debut = strpos($texte,$b[0]);
if(($d = strpos($texte,"")))
{
$d2 = $d + strlen("");
$boucle['pre'] = substr($texte,$d2,($pos_debut - $d2));
}
$pos_fin = strpos($texte,"") + strlen("");
if($f = strpos($texte,"")) {
$boucle['post'] = substr($texte,$pos_fin,($f - $pos_fin));
$pos_fin = $f + strlen("");
}
if($a = strpos($texte,"/B".$b[1].">")) {
$boucle['alt'] = substr($texte,$pos_fin,$a - $pos_fin);
$pos_fin = $a + strlen("/B".$b[1].">");
}
if($d) $deb = $d;
else $deb = $pos_debut;
$boucle['total'] = substr($texte,$deb,($pos_fin - $deb));
return $boucle;
}
function traiter_boucles($journal)
{
$boucles_mortes = array();
// On repère toutes les boucles de la page
preg_match_all("§§U",$this->contenu,$out,PREG_SET_ORDER);
if(count($out) < 0) return FALSE;
// On fait le boulot pour chaque boucle
for($i=0; $i < count($out); $i++)
{
$orderCount = 0;
$nom = $out[$i][1];
// On vérifie qu'il y a une balise fermante contenu,"")) return $this->_err("La boucle n'a pas de balise fermante. Vérifiez le squelette.");
// Si le nom de la boucle commence par un tiret bas, on le vire
if(substr($nom,0,1) == "_") $nom = substr($nom,1);
// On récupère le type de boucle
$type = strtolower($out[$i][2]);
if(!in_array($type,$this->types_boucles)) return $this->_err("La boucle {$nom} a un type {$type} inconnu. Vérifiez le squelette.");
// On récupère tous les critères de la boucle dans un tableau
$options = strtolower($out[$i][3]);
$options = substr(trim($options),1,-1);
$options = explode("}{",$options);
$criteres = array();
// On détermine les options/critères de la boucle
for($j=0; $j < count($options); $j++)
{
$o = array(); // remet à 0 $o pour éviter les bugs
if($options[$j] == "parent" && $type == "forums")
$req[where][] = "(parent='{$GLOBALS[id]}')";
// Ordre inverse
elseif($options[$j] == "inverse")
$req[orderby][$orderCount].= " DESC";
// Si c'est un séparateur de boucle {", "} par exemple
elseif(substr($options[$j],0,1) == '"')
$separ = substr($options[$j],1,-1);
// Si c'est un critère de limite des résultats affichés
elseif(ereg("(debut_([a-z0-9_-]+)|([0-9]+)),([0-9]+)?",$options[$j],$o))
{
if(substr($o[1],0,6) == "debut_") $debut = $GLOBALS[$o[1]];
else $debut = $o[3];
if(empty($debut)) $debut = 0;
if(trim($o[4]) == "") $o[4] = "-1";
$req['limit'] = $debut.",".$o[4];
}
// Si c'est un critère de recherche
elseif($options[$j] == "recherche")
{
if(in_array("sujet",$tables[$type])) $req[where][] = "(sujet LIKE \"%".addslashes($GLOBALS[recherche])."%\")";
if(in_array("titre",$tables[$type])) $req[where][] = "(titre LIKE \"%".addslashes($GLOBALS[recherche])."%\")";
if(in_array("chapo",$tables[$type])) $req[where][] = "(chapo LIKE \"%".addslashes($GLOBALS[recherche])."%\")";
if(in_array("texte",$tables[$type])) $req[where][] = "(texte LIKE \"%".addslashes($GLOBALS[recherche])."%\")";
}
// Critère de comparaison REGEXP
elseif(ereg("(==|!==)",$options[$j],$o))
{
$pos = strpos($options[$j],$o[1]);
$c = substr($options[$j],0,$pos);
$expr = substr($options[$j],$pos+strlen($o[1]));
if($o[1] == "==") $op = "REGEXP";
else $op = "NOT REGEXP";
$req[where][] = "(".trim($c)." ".$op." \"".trim($expr)."\")";
}
// Si c'est un critère de comparaison LIKE
elseif(ereg("(=~|!=~)",$options[$j],$o))
{
$pos = strpos($options[$j],$o[1]);
$c = substr($options[$j],0,$pos);
$expr = substr($options[$j],$pos+strlen($o[1]));
if($o[1] == "=~") $op = "LIKE";
else $op = "NOT LIKE";
$req[where][] = "(".trim($c)." ".$op." \"".trim($expr)."\")";
}
// Si c'est un critère de comparaison classique
elseif(ereg("(<|>|=|>=|<=|!=)",$options[$j],$o))
{
$pos = strpos($options[$j],$o[1]);
$c = substr($options[$j],$pos+strlen($o[1]));
if(substr(trim($c),0,1) == "$") { $c = substr(trim($c),1); $c = $GLOBALS[$c]; }
$c = "'".trim($c)."'";
$req[where][] = "(".substr($options[$j],0,$pos+strlen($o[1])).$c.")";
}
// Trier par...
elseif(substr($options[$j],0,3) == "par")
{
$orderCount++;
$req[orderby][$orderCount] = substr($options[$j],4);
if($req[orderby][$orderCount] == "hasard") $req[orderby][$j] = "RAND()";
}
elseif(($options[$j] == "id") || ($options[$j] == "mois"))
$req[where][] = "({$options[$j]}='{$GLOBALS[$options[$j]]}')";
elseif($options[$j] == "tout")
$tout = TRUE;
// Sinon ça veut dire que cette option n'existe pas
else {
$this->_err("Le critère {{$options[$j]}} de la boucle '{$nom}' n'est pas compris.");
return FALSE;
}
}
$requete = "SELECT * FROM ".$type;
$requete.= " WHERE journal='{$journal}'";
if($type == "ecrits") $requete.= " AND statut != 'prive' AND valide='oui'";
if(!$tout) {
if(count($req['where']) > 0)
{
$requete.= " AND ";
$requete.= implode(" AND ",$req['where']);
}
}
if($req['orderby']) $requete.= " ORDER BY ".implode(", ",$req[orderby]);
if($req['limit']) $requete.= " LIMIT ".$req[limit];
if($type == "mois")
{
if($type == "mois") $requete = "SELECT mois FROM ecrits WHERE journal='{$journal}' AND statut!='prive' AND valide='oui' GROUP BY mois ORDER BY mois";
#elseif($type == "forums_mois") $requete = "SELECT mois FROM forums WHERE journal='{$journal}' AND parent='0' GROUP BY mois ORDER BY mois";
if($req['orderby'][0] == " DESC") $requete.= " DESC";
}
$res = mysql_query($requete) or die($this->_err("Erreur mySQL.",$requete."\n --> ".mysql_error()));
$nb_items = mysql_num_rows($res);
// On récupère le contenu de la boucle
$bcl = $this->decoupe_boucle($this->contenu,$out[$i]);
// Si pas d'enregistrement retourné, on vire la boucle
if($nb_items < 1) {
// On référence les boucles mortes
preg_match_all("§§U",substr($bcl[total],7),$k,PREG_SET_ORDER);
for($l=0; $l < count($k); $l++) {
$boucles_mortes[] = $k[$l][1];
}
$this->contenu = str_replace($bcl['total'],$bcl['alt'],$this->contenu);
}
// Sinon on traite le contenu de la boucle
else {
// On récupère le contenu lui-même de la boucle (sans les balises BOUCLE)
$d = strpos($this->contenu,$out[$i][0]) + strlen($out[$i][0]);
$f = strpos($this->contenu,"contenu,$d,$f);
// Si ya des sous-boucles, on les vire le temps d'exécution pour éviter de confondre les tags
if(strpos($boucle,"]+>%Us",$boucle,$temp,PREG_SET_ORDER);
for($s=0;$s < count($temp); $s++) {
$boucle = str_replace($temp[$s][0],"",$boucle);
}
}
// On réitère le contenu de la boucle pour chaque enregistrement
while($rec = mysql_fetch_assoc($res))
{
// Si c'est un ID, on le met dans les doublons (à ne pas réafficher)
#if(isset($rec['nom']) && empty($rec['nom'])) $rec['nom'] = "Anonyme";
if($rec['id']) $doublons[$type][] = $rec[id];
if($type == "mois" || $type == "forums_mois") {
$rec["date"] = $rec['mois'];
$rec['mois'] = mktime(1,1,1,substr($rec["date"],4,2),1,substr($rec["date"],0,4));
}
elseif($type == "ecrits")
{
$txtRes = mysql_query('SELECT t.texte,h.texte AS texte_html FROM ecrits_textes AS t, ecrits_html AS h
WHERE t.id="'.$rec['id'].'" AND t.id=h.id');
$txtRec = mysql_fetch_row($txtRes);
$rec['texte_html'] = stripslashes($txtRec[1]);
$rec['texte'] = stripslashes($txtRec[0]);
}
elseif($type == "forums")
{
$txtRes = mysql_query('SELECT texte FROM forums_textes WHERE id="'.$rec['id'].'"');
$txtRec = mysql_fetch_row($txtRes);
$rec['texte_html'] = $GLOBALS['forum']->parseText($txtRec[0]);
$rec['texte'] = stripslashes($txtRec[0]);
}
// Si ya une séparation entre chaque itération de la boucle
if($b && $separ) $b = $separ.$boucle;
else $b = $boucle;
// Pour chaque champ de la table on remplace les balises correspondantes
foreach($rec as $val=>$v) {
// Si c'est un nombre on le met en globales avec id_ en préfixe (pour critères {id_texte} et cie.)
if(is_numeric($rec[$val])) {
if($val != "id") $v2 = "id_".$val;
else $v2 = "id_".substr($type,0,-1);
if($v2 == "id_parent") $var[$v2] = $rec[id];
else $var[$v2] = $rec[$val];
}
// Remplacement de la balise
$b = $this->balise("#".strtoupper($val),stripslashes($rec[$val]),$b);
}
$sortie.= $b;
// Balise #INTRO (conforme SPIP & PHPInk)
if(!empty($rec['texte_html'])) {
$intro = strip_tags($rec['texte_html']);
if(strlen($intro) > 600) {
$intro = substr($intro,0,600);
$pos = strrpos($intro," ");
if($pos > 1) $intro = substr($intro,0,$pos);
}
}
$sortie = $this->balise("#INTRO",$intro,$sortie);
if($type == "ecrits") {
#if(empty($rec['name'])) $url = $rec['id'];
#else $url = $rec['name'];
#$url = date("/Y/m/d/",$rec['date']).$url;
$url = "/".$rec['uri'];
}
elseif($type == "forums") {
$url = "/forum/".$rec['uri'];
#$url = "/forum".date("/Y/m/d/",$rec[date]).$url;
}
elseif($type == "mois") $url = "/".substr($rec["date"],0,4)."/".substr($rec["date"],4,2)."/";
#elseif($type == "forums_mois") $url = "/forum/".substr($rec["date"],0,4)."/".substr($rec["date"],4,2)."/";
$sortie = $this->balise("#URL",$url,$sortie);
if(strchr($sortie,"#_COULEUR")) $sortie = $this->balise("#_COULEUR","#eee",$sortie);
}
// On remet les sous-boucles aux bons endroits
if($temp) {
for($s=0; $s < count($temp); $s++) {
$sortie = str_replace("",$temp[$s][0],$sortie);
}
}
$bcl['post'] = $this->balise("#TOTAL_BOUCLE",$nb_items,$bcl['post']);
$this->contenu = str_replace($bcl['total'],$bcl['pre'].$sortie.$bcl['post'],$this->contenu);
$this->var = $var;
$var2[$i] = $var;
}
if(count($temp) > 0) {
if(empty($niveau[$i])) $niveau[$i] = 0;
for($c = 1; $c <= count($temp); $c++) {
$niveau[$i+$c] = $niveau[$i] + 1;
}
$pere[$niveau[$i]] = $i;
}
else {
$var = $var2[$niveau[$i]-1];
}
// On fait le ménage
unset($temp,$ordre,$unique,$tout,$criteres,$inverse,$limit,$b,$separ,$boucle,$sortie,$intro,$req);
}
return $this->contenu;
}
// On récupère le chemin du CSS
function get_css($visuel,$journal)
{
if($visuel == "custom")
$css = $this->chemin."documents/".$journal."/default.css";
else
$css = $this->chemin."templates/".$visuel."/default.css";
return $css;
}
// On récupère le template correspondant au membre
function get_template($visuel,$journal,$template)
{
if($visuel == "custom")
{
$path = $this->chemin."/documents/".$journal."/skel_".$template.".html";
if(!file_exists($path)) $path = $this->chemin."templates/default/".$template.".html";
}
else
{
$path = $this->chemin."/templates/".$visuel."/".$template.".html";
if(!file_exists($path)) $path = $this->chemin."templates/default/".$template.".html";
}
// On inclut le CSS
$css = $this->get_css($visuel,$journal);
$f = @file($path);
if(!$f) return $this->_err("Impossible d'accéder au template.");
$f = implode("",$f);
$f = str_replace("#CSS",'',$f);
return $f;
}
// On parse les tags généraux affichés sur toutes les pages
function parse_general($journal,$template)
{
// On parse la boucle des mois dispos
//$template = $this->boucle_mois($template,$journal[mois]);
// Relatif aux forums et autres
if($journal['forum'] == "non") $journal['forum'] = "";
else $journal['forum'] = "/forum/";
if($journal['suivimail'] == "oui") $journal['suivimail'] = "/membre/abon?new=".$journal[id];
else $journal['suivimail'] = "";
// Remplissage des tags
$tags = array(
"#TITRE_JOURNAL"=> $journal['titre'],
"#URL_JOURNAL" => $journal['url'],
"#TEXTE_JOURNAL"=> $journal['texte'],
"#ID_JOURNAL" => $journal['id'],
"#STATUT_JOURNAL"=> $journal['statut'],
"#FORUM" => $journal['forum'],
"#SUIVIMAIL" => $journal['suivimail'],
"#IDENTIFIANT" => $journal['id'],
"#SABONNER" => $journal['suivimail'],
"#FORMULAIRE" => "/addmessage.php?login=".$journal['id']);
foreach($tags as $key=>$value) {
$template = $this->balise($key,$value,$template);
}
$this->contenu = $template;
$GLOBALS['mois'] = $journal['select_mois'];
$this->traiter_boucles($journal['id']);
return $this->contenu;
}
// rendu d'un écrit
function skel_ecrit($journal,$ecrit)
{
// On récupère le template
$template = $this->get_template($journal['visuel'],$journal['id'],"ecrit");
// Parsage des tags généraux
$template = $this->parse_general($journal,$template);
// On parse les tags spécifiques à la page
$tags = array(
"#ID" => $ecrit['id'],
"#TITRE" => $ecrit['titre'],
"#TEXTE_HTML" => $ecrit['texte_html'],
"#TEXTE" => $ecrit['texte'],
"#DATE" => $ecrit['date'],
"#STATUT" => $ecrit['statut'],
"#VALIDE" => $ecrit['valide'],
"#SYNTAXE" => $ecrit['syntaxe'],
"#URI" => $ecrit['uri']);
foreach($tags as $key=>$value) {
$template = $this->balise($key,$value,$template);
}
return $template;
}
// Rendu de l'index d'un mois
function skel_mois($journal)
{
$template = $this->get_template($journal['visuel'],$journal['id'],"mois");
// Parsage des tags généraux
$template = $this->parse_general($journal,$template);
$m = $journal['select_mois'];
$template = $this->balise("#MOIS",mktime(1,1,1,substr($m,4,2),1,substr($m,0,4)),$template);
return $template;
}
// Rendu de l'index d'un mois
function skel_accueil($journal)
{
$template = $this->get_template($journal['visuel'],$journal['id'],"accueil");
// Parsage des tags généraux
$template = $this->parse_general($journal,$template);
$m = $journal['select_mois'];
$template = $this->balise("#MOIS",mktime(1,1,1,substr($m,4,2),1,substr($m,0,4)),$template);
return $template;
}
// Rendu de l'index dun mois de forum
function skel_forum_page($journal,$liste)
{
$template = $this->get_template($journal['visuel'],$journal['id'],"forum_page");
$template = $this->parse_general($journal,$template);
return $template;
}
// rendu d'un message de forum
function skel_forum_message($journal,$message)
{
// On récupère le template
$template = $this->get_template($journal['visuel'],$journal['id'],"forum_message");
// Parsage des tags généraux
$template = $this->parse_general($journal,$template);
// On parse les tags spécifiques à la page
$tags = array(
"#ID" => $message['id'],
"#TITRE" => $message['titre'],
"#TEXTE_HTML" => $message['texte_html'],
"#TEXTE" => $message['texte'],
"#DATE" => $message['date'],
"#STATUT" => $message['statut'],
"#URI" => $message['uri'],
"#NOM" => $message['nom'],
"#EMAIL" => $message['email'],
"#AUTEUR" => $message['auteur'],
"#URL_FORUM" => "/forum/");
foreach($tags as $key=>$value) {
$template = $this->balise($key,$value,$template);
}
return $template;
}
}
?>