1075 visites

Script générique des diaporamas AJAX

samedi 18 octobre 2014

Version imprimable de cet article Version imprimable

Ce script est le même pour le diaporama de la page de garde et pour le diaporama de la galerie.

Il lit des paramètres dans la page (numéro de rubrique à parcourir, nombre de niveaux de sous-rubriques à chercher, langue) et envoie la requête au serveur, puis insère dans la page l’image, le titre et le texte de chaque élément du diaporama en l’adaptant à la taille de la fenêtre, avant de demander l’élément suivant.

En effet, les éléments de ce diaporama sont des articles :

  • le logo de l’article est une image particulière, que l’on peut aisément différencier du texte, afin de lui accorder un traitement différent.
  • un article existe dans une certaine langue, ce qui permet d’afficher un diaporama différent selon la langue souhaitée
  • un article avec texte, titre et logo est facile à ajouter, modifier ou enlever dans l’espace privé de SPIP.

Lancement des fonctions JavaScript

Comme on peut le voir dans l’aperçu Firebug de la structure de la page de garde, il y a dans chaque page, pour l’évènement onLoad (= "au chargement") de l’élément HTML body, appel à une fonction unique et générique "AuChargement".

function AuChargement(){
        pisteIE();
        cachejs();
        setTimeout("charger_diapo()",1000); // 1 seconde
        traitercadres();
        traiterimages();
}

Cette fonction unique en invoque d’autres, qui, selon les éléments présents ou non dans la page, feront quelque chose :

  • pisteIE va, comme son nom l’indique, rediriger les utilisateurs du navigateur Internet Explorer vers une page d’avertissement, indiquant les déficiences de Microsoft Internet Explorer quand aux éléments pourtant normalisés W3C de la page.
    • Un lien "continuer quand même" permet aux utilisateurs d’Internet Explorer de poursuivre la navigation, ils ont été prévenus.
    • Un système de cookie enregistre le fait que l’utilisateur est prévenu, cela évite de faire la redirection à chaque ouverture de page.
  • cachejs sert, comme son nom l’indique, à cacher le message selon lequel JavaScript est désactivé sur le navigateur.
  • setTimeout("charger_diapo()",1000); lance la fonction charger_diapo() au bout d’une seconde.
    • C’est cette fonction qui ira chercher les paramètres du diaporama dans la page et enverra la requête au serveur pour le premier élément.
  • traitercadres et traiterimages vont redimensionner les cadres et images qui en ont besoin.

Lancement du diaporama

function charger_diapo(){
        if (this.document.getElementById('diapo')!=null){

Cette fonction ne s’exécutera que si un élément "diapo" est présent dans la page

                if (this.document.getElementById('nrubrique')!=null){
                        nrubrique=this.document.getElementById('nrubrique').value;
                }else{
                        nrubrique=0;
                }

Pour chaque paramètre du diaporama, on vérifie sa présence, et en cas d’absence on utilise une valeur par défaut

Autres paramètres

                if (this.document.getElementById('mindepth')!=null){
                        mindepth=this.document.getElementById('mindepth').value;
                }else{
                        mindepth=0;
                }
                if (this.document.getElementById('maxdepth')!=null){
                        maxdepth=this.document.getElementById('maxdepth').value;                       
                }else{
                        maxdepth=1;
                }
                if (this.document.getElementById('lang')!=null){
                        lang=this.document.getElementById('lang').value;                       
                }else{
                        lang="fr";
                }

Puis on initialise quelques valeurs avant d’appeler la fonction qui créera et enverra la requête.

                var url_image=null;
                var texte_diapo=null;
                var titre_diapo=null;
                requete_requete_image_diapo('charger_diapo.php?id=0&rub='+nrubrique+'&min='+mindepth+'&max='+maxdepth+'&lang='+lang);
        }
}

Création de la requête XMLHTTP

Le script javaScript défini quelque variables globales, que plusieurs fonctions utiliseront.

var diapo = 0;
var prochain=0;
var nrubrique=0;
var mindepth=0;
var maxdepth=1;
var delai=5000;

Avant de pouvoir créer la requête XMLHTTP, il faut un objet de type xmlhttprequest pour y mettre les paramètres, l’envoyer au serveur et recevoir sa réponse.
En fonction du navigateur, on utilisera plusieurs méthodes.

Création de l’objet xmlhttprequest

function get_requete_image_diapo(){
        var requete_image_diapo = null;
        if (window.XMLHttpRequest){ // Firefox
                requete_image_diapo=new XMLHttpRequest();
        }else if (window.ActiveXObject){ // IE
                try{
                        requete_image_diapo=new ActiveXObject("Msxml12.XMLHTTP");
                }catch(e){
                        try{
                                requete_image_diapo=new ActiveXObject("Microsoft.XMLHTTP");
                        }catch(e1){
                                requete_image_diapo=null;
                        }
                }
        }else{ // non supporté
                alert("Votre navigateur ne supporte pas les XMLHTTPRequest.");
                /* + redirection vers page navigs.html */
        }
        return requete_image_diapo;
}

La fonction précédente, qui créé l’objet xmlhttprequest, est appelée par la fonction de création et d’envoi de la requête que voici :

function requete_requete_image_diapo(url){

        requete_image_diapo=get_requete_image_diapo();
        if (!requete_image_diapo){
                alert("Votre navigateur ne peut créer de requête AJAX.");
                /* + redirectiuon vers page navigs.html */
                return;
        }

On récupère l’objet xmlhttprequest, puis, si celui-ci n’a pu être créé et que par conséquent la variable requete_image_diapo n’existe pas - le ! signifiant la négation - on affiche un message et l’on quitte la fonction.
Sinon, on poursuit

        //alert("envoi de la requete");
        requete_image_diapo.onreadystatechange=function(){traitementReponse_requete_image_diapo(requete_image_diapo)}
        requete_image_diapo.open("GET",url,true);
        requete_image_diapo.send(null);
}

requete_image_diapo.onreadystatechange=<code> définit la fonction <code>function(){ ... } de traitement de la réponse, quand la requête aura "changé d’état".
Puis on ouvre l’url du script du serveur auquel il faut envoyer la requête, et qui la traitera pour envoyer la réponse selon les paramètres indiqués, et on y envoie la requête.

Modification de la page affichée

function traitementReponse_requete_image_diapo(requete_image_diapo){
        var contenu;
        var erreur=0;
        if (requete_image_diapo.readyState==4){

Si la requête est dans l’état "4", c’est à dire que l’on a reçu la réponse du serveur,

                //alert("reception de la reponse : traitement");
                contenu=requete_image_diapo.responseXML;

On récupère le document XML constituant la réponse du serveur.

                if (contenu.getElementsByTagName("image")[0].firstChild.nodeValue!=null){
                        url_image=contenu.getElementsByTagName("image")[0].firstChild.nodeValue;
                }else{
                        erreur=1;
                }

On vérifie la présence de différents éléments de réponse, en préparant des valeurs par défaut si besoin.

  • contenu est le document XML de réponse. Celui-ci est organisé selon une arborescence de balises pour les divers éléments et leurs valeurs.
  • on utilise la fonction getElementsByTagName pour adresser ces balises par leur nom
    • cette fonction renvoie un tableau de balises correspondantes, dont on s’intéresse au premier élément, à la case 0, qui est la première case d’un tableau javaScript.
  • Une fois récupéré la balise souhaitée, on récupère la valeur du nœud (nodeValue).

Autres éléments

                if (contenu.getElementsByTagName("url_article")[0].firstChild.nodeValue!=null){
                        url_article=contenu.getElementsByTagName("url_article")[0].firstChild.nodeValue;
                }else{
                        erreur=1;
                }
                if (contenu.getElementsByTagName("titre")[0].firstChild!=null){
                        if (contenu.getElementsByTagName("titre")[0].firstChild.nodeValue!=null){
                                titre_diapo=contenu.getElementsByTagName("titre")[0].firstChild.nodeValue;
                        }else{
                                erreur=1;
                        }
                }else{
                        titre_diapo="";
                }
                //alert("titre="+contenu.getElementsByTagName("titre")[0].textContent); // y'a aussi data, wholeText...nodeValue...
                if (contenu.getElementsByTagName("texte")[0].firstChild!=null){
                        if (contenu.getElementsByTagName("texte")[0].firstChild.nodeValue!=null){
                                texte_diapo=contenu.getElementsByTagName("texte")[0].firstChild.nodeValue;
                                if ((texte_diapo==null)||(texte_diapo=="")){
                                        texte_diapo="Sans titre";
                                }
                        }else{
                                texte_diapo="";
                        }
                }else{
                        texte_diapo="";
                }

De même, on récupère plusieurs paramètres toujours présents, dont la prochaine image preload que l’on va commencer à charger comme arrière plan à taille nulle pour accélérer son chargement lorsque ce sera son tour.

                prochain=contenu.getElementsByTagName("prochain")[0].firstChild.nodeValue;
                // delai=contenu.getElementsByTagName("delai")[0].firstChild.nodeValue;
                preload=contenu.getElementsByTagName("preload")[0].firstChild.nodeValue;
                //alert("texte="+contenu.getElementsByTagName("texte_diapo")[0].firstChild.nodeValue);

Pour comprendre à quoi correspondent ces éléments, voir l’onglet détaillant le script PHP.

Et si tout va bien (variable erreur toujours à zéro)

        if (erreur==0){       

On essaie de récupérer le bloc "image" du diaporama afin de pouvoir y intégrer l’image indiquée dans le document XML.
Dans la même structure conditionnelle, l’on s’assure qu’il y a bien une image à y intégrer (l’url de l’image fournie dans la réponse XML est non nulle).

                if ((this.document.getElementById('diapo_image')!=null)&&(url_image!="")){
                        //alert ("on a le div image");

Si le bloc image existe, on le référence afin de pouvoir le modifier, en utilisant la fonction getElementById qui renvoie un élément unique, puis on y intègre un lien vers l’article sous la forme d’une image qui est son logo avec la valeur innerHTML de l’élément, qui correspond au code HTML que l’élément contient.

                        var div_image=this.document.getElementById('diapo_image'); // le div
                        div_image.innerHTML="<a href=\""+url_article+"\"><img src=\""+url_image+"\" style=\"margin-left:0px;margin-top:0px;\"></a>";

L’image du diaporama étant dans son bloc, il est peut être utile à présent de la redimensionner afin de l’adapter aux dimensions dudit bloc.

On récupère donc les dimensions du bloc, par offsetHeight et offsetWidth, puis les dimensions réelles de l’image, par les valeurs "hauteur" et "largeur" fournies dans la réponse (voir script PHP).

                        var h_div=this.document.getElementById('diapo_image').offsetHeight;
                        var l_div=this.document.getElementById('diapo_image').offsetWidth;
               
                        var h_img=parseFloat(contenu.getElementsByTagName("hauteur")[0].firstChild.nodeValue);
                        var l_img=parseFloat(contenu.getElementsByTagName("largeur")[0].firstChild.nodeValue);
                        //alert("traitement d'une image de "+h_img+" par "+l_img);

Selon la différence de dimension entre le bloc et l’image, il faudra la réduire prioritairement en largeur, en hauteur, ou les deux, et si l’image n’est pas trop grande, on cherchera à la centrer.

Le reste du script de traitement devrait être aisément compréhensible, d’autant que les commentaires permettent de suivre les conditions vérifiées et le traitement effectué.
Le principe reste toujours le même :

  • si une dimension de l’image est plus grande que celle du bloc, alors
    • calculer la proportion entre les deux afin de pouvoir réduire l’image
  • une fois la bonne proportion de réduction trouvée, calculer les marges entre les dimensions du bloc et celles de l’image réduite, pour centrer l’image.

                        if (l_img>l_div){
                                var reduction=l_img/l_div; // la proportion de réduction, qui sera la meme en hauteur et largeur
                                // si h_img/reduction>h_div alors
                                if ((h_img/reduction)>h_div){
                                        // image plus large et en réduite, plus haute que le div
                                        // image plus HAUTE que large
                                        // réduction_h = h_img/h_div
                                        var reduction_h=h_img/h_div;
                                        // appliquer reduction_h en hauteur et largeur
                                        var nh=h_img/reduction_h;
                                        var nl=l_img/reduction_h;
                                        // pour être au milieu

Une fois l’image réduite, on calcule la marge, puis on applique réduction et marge de centrage.
De même que pour le bloc diapo, on utilise la fonction getElementById pour référencer le bloc, puis, comme pour la réponse XML, getElementsByTagName pour récupérer le tableau des images (balise <img ...> contenues, la première (et seule) étant à la case 0.
Puis l’on définit les attributs HTML de cette balise <img ...> pour retailler l’image, et lui ajouter un style personnalisé contenant la marge de centrage, ainsi que la prochaine image preload comme arrière-plan de taille nulle pour accélérer son chargement lorsque ce sera son tour.

                                        var margel=(l_div-nl)/2;
                                        // si la marge est > à x px, calculer la différence et réduire div image pour agrandir div texte
                                        image=this.document.getElementById('diapo_image').getElementsByTagName('img')[0];
                                        image.setAttribute("height",nh);
                                        image.setAttribute("width",nl);                               
                                        image.setAttribute("style","margin-left:"+margel+"px; background-image:url(\""+preload+"\"); background-size: 0px 0px;");

Autres cas

                                // sinon
                                }else{
                                        // image plus large mais pas plus haute que le div
                                        // image plus LARGE que haute
                                        // appliquer réduction en largeur et hauteur
                                        var nh=h_img/reduction;
                                        var nl=l_img/reduction;
                                        // pour être au milieu, il faut que margeh=()h_div-nh/2
                                        var margeh=(h_div-nh)/2;
                                        image=this.document.getElementById('diapo_image').getElementsByTagName('img')[0];
                                        image.setAttribute("height",nh);
                                        image.setAttribute("width",nl);
                                        image.setAttribute("style","margin-top:"+margeh+"px; background-image:url(\""+preload+"\"); background-size: 0px 0px;");
                                //finsi
                                }
                                // fins
                        }else{
                                // image pas plus large que le div
                                if (h_img>h_div){
                                        // div assez large mais pas assez haut
                                        // réduction_h = h_img/h_div
                                        var reduction_h=h_img/h_div;
                                        // appliquer reduction_h en hauteur et largeur
                                        var nh=h_img/reduction_h;
                                        var nl=l_img/reduction_h;
                                        // pour être au milieu, il faut que margel=()545-nl/2
                                        var margel=(l_div-nl)/2;
                                        image=this.document.getElementById('diapo_image').getElementsByTagName('img')[0];
                                        image.setAttribute("style","margin-left:"+margel+"px; background-image:url(\""+preload+"\"); background-size: 0px 0px;");
                                        image.setAttribute("height",nh);
                                        image.setAttribute("width",nl);
                                }else{
                                        // image pas trop grande
                                        // mais cadre peut-être trop grand
                                        var margeh=(h_div-h_img)/2;
                                        var margel=(l_div-l_img)/2;
                                        image=this.document.getElementById('diapo_image').getElementsByTagName('img')[0];
                                        image.setAttribute("style","margin-left:"+margel+"px;margin-top:"+margeh+"px; background-image:url(\""+preload+"\"); background-size: 0px 0px;");
                                }
                        }
                }else{
                        //alert("div image non trouvé");
                }

Puis on fait la même chose pour le texte et le titre

                if (this.document.getElementById('diapo_texte')!=null){
                        var div_texte=this.document.getElementById('diapo_texte'); // le div
                        //alert ("on a le div texte");
                        div_texte.innerHTML="<span class=\"titre_diapo\"><a href=\""+url_article+"\">"+titre_diapo+"</a></span><p><span class=\"texte_diapo\">"+texte_diapo+"</span></p>";
                }else{
                        //alert("div texte non trouvé");
                }
        }

...et on demande le prochain élément, si bien sûr cela a du sens.
Si le diaporama n’a aucun ou qu’un seul élément, il n’est pas utile d’envoyer d’autre requête, et le script du serveur indiquera que prochain vaut "-1", soit une valeur non valide.

la commande setTimeout( permet de définir un délai avant de demander le prochain élément.

                diapo=prochain;
                if (prochain!=-1){                       
                        //        requete_requete_image_diapo("charger_diapo.php?id="+diapo+"&delai="+delai);       
                        setTimeout("requete_requete_image_diapo('charger_diapo.php?id='+diapo+'&rub='+nrubrique+'&min='+mindepth+'&max='+maxdepth+'&lang='+lang)",delai);
                }
        }
}

script PHP

Le script PHP charger_diapo.php, situé à la racine du serveur web, et appelé comme URL par la fonction charger_diapo et après chaque traitement de réponse, va traiter la requête xmlhttp et envoyer une réponse au format XML.

<?php
session_start();

Dans la mesure où les scripts PHP de SPIP peuvent utiliser des variables de session pour stocker des paramètres, on se connecte à cette session afin de pouvoir récupérer la langue choisie.

On créé l’entête de la réponse avant qu’un autre script, de traitement des accents, ne s’en charge.
le script accents.php contient plusieurs fonctions, dont une utilisée pour transformer les caractères accentués contenus dans la base en leur équivalent en code HTML, permettant un affichage normal quel que soient les encodages de caractère du serveur et du navigateur.

header('content-Type:text/xml,charset=UTF-8');
require "accents.php";

On se connecte à la base de données.

mysql_connect('serveur','utilisateur','mot de passe','MYSQL');
mysql_select_db("nom de la base");

On travaillera sur les tables des rubriques et des articles de SPIP, qui ont généralement un nom commençant par "spip_".

$tablerubriques="spip_rubriques";
$tablearticles="spip_articles";

La requête xmlhttp envoyant ses paramètres dans l’url, par la méthode GET (voir article sur PHP), on récupère les paramètres par la variable globale $_GET, qui est un tableau associatif (les colonnes sont identifiées par nom et non par numéro).

if (isset($_GET["id"])){
        $idd=$_GET["id"];
}else{
        $idd=0; /* id du diapo en cours, à diviser par total de diapo et prendre le reste , ex si idd = 5 pour 3 photos existantes, alors charger photo 2 */
}

Autres paramètres

if (isset($_GET["delai"])){
        $delai=$_GET["delai"];
        //echo "delai de $delai secondes<br>";
}else{
        $delai=0;
}

if (isset($_GET["rub"])){
        $id_rubrique_diapo=$_GET["rub"];
}else{
        $id_rubrique_diapo=0;
}

if (isset($_GET["min"])){
        $min_depth=$_GET["min"];
}else{
        $min_depth=0;
}

if (isset($_GET["max"])){
        $max_depth=$_GET["max"];
}else{
        $max_depth=1;
}

if (isset($_GET["lang"])){
        $_SESSION["lang"]=$_GET["lang"];
}else{
        if (isset($_SESSION["languser"])){
                $_SESSION["lang"]=$_SESSION["languser"];
        }

        if (!isset($_SESSION["lang"])){
                $_SESSION["lang"]="fr";
        }
}

Pour la langue, on essaie d’abord de la récupérer par le paramètre fourni lors de la requête et le stocker dans la variable de session "lang", avant de pendre la variable de session "languser" si elle est définie, et enfin, si la variable de session "lang" n’est toujours pas définie, on prend par défaut langue française.

Une fonction de parcourt de rubrique et sous-rubrique est définie, ce qui permet de faire du parcours récursif, lorsque la fonction s’appelle elle-même.
La fonction renverra tous les identifiants de sous-rubriques dans lesquelles on est susceptible de trouver des éléments de diaporama.

function parcourt_rubrik($cur_rubrik,$curdepth,$maxdepth,$mindepth) {

Ces deux paramètres ne pouvant être passés d’un niveau à l’autre de la boucle récursive sans rendre la fonction complexe, on les redéfinit localement à chaque niveau.

        $tablerubriques="spip_rubriques";
        $tablearticles="spip_articles";

        $curdepth.=$curdepth+1;       
        $rubs=array(); // le tableau qu'on renverra, contenant dans la case 0 sa taille
        $reksrub="select id_rubrique from ".$tablerubriques." where id_parent=$cur_rubrik";
        $resrub=mysql_query($reksrub);
        while ($rowrub=mysql_fetch_array($resrub,MYSQL_ASSOC)){
                $ssrub=$rowrub["id_rubrique"];
                if ($curdepth>=$mindepth){
                        $rubs[]=$ssrub;
                }
                if ($curdepth<$maxdepth){
                        $rubs=array_merge($rubs,parcourt_rubrik($ssrub,$curdepth,$maxdepth,$mindepth));
                }
        }
        return $rubs;
}

On créé donc la liste des rubriques en appelant la fonction récursive, en partant de la rubrique fournie en paramètre par la requête xmlhttp.

$liste_rubriques=parcourt_rubrik($id_rubrique_diapo,$min_depth,$max_depth,$min_depth);

Ici, on construit un morceau de la requête SQL, à savoir une partie de la clause conditionnelle WHERE, en ajoutant à un code de base des morceaux de code SQL [1]
On utilise une boucle while (tant que) pour parcourir un tableau dont la taille est variable, en s’arrêtant lorsque l’index atteint le nombre de case contenues dans le tableau, et en incrémentant l’index au fur et à mesure.

$liste_rubrik="(id_rubrique=$id_rubrique_diapo";
$irub=0;

while ($irub<count($liste_rubriques)){
        $liste_rubrik.=" or id_rubrique=$liste_rubriques[$irub]";
        $irub++;
}

$liste_rubrik.=")";

Une fois que la partie "liste des rubriques parentes" de la requête des articles que l’on va sélectionner est créée, on l’utilise d’abord dans une requête pour compter les éléments, puis ensuite dans la requête de récupération.

/* requete pour connaître le nombre total de photos pouvant être affichées */

$rek_compt="select count(*) as total from ".$tablearticles." where $liste_rubrik and statut='publie' and lang='".$_SESSION["lang"]."'"; // pas de order by pour compter
$res_compt=mysql_query($rek_compt);
$row_total=mysql_fetch_array($res_compt,MYSQL_ASSOC);
$total=$row_total["total"];

  • clause SELECT :
    • On compte count
    • les lignes dans leur globalité count(*)
    • dont on stockera le compte dans une colonne nommée "total" as total, plus simple pour la référencer,
  • clause FROM
    • depuis la table des articles, dont le nom, susceptible de varier, a été mis dans la variable tablearticles
  • clause WHERE
    • pour les articles faisant partie de la liste des rubriques
    • et étant publiés
    • et dont la langue est celle déterminée plus tôt et stockée dans la variable de session.

if ($total>0){

Si il y a effectivement plusieurs articles publiés dans les rubriques ciblées et ce dans la langue choisie, alors on va récupérer les deux premiers articles selon un tri définit plus bas.
Le script JavaScript, fournissant toujours un paramètre de numéro de diapo à charger dans la requête xmlhttp, on se base sur ce paramètre pour démarrer la sélection dans la liste des articles disponibles.

Quand au prochain élément de diaporama à charger, c’est soit l’article suivant dans la liste - si l’article en cours n’est pas le dernier de la liste - soit le premier, à savoir le numéro 0 de la liste (tableau des réponses).

        $debut=$idd; // 0 par defaut
        $par_page=1;
       
        if (($idd+1)<$total){
                $prochain=$idd+1;
        }else{
                $prochain=0;
        }

La requête de sélection est la même que celle de comptage, logique puisque l’on travaille sur les mêmes éléments.
Seules les clauses SELECT - car on ne compte pas cette fois - et la clause de tri ORDER - qui était inutile dans une requête de comptage - vont changer
On ajoute aussi une clause LIMIT qui restreint le nombre de lignes de résultat que l’on va finalement traiter.

  • clause SELECT : on sélectionne tous les champs *
  • clause ORDER BY par date décroissante DESC, et donc par article le plus récent.
  • on limite les lignes de résultat à 1, comme vu plus haut         $par_page=1;, et on démarre à la ligne numéro $debut, à savoir $idd, le paramètre de numéro de diapo fourni à l’appel du script par la requête xmlhttp.

        $rek_sel="select * from ".$tablearticles." where $liste_rubrik and statut='publie' and lang='".$_SESSION["lang"]."' order by 'date' DESC limit $debut,$par_page "; // order by date DESC
        $res_sel=mysql_query($rek_sel);

Étant donné que l’on traite des articles, et que l’image cherchée est un logo, il est bon de savoir que sous SPIP, les logos ont un nom particulier :

  • type de l’élément SPIP articles, rubriques, sites
  • on
  • numéro dudit élément
  • les logos étant stockés à la racine du dossier IMG, peu importe leur extension (jpg, png, gif...)

        $imagebase="IMG/arton";

Pour chaque ligne de résultat renvoyée (en fait il n’y en a qu’une)

        while ($row_sel=mysql_fetch_array($res_sel,MYSQL_ASSOC)){

On récupère la valeur de chaque champ dont on a besoin.
Les champs de type texte (titre et texte) passent par plusieurs filtres pour traiter des caractères spéciaux qui risqueraient de faire planter le document XML réponse.

       
        $id=$row_sel["id_article"];
               
                $titre=htmlentities($row_sel["titre"]);
                $titre=remet_accents($titre);
                $titre=str_replace("'","&#039;",$titre);
                $titre=str_replace('"','&quot;',$titre);
                $titre=str_replace("°","&deg;",$titre);
                $texte=htmlentities($row_sel["texte"]);
                $texte=remet_accents($texte);
                $texte=str_replace("'","&#039;",$texte);
                $texte=str_replace('"','&quot;',$texte);
                $texte=str_replace("°","&deg;",$texte);
                $texte=nl2br($texte);
               
                $urlarticle="spip.php?article$id";

Pour l’image, on recherche si le fichier artonXX existe pour plusieurs extensions possibles.
Si un fichier portant ce nom existe, alors on a trouvé.

                // image = IMG/arton[+id article].jpg ou autre
                // =========== existence du fichier jpg, png ou gif ==============
                $extensions=array("jpg","jpeg","JPG","png","PNG","gif","GIF");
                $i=0;
                $trouve=false;
                $image="";
                while (($i<sizeof($extensions))&&($trouve==false)){
                        $image_test=$imagebase.$id.".".$extensions[$i];
                        //echo "on teste $image_test<br>";
                        if (file_exists($image_test)){
                                //echo "$image_test existe<br>";
                                $image=$image_test;
                                $trouve=true;
                        }else{
                                //echo "$image_test n'existe pas<br>";
                        }
                        $i++;
                }
                // image par défaut
                if (!$trouve){
                        $image="interrogation.png";
                }

Si aucun fichier image de logo correspondant à l’article n’est trouvé, on prend une image par défaut.
Puis on récupère les dimensions de l’image contenue dans le fichier avec une fonction PHP.

       
                $infos_image = @getImageSize($image); // info sur la dimension de l'image
       
                // '@' est placé devant la fonction getImageSize() pour empecher l'affichage des erreurs si l'image est absente.
               
                 //dimension
                 $largeur = $infos_image[0]; // largeur de l'image
                 $hauteur = $infos_image[1]; // hauteur de l'image

Ces informations de taille seront envoyées dans la réponse et utilisées par le script pour redimensionner l’image si besoin est.

Et on oublie pas de fermer la boucle de traitement de la ligne de résultat des articles correspondants à ce que l’on cherche.

       
        }

Puis on sélectionne l’image suivante afin de pouvoir commencer à la charger plus tôt, de sorte qu’au tour d’après, l’image de la diaporama suivante se chargera plus vite.
La requête est la même que la précédente, mais on ne prendra pas la même ligne de résultat.
Le traitement pour trouver le fichier image sera le même.

Image suivante

        $rek_presel="select * from ".$tablearticles." where $liste_rubrik and statut='publie' and lang='".$_SESSION["lang"]."' order by 'date' DESC limit $prochain,$par_page "; // order by date DESC
        $res_presel=mysql_query($rek_presel);
        while ($row_presel=mysql_fetch_array($res_presel,MYSQL_ASSOC)){
                $extensions=array("jpg","jpeg","JPG","png","PNG","gif","GIF");
                $i=0;
                $trouve=false;
                $pre_image="";
                while (($i<sizeof($extensions))&&($trouve==false)){
                        $image_test=$imagebase.$id.".".$extensions[$i];
                        //echo "on teste $image_test<br>";
                        if (file_exists($image_test)){
                                //echo "$image_test existe<br>";
                                $pre_image=$image_test;
                                $trouve=true;
                        }else{
                                //echo "$image_test n'existe pas<br>";
                        }
                        $i++;
                }
                // image par défaut
                if (!$trouve){
                        $pre_image="interrogation.png";
                }
        }
        //echo "image trouvee : $image<br>";

Si en revanche il n’y a aucun article correspondant à ce que l’on cherche

}else{
        $image="interrogation.png";
        $texte="\"\"";
        $largeur=0;
        $hauteur=0;
        $delai=0;
        $pre_image="\"\"";       
        $urlarticle="#"; // page actuelle
        $prochain=-1;
        $titre="Aucune image disponible."; // changer le texte selon la langue
        if ($_SESSION["lang"]=="fr"){
                $titre="Aucune image disponible."; // changer le texte selon la langue
        }
        if ($_SESSION["lang"]=="en"){
                $titre="No article available for this language : english."; // changer le texte selon la langue
        }
        if ($_SESSION["lang"]=="de"){

        }
        $texte=$titre;
        // $texte=htmlentities($texte);
        // $texte=remet_accents($texte);
}

Puis il est temps de créer le document XML qui servira de réponse.
Dans Firebug, il est possible de voir, dans l’onglet réseau, les requêtes avec leurs paramètres, et les réponses associées en XML.

On crée un objet de type DOMDocument, puis on y ajoute les éléments et sous-éléments, en commençant par la racine du document.

// réponse du serveur = contenu de l'XmlHttpResponse
$doc=new DOMDocument("1.0","utf-8");
$racine=$doc->createElement('root');
$doc->appendChild($racine);
$url_image=$doc->createElement('image',$image);
$racine->appendChild($url_image);
$lien=$doc->createElement('url_article',$urlarticle);
$racine->appendChild($lien);
$titre_diapo=$doc->createElement('titre',$titre);
$racine->appendChild($titre_diapo);
$texte_diapo=$doc->createElement('texte',$texte);
$racine->appendChild($texte_diapo);
$info=$doc->createElement('largeur',$largeur);
$racine->appendChild($info);
$info2=$doc->createElement('hauteur',$hauteur);
$racine->appendChild($info2);
$tempo=$doc->createElement('delai',$delai);
$racine->appendChild($tempo);
$next=$doc->createElement('prochain',$prochain);
$racine->appendChild($next);
$pre=$doc->createElement('preload',$pre_image);
$racine->appendChild($pre);
$debug=$doc->createElement('debug',"$debugmsg");
$racine->appendChild($debug);

Et pour finir, on envoie le document par un simple echo du texte XML renvoyé par la fonction saveXML sur l’objet.

echo $doc->saveXML();
?>

Notes

[1ça tombe bien, j’avais justement besoin d’exemple de ce genre de méthode pour un autre article

Répondre à cet article

Total 190764 visites depuis 2729 jours | Site réalisé par Vader[FR] | SPIP | | Plan du site | Suivre la vie du site RSS 2.0 | contact mail