2009-12-29 à 17:36:59

XML Sitemap

Cet article aurait du être écrit il y a bien longtemps, au moins en 2006 déjà. Mais voilà, les aléas de la vie informatique nous font remettre au lendemain les choses projetées la veille qui s'enfouissent dans le code déjà produit mais … jamais documenté.

Au départ, c'est un article trouvé sur Internet qui nous a mis la puce à l'oreille, un article consacré au Google Sitemap : http://www.phpfive.com/article_5.php. Cependant, cette réference n'existe plus, malheureusement! Et depuis, les Google sitemaps se sont transposés en XML Sitemaps.

Les XML Sitemaps sont un moyen facile pour les gestionnaires de sites d'indiquer aux moteurs de recherche quelles pages composent leurs sites sans que les moteurs de recherche aient eux-mêmes à déterminer les pages en question.

Par ailleurs, cela leur permet également d'indiquer quand les URLs en question ont été mises à jour, à quelle fréquence elles sont en général mises à jour, quelle importance elles revêtent l'une par rapport à l'autre, etc. C'est un sacré coup de main pour les moteurs de recherche.

Ce genre de fichier est — simplifions un peu les choses — une collection d'URL, collection que les moteurs de recherche pourront utiliser mais, soyons clairs, sans certitude qu'elle le soit. Cela vaut comme "renseignement" et non comme "directive".

Au départ, notre framework Vae Soli! utilisait la version 0.84 du protocole, une version qui à l'époque n'était — si nous ne nous trompons pas — uniquement utilisée par Google. Voilà d'ailleurs l'instruction de génération du sitemap que nous utilisions en 2006: <urlset xmlns="http://www.google.com/schemas/sitemap/0.84">.

Depuis, Yahoo!, Google et Microsoft, tous ensemble, utilisent le protocole en question, désormais sous sa version 0.90, une version sous les termes de la licence "Attribution-ShareAlike" de Creative Commons. Il est désormais documenté à l'adresse suivante : sitemaps.org

Vae Soli! et les XML sitemaps

Vae Soli! permet de créer des XML sitemaps le plus aisément du monde. En UNE SEULE instruction, il vous est possible de créer un XML Sitemap à partir du géorama. Un bref rappel s'impose avant que nous ne vous montrions la méthode en question.

Le géorama est une carte de l'ensemble d'un site: tout y est indiqué pour la gestion du site. Le site nous l'appelons le Pangaea (La Pangée est le nom donné au supercontinent du Paléozoïque et du Mésozoïque : c'est notre analogie pour désigner un site web). La Pangée est composée de Lands (pays); les Lands sont composés d'archipels et les archipels sont composés d'îles. Les pays (<Land>) qui composent la Pangée sont les pages qui doivent être prises en compte dans le site. Et les pays sont composés d'archipels (<Archipelago>) qui eux-mêmes sont composés d'îles (<Island>). Si les pays sont apparentés à des pages d'un site, les archipels sont eux des groupes de blocs de données (textes et images). Par exemple on peut avoir un archipel qui représente le corps principal d'une page et un autre archipel qui représente des informations secondaires. Les archipels sont eux-mêmes composés d'îles (Island). Chaque île représente des données (textes, images, sons, vidéo, ...). Par exemple on pourrait disposer d'un archipel avec le texte principal d'une page qui se découpe en différents paragraphes (les îles).

Dès lors, si toutes les pages d'un site sont répertoriées dans le géorama, il devient simple — mais vraiment d'une simplicité enfantine — de créer un fichier XML qui recence … toutes les pages du site. Hihi. À la limite, c'est une simple transformation XSL.

Maintenant que nous avons vu à quoi sert un XML Sitemap, il y a lieu de s'intéresser à la manière de créer le XML Sitemap, de le mentionner aux moteurs de recherche et à éviter quelques pièges, notamment pour les cross domains.

Exemple

Le plus simple est de partir de l'exemple d'un sitemap composé d'une seule page pour le site de Lato Sensu Management, www.latosensu.be :

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <url>
      <loc>http://www.latosensu.be/</loc>
      <lastmod>2005-01-01</lastmod>
      <changefreq>monthly</changefreq>
      <priority>0.8</priority>
   </url>
</urlset>

On constate en premier lieu que le prologue du fichier XML fait usage de l'encodage UTF-8. C'est une obligation.

<?xml version="1.0" encoding="UTF-8"?>

Ensuite, on remarque que le namespace du XML pointe vers la spec du XML Sitemap :

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

Enfin, viennent les 4 tags principaux qui définissent chaque URL :

  • <loc>...</loc>
  • <lastmod>...</lastmod>
  • <changefreq>...</changefreq>
  • <priority>...</priority>

Seul le tag <loc>...</loc> est obligatoire parmi les 4.

Référence

Voyons ce que chaque tag signifie et comment le formater :

Tags du XML Sitemap
Tag Description
<loc> OBLIGATOIRE: URL de la page. Celle-ci doit mentionner le protocole. Elle ne peut pas comporter plus de 2048 caractères. Nous vous conseillons donc de toujours utiliser un FQDN (Fully Qualified Domain Name). L'URL doit être échappée (escaped) (codes d'échappement d'entité). Voici la liste des caractères qui DOIVENT être codés :
CaractèreCode d'échappement
&&amp;
'&apos;
"&quot;
<&lt;
>&gt;
<lastmod> FACULTATIF: Date de dernière modification du fichier. Vous devez mentionner la date au format requis par le W3C. Le plus simple, évidemment, consisite à ne stipuler que la date. Dans ce cas, elle doit être formatée à la manière YYYY-MM-DD (2009-12-15 étant l'indication pour le 15 décembre 2009).
<changefreq> FACULTATIF: Fréquence probable de modification de la page. Ceci doit être considéré comme une indication pour les moteurs de recherche et NON comme une obligation pour ces derniers d'indexer la page à cet intervalle. Les valeurs suivantes sont possibles :
  • always (documents qui changent à chaque accès)
  • hourly
  • daily
  • weekly
  • monthly
  • yearly
  • never (URL archivées)
<priority> FACULTATIF: Priorité de cette URL par rapport aux autres URL du site, selon l'angle des moteurs de recherche ... et est donc utilisée pour hiérarchiser vos propres résultats (cad sans aucune comparaison avec les autres sites qui pourraient parler du même sujet). Les valeurs possibles sont comprises entre 0.0 et 1.0. Si ce paramètre n'est pas fourni, la valeur prise en compte est 0.5.

Attention, le fichier XML Sitemap résultat ne peut dépasser 50000 URLs et ne peut être plus gros que 10Mb (10485760 bytes). Attention, il est possible de "compresser" les fichiers XML Sitemaps ... mais en tout état de cause la taille maxi de 10Mb vaut pour après décompression. C'est ce que dit la spec disponible sur http://www.sitemaps.org/fr/protocol.php.

Composition du fichier XML Sitemap

Sur base des infos précédentes, vous devinez dès lors que la création d'un XML Sitemap est donc affaire de parcourir l'ensemble des pages de votre site que vous souhaitez référencer (il est inutile de faire indexer des pages de votre site qui n'ont aucune valeur de référencement, des pages d'aide par exemple ou … les pages de votre intranet dont nous doutons que vous vouliez qu'elles soient référencées publiquement).

Voilà à quoi ressemble un fichier XML Sitemap général dont nous n'avons gardé que quelques URLs :

<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>http://www.latosensu.be/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.8</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/colophon.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.4</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/links.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.4</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/toolkit.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>weekly</changefreq>
        <priority>0.8</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/projects/core/vaesoli/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>weekly</changefreq>
        <priority>0.8</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/vaesoli-downloads.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.8</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/xml-sitemap/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>weekly</changefreq>
        <priority>0.6</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles-core.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>weekly</changefreq>
        <priority>0.6</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/pageframe-tabs/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.6</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/image-transition/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.6</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/inline-javascript/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.6</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/accessibility-seo/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.4</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/longitude-latitude-google-maps/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.4</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/wiki/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.4</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/css/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.5</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/accessible-popups/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.2</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/php-server-variables/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.2</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/gestion-des-couleurs/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>weekly</changefreq>
        <priority>0.8</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/risk management/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.4</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/vaesoli-transform-images/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.6</priority>
    </url>
    <url>
        <loc>http://www.latosensu.be/articles/core/sponsorship-meeting/index.php</loc>
        <lastmod>2009-12-17</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.4</priority>
    </url>
<urlset>

Les valeurs des différentes balises <priority> et <changefreq> sont issues directement du géorama.

Validation du XML Sitemap

Nous vous conseillons de valider attentivement votre fichier XML Sitemap. Pour ce faire, vous devez utiliser le schéma approprié (http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd) et faire appel à un outil de validation. Le site du W3C propose une liste très fournie d'outils.

Que ce soit pour des questions de formatage ou de droits, les URL refusées ne sont plus prises en compte. Il est donc vivement recommandé de tester avec minutie la création de votre fichier sitemap sous peine d'obtenir l'effet inverse escompté.

Multiples XML Sitemap

Il est possible de mentionner plusieurs fichiers XML Sitemap. En réalité, chaque fichier sitemap ne peut contenir que des URLs relatives au même domaine, même chemin. Par exemple, si un fichier sitemap est déposé dans le répertoire www.latosensu.be/news/, alors toutes les URLs mentionnées dans ce fichier sitemap DOIVENT commencer par www.latosensu.be/news/. Par ailleurs, le protocole utilisé doit faire partie de chaque URL (http ou https par exemple).

Par exemple, dans le cas du site de Lato Sensu Management, il serait utile que nous créions des sitemaps pour nos ressources, nos articles, nos nouvelles … et pour le reste de notre site. Ce qui ne saurait tarder !

Emplacement du XML Sitemap

L'emplacement du fichier Sitemap permet de déterminer l'ensemble des URL susceptibles d'être incluses dans ce plan Sitemap. Un fichier Sitemap stocké à l'adresse http://exemple.fr/catalog/sitemap.xml peut contenir toutes les URL commençant par http://exemple.fr/catalog/, mais ne peut pas inclure d'URL commençant par http://exemple.fr/images/. Si vous disposez des droits pour modifier le fichier http://example.org/path/sitemap.xml, il est admis que vous pourrez également fournir des informations sur les URL dotées du préfixe http://example.org/path/. Exemples d'URL qui seront acceptées dans http://example.com/catalog/sitemap.xml :

Autres formats

Il est possible de mentionner les URLs d'un domaine sous un autre format que le format XML. Ainsi, il est envisageable de renseigner les URLs sous la forme d'un flux RSS ou encore sous la forme d'un fichier texte. Cet article ne couvre ni l'une ni l'autre technique.

Index Sitemap

Domaines multiples

Un problème épineux du XML Sitemap tient à ce que les URLs à mentionner DOIVENT être liés au même domaine.

LSXMLSitemap

La nouvelle classe LSXMLSitemap est issue de notre ancienne classe LSGoogleSitemap que nous avons légèrement mise à jour sur base des nouvelles specs.

Grâce à sa méthode Create(), le LSXMLSitemap peut créer un XML sitemap pour tout un domaine. Voyons comment cette méthode fonctionne grâce à un exemple simple :

/* New XML Sitemap object */
$oSitemap = new LSXMLSitemap( $GLOBALS['oApp'],'c:\websites\mydomain.com\sitemap.xml' );
/* Create XML Sitemap file */
$oSitemap->Create( 'www.latosensu.be' );

Le même exemple … complet cette fois-ci :

$szXMLFile  = 'c:\websites\mydomain.com\sitemap.xml';

/* oApp refers to the global Application object created by Vae Soli! */
$oSitemap = new LSXMLSitemap( $GLOBALS['oApp'],$szXMLFile );    /* Create a new XML Sitemap object */

if ( $oSitemap instanceof LSXMLSitemap )                        /* If sitemap successfully created */
{
    if ( is_file( $szXMLFile ) )                                /* If XML Sitemap file already existing */
    {
        if ( FIL_Delete( $szXMLFile ) )                         /* Try to delete the file */
        {
            echo "<p>Le fichier <code>{$szXMLFile}</code> existait et il a été supprimé.</p>\n";
        }   /* if ( FIL_Delete( $szXMLFile ) ) */
        else   /* Else of ... if ( FIL_Delete( $szXMLFile ) ) */
        {
            echo "<p>Le fichier <code>{$szXMLFile}</code> existait et il n'a pas pu être supprimé.</p>\n";
        }   /* Else of ... if ( FIL_Delete( $szXMLFile ) ) */
    }   /* if ( is_file( $szXMLFile ) ) */

    if ( $oSitemap->Create( 'www.latosensu.be' ) == 0 ) /* Create the XML Sitemap file for the www.latosensu.be domain */
    {
        echo "<p>Le fichier <code>{$szXMLFile}</code> a été créé.</p>\n";
    }   /* if ( $oSitemap->Create( $szXMLFile ) ) */
    else   /* Else of ... if ( $oSitemap->Create( $szXMLFile ) ) */
    {
        echo "<p>Le fichier <code>{$szXMLFile}</code> n'a pas pu être créé correctement.</p>\n";
    }   /* End of ... Else of ... if ( $oSitemap->Create( $szXMLFile ) ) */
}   /* if ( $oSitemap instanceof LSXMLSitemap ) */

Bien … maintenant vous savez comment créer le fichier XML Sitemap. Encore faut-il avoir un mécanisme pour informer les moteurs de recherche que ce fichier est disponible.

Soumission du fichier XML Sitemap

La manière la plus simple de référencer le fichier XML Sitemap est de l'indiquer dans le le fichier robots.txt de votre site. En voilà un exemple :

User-agent: *
Disallow: /include/
Disallow: /template/
Disallow: /islands/
Disallow: /errdocs/
Disallow: /intranet/
Disallow: /logs/
Disallow: /vaesoli/

Sitemap: /sitemap-ls.xml

Dans l'exemple ci-dessus, le fichier XML Sitemap est localisé dans la racine du site sous le nom sitemap-ls.xml.

Vous pouvez aussi décider d'informer vous-même les moteurs de recherche de l'existence de votre fichier XML Sitemap. La table suivante vous donne des indications précieuses sur la manière de référencer vos XML Sitemaps sur les moteurs de recherche qui ont adhéré à ce standard, à savoir Google (qui, sauf erreur de notre part, a lancé l'initiative), Microsoft, Yahoo et Ask :

Soumission aux moteurs de recherche
Moteur de recherche URL de soumission Aide
Google http://www.google.com/webmasters/tools/ping?sitemap= Creating and submitting Sitemaps
Yahoo!
  • http://developer.yahoo.com/search/siteexplorer/V1/updateNotification.html
  • http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=SitemapWriter&url=
  • http://developer.yahoo.com/search/siteexplorer/V1/ping.html
  • http://search.yahooapis.com/SiteExplorerService/V1/ping?sitemap=
  • Using Site Explorer
  • http://developer.yahoo.com/search/siteexplorer/V1/updateNotification.html
  • http://developer.yahoo.com/search/siteexplorer/V1/ping.html
Ask.com http://submissions.ask.com/ping?sitemap=http%3A//www.the URL of your sitemap here.xml Q: Does Ask.com support sitemaps?
Bing (Live Search) http://www.bing.com/webmaster/ping.aspx?siteMap= Webmaster Center

Lectures additionnelles

  • http://en.wikipedia.org/wiki/Sitemaps
  • http://www.sitemaps.org
  • http://www.google.com/support/webmasters/bin/topic.py?topic=8476

Code source

0001 ... <?php
0002 ...     /**
0003 ...      *  @file                   LSXMLSitemap.class.php
0004 ...      *  @purpose                Création de sitemaps pour Google
0005 ...      *  @package                Vaesoli.Fondation.Classes
0006 ...      *  @subpackage             Sitemap.Google
0007 ...      *  @author                 Patrick Boens
0008 ...      *  @company                Lato Sensu Management
0009 ...      *                          Rue Bois des Mazuis, 47
0010 ...      *                          5070 Vitrival
0011 ...      *                          Belgium
0012 ...      *                          http://www.latosensu.be
0013 ...      *                          Vae Soli! : http://www.vaesoli.org
0014 ...      *  @creationdate           22/05/2006 - 14:36
0015 ...      *  @modificationdate       20/12/2009 - 10:40
0016 ...      *  @license                http://creativecommons.org/licenses/by-sa/2.0/be/
0017 ...      *
0018 ...      *                          Pour obtenir les informations détaillées des
0019 ...      *                          termes de licence, nous vous demandons de bien
0020 ...      *                          vouloir vous en référer au texte intégral
0021 ...      *                          fourni dans le fichier LSCopyright.php
0022 ...      *
0023 ...      *  ------------------------------------------------------------------------
0024 ...      *  Changes History     :   Based on an idea found at http://www.phpfive.com/article_5.php
0025 ...      *  ........................................................................
0026 ...      *  06/05/2008          :   1)  All comments before this release have been
0027 ...      *  v. 1.1.0515                 eliminated (for tracking purposes, please
0028 ...      *                              head to the Vae Soli! archive
0029 ...      *                              (vaesoli-1.1.0501.zip)). At that time it was
0030 ...      *                              still a Google spec (Google Sitemap). Since
0031 ...      *                              then it has evolved to an industry spec.
0032 ...      *  ........................................................................
0033 ...      *  11/12/2009          :   1)  New implementation based on sitemaps.org
0034 ...      *  v. 2.3.0007                 standards:
0035 ...      *                              Doc on Google: http://www.google.com/support/webmasters/bin/topic.py?topic=8476
0036 ...      *                              Doc on sitemaps.org: http://www.sitemaps.org/protocol.php
0037 ...      *  ........................................................................
0038 ...      *  15/12/2009          :   1)  Limits of specs are now set in properties
0039 ...      *  v. 2.3.0007                 which permits to overwrite them
0040 ...      *  ........................................................................
0041 ...      *  20/12/2009          :   1)  Cosmetic modifications
0042 ...      *  v. 2.4.0000
0043 ...      *  ------------------------------------------------------------------------
0044 ...     */
0045 ... 
0046 ...     if ( ! defined( 'VAESOLI_PATH' ) )                                  /* If the path is not defined yet */
0047 ...     {
0048 ...         /**
0049 ...          * @ignore
0050 ...          */
0051 ...         define( 'VAESOLI_PATH',dirname( __FILE__ ) );                   /* Define the path where Vae Soli! is installed */
0052 ...     }   /* if ( ! defined( 'VAESOLI_PATH' ) ) */
0053 ... 
0054 ...     if ( ! defined( 'VAESOLI_PLUGINS' ) )                               /* If the path is not defined yet */
0055 ...     {
0056 ...         /**
0057 ...          *  Définit où sont installés les plug-ins de Vae Soli!
0058 ...          *  @ignore
0059 ...          */
0060 ...         define( 'VAESOLI_PLUGINS',FIL_Normalize( VAESOLI_PATH . '/../plugins' ) ); /* Define where the plugins are located */
0061 ...     }   /* if ( ! defined( 'VAESOLI_PLUGINS' ) ) */
0062 ... 
0063 ...     if ( ! defined( 'CODE_ORIGIN' ) )                                   /* This defines a macro for tracing */
0064 ...     {
0065 ...         define( 'CODE_ORIGIN',__METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ')' );
0066 ...     }   /* if ( ! defined( 'CODE_ORIGIN' ) ) */
0067 ... 
0068 ...     /* ====================================================================== */
0069 ...     /**
0070 ...      *  XML Sitemap (à la Google)
0071 ...      *  @package                Vaesoli.Fondation.Classes
0072 ...      *  @subpackage             Sitemap
0073 ...      */
0074 ...     /* ====================================================================== */
0075 ...     class LSXMLSitemap
0076 ...     /*==============*/
0077 ...     {
0078 ...         /**
0079 ...          *  Objet LSApplication qui a créé le géorama
0080 ...          *  @var $oApp
0081 ...          */
0082 ...         public      $oApp                   = null;
0083 ... 
0084 ...         /**
0085 ...          *  Fichier XML Sitemap
0086 ...          *  @var    string
0087 ...          */
0088 ...         public      $szFile                 = null;
0089 ... 
0090 ...         /**
0091 ...          *  Document Object Model
0092 ...          *  @var LSDom
0093 ...          */
0094 ...         public      $oDom                   = null;
0095 ... 
0096 ...         /**
0097 ...          *  Objet XPath
0098 ...          *  @var LSXPath
0099 ...          */
0100 ...         public      $oXPath                 = null;
0101 ... 
0102 ...         /**
0103 ...          *  Racine du site
0104 ...          *  @var string
0105 ...          */
0106 ...         public      $szRoot                 = null;
0107 ... 
0108 ...         /**
0109 ...          * Objet offrant des services de trace
0110 ...          * @var LSTracer
0111 ...          */
0112 ...         public      $oTracer                = null;
0113 ... 
0114 ...         /**
0115 ...          *  Nom du fichier géorama
0116 ...          *  @var string
0117 ...          */
0118 ...         public      $szGeoramaFile          = null;
0119 ... 
0120 ...         /**
0121 ...          *  Taille limite du fichier XML
0122 ...          *  @var    integer
0123 ...          */
0124 ...         public      $iLimit                 = 10485760;
0125 ... 
0126 ...         /**
0127 ...          *  Nombre maximum d'URLs
0128 ...          *  @var    integer
0129 ...          */
0130 ...         public      $iURLCount              = 50000;
0131 ... 
0132 ... 
0133 ...         /* ================================================================== */
0134 ...         /**
0135 ...          *  Constructeur de la classe
0136 ...          *  @param      string      $szFile     Nom du fichier sitemap
0137 ...          *  Google sitemap sample:
0138 ...          *                <?xml version="1.0" encoding="UTF-8"?>
0139 ...          *                <!-- <urlset xmlns="http://www.google.com/schemas/sitemap/0.84"> -->
0140 ...          *                <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
0141 ...          *
0142 ...          *                   <url>
0143 ...          *                      <loc>http://www.fastwrite.com/</loc>
0144 ...          *                      <lastmod>2006-05-20</lastmod>
0145 ...          *                      <changefreq>weekly</changefreq>
0146 ...          *                      <priority>0.8</priority>
0147 ...          *                   </url>
0148 ...          *                   ...
0149 ...          *                </urlset>
0150 ...          */
0151 ...         /* ================================================================== */
0152 ...         //function LSXMLSitemap( $szFile = '', $szLang = 'fr' )
0153 ...         function LSXMLSitemap( $oApplication = null,$szFile = '' )
0154 ...         /*------------------------------------------------------*/
0155 ...         {
0156 ...             /******************************************************************/
0157 ...             /* The georama will contain a reference to the Application object */
0158 ...             /* The application object will contain a reference to the georama */
0159 ...             /******************************************************************/
0160 ...             if ( $oApplication instanceof LSApplication )
0161 ...             {
0162 ...                 $oApplication->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : entering function",TRACING_INFO_LEVEL );
0163 ...                 $this->oApp             = $oApplication;                /* Application object */
0164 ...                 $this->szRoot           = $this->oApp->szRoot;          /* Set class member with parameter : root directory */
0165 ...                 $this->szGeoramaFile    = $this->oApp->szGeoramaFile;   /* Set class member with parameter : georama file */
0166 ...                 $this->szFile           = $szFile;                      /* Assign filename */
0167 ...                 $this->oDom             = new LSDom( '1.0','utf-8' );   /* Create new DOM */
0168 ...                 $oApplication->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : exiting function",TRACING_INFO_LEVEL );
0169 ...             }   /* if ( $oApplication instanceof LSApplication ) */
0170 ... 
0171 ...         }  /* End of method constructor for LSXMLSitemap class */
0172 ...         /* ================================================================== */
0173 ... 
0174 ...         /* ================================================================== */
0175 ...         /**
0176 ...          *  Crée un fichier XML Sitemap pour un domaine donné
0177 ...          *  @param  string      $szDomain       Domain name for which the XML sitemap
0178 ...          *                                      needs to be created
0179 ...          *  @return boolean                     true if sitemap created successfully;
0180 ...          *                                      false otherwise.
0181 ...          */
0182 ...         /* ================================================================== */
0183 ...         function Create( $szDomain )
0184 ...         /*------------------------*/
0185 ...         {
0186 ...             $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : entering function",TRACING_INFO_LEVEL );
0187 ...             $iRetVal = 0;                                               /* Ready to return a success */
0188 ... 
0189 ... /**
0190 ...  *  @todo   Une amélioration appréciable de la classe serait de pouvoir
0191 ...  *          générer un fichier XML Sitemap sur base d'un groupe de pages
0192 ...  *          (group="...") du géorama
0193 ...  */
0194 ...             if ( $this->szGeoramaFile )                                 /* If georama file mentioned */
0195 ...             {
0196 ...                 $oGeoDom = new LSDom();                                 /* Create new DOM for the georama */
0197 ... 
0198 ...                 if ( $oGeoDom )                                         /* If DOM for georama is successfully created */
0199 ...                 {
0200 ...                     if ( $oGeoDom->load( $this->szGeoramaFile ) )       /* If georama file can be loaded */
0201 ...                     {
0202 ...                         $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : {$this->szGeoramaFile} successfully loaded",TRACING_INFO_MEDIUM_LEVEL );
0203 ... 
0204 ...                         if ( ( $oXPath = new LSXPath( $oGeoDom ) ) )    /* Create a new XPath object */
0205 ...                         {
0206 ...                             /*************************/
0207 ...                             /* ALL is well until now */
0208 ...                             /*************************/
0209 ...                             $szQuery = "//Georama/Pangaea/Land[string-length(@landscape)=0 and @active='yes'] |" .
0210 ...                                        "//Georama/Pangaea/Land[contains(@landscape,'{$szDomain}') and @active='yes']";
0211 ...                             $oPageColl = $oXPath->query( $szQuery );    /* Execute XPath query */
0212 ... 
0213 ...                             if ( $oPageColl->length > 0 )               /* If pages found */
0214 ...                             {
0215 ...                                 $iCount = 0;                            /* 0 URL added so far */
0216 ... 
0217 ...                                 foreach( $oPageColl as $oPage )         /* For each page we have found */
0218 ...                                 {
0219 ...                                     if ( $oPage instanceof DOMNode )    /* If page is an instance of a DOM node */
0220 ...                                     {
0221 ...                                         $oSitemapColl = $oXPath->query( 'Sitemap',$oPage ); /* Is this page participating to a sitemap */
0222 ... 
0223 ...                                         if ( $oSitemapColl->length > 0 )/* Yep ... it's in there */
0224 ...                                         {
0225 ...                                             $szID        = $oPage->getAttribute( 'id' ); /* page ID = also page name + page aliases */
0226 ...                                             $szPriority  = $oSitemapColl->item(0)->getAttribute( 'priority'  ); /* Sitemap priority */
0227 ...                                             $szFrequency = $oSitemapColl->item(0)->getAttribute( 'frequency' ); /* Sitemap frequency */
0228 ...                                             $szMainID    = $szID;       /* Main page name (aliases are forgotten */
0229 ... 
0230 ...                                             if ( $iPos = stripos( $szID,';' ) ) /* Position of the ';' char */
0231 ...                                                 $szMainID = STR_left( $szID,$iPos ); /* Page name */
0232 ... 
0233 ...                                             if ( ! $this->Add( $szMainID,$szPriority,$szFrequency ) ) /* Add page to sitemap */
0234 ...                                             {
0235 ...                                                 $iRetVal = -1; /* Ready to return a failure */
0236 ...                                                 $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : {$szMainID} cannot be added to sitemap",TRACING_WARNING_LEVEL );
0237 ...                                                 break;
0238 ...                                             }   /* if ( ! $this->Add( $szMainID,$szPriority,$szFrequency ) ) */
0239 ...                                         }   /* if ( $oSitemapColl->length > 0 ) */
0240 ...                                     }   /* if ( $oPage instanceof DOMNode ) */
0241 ... 
0242 ...                                     if ( ++$iCount > $this->iURLCount ) /* Spec says that 50000 URLs is a max */
0243 ...                                     {
0244 ...                                         $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : URL limit (50000) reached",TRACING_WARNING_LEVEL );
0245 ...                                         break;                          /* Stop adding URL to sitemap */
0246 ...                                     }   /* if ( $++iCount > $this->iURLCount ) */
0247 ...                                 }   /* foreach( $oPageColl as $oPage ) */
0248 ...                             }   /* if ( $oPageColl->length > 0 ) */
0249 ...                             else   /* Else of ... if ( $oPageColl->length > 0 ) */
0250 ...                             {
0251 ...                                 $iRetVal = -1; /* Ready to return a failure */
0252 ...                                 $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : no page found in georama",TRACING_WARNING_LEVEL );
0253 ...                             }   /* End of ... Else of ... if ( $oPageColl->length > 0 ) */
0254 ...                         }   /* if ( ( $oXPath = new LSXPath( $oGeoDom ) ) ) */
0255 ...                         else   /* Else of ... if ( ( $oXPath = new LSXPath( $oGeoDom ) ) ) */
0256 ...                         {
0257 ...                             $iRetVal = -1; /* Ready to return a failure */
0258 ...                         }   /* End of ... Else of ... if ( ( $oXPath = new LSXPath( $oGeoDom ) ) ) */
0259 ...                     }   /* if ( $oGeoDom->load( $this->szGeoramaFile ) ) */
0260 ...                     else   /* Else of ... if ( $oGeoDom->load( $this->szGeoramaFile ) ) */
0261 ...                     {
0262 ...                         $iRetVal = -1; /* Ready to return a failure */
0263 ...                         $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : cannot load {$this->szGeoramaFile}",TRACING_ERROR_LEVEL );
0264 ...                     }   /* End of ... Else of ... if ( $oGeoDom->load( $this->szGeoramaFile ) ) */
0265 ...                 }   /* if ( $oGeoDom ) */
0266 ...                 else   /* Else of ... if ( $oGeoDom ) */
0267 ...                 {
0268 ...                     $iRetVal = -1; /* Ready to return a failure */
0269 ...                     $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : DOM cannot be created",TRACING_ERROR_LEVEL );
0270 ...                 }   /* End of ... Else of ... if ( $oGeoDom ) */
0271 ...             }   /* if ( $this->szGeoramaFile ) */
0272 ...             else   /* Else of ... if ( $this->szGeoramaFile ) */
0273 ...             {
0274 ...                 $iRetVal = -1; /* Ready to return a failure */
0275 ...                 $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : No georama file",TRACING_ERROR_LEVEL );
0276 ...             }   /* End of ... Else of ... if ( $this->szGeoramaFile ) */
0277 ... 
0278 ...             $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : exiting function",TRACING_INFO_LEVEL );
0279 ... 
0280 ...         }  /* End of method LSXMLSitemap.Create() */
0281 ...         /* ================================================================== */
0282 ... 
0283 ...         /* ================================================================== */
0284 ...         /**
0285 ...          *  Ajoute une URL dans le sitemap XML
0286 ...          *  @param  string      $szURL          The URL to add to the sitemap
0287 ...          *  @param  string      $szPriority     The priority of this URL relative to
0288 ...          *                                      other URLs on your site. Valid
0289 ...          *                                      values range from 0.0 to 1.0. This
0290 ...          *                                      value has no effect on your pages
0291 ...          *                                      compared to pages on other sites,
0292 ...          *                                      and only lets the search engines
0293 ...          *                                      know which of your pages you deem
0294 ...          *                                      most important so they can order the
0295 ...          *                                      crawl of your pages in the way you
0296 ...          *                                      would most like. Deafult priority
0297 ...          *                                      is set to '0.5'.
0298 ...          *  @param  string      $szFrequency    "always"
0299 ...          *                                      "hourly"
0300 ...          *                                      "daily"
0301 ...          *                                      "weekly"
0302 ...          *                                      "monthly"
0303 ...          *                                      "yearly"
0304 ...          *                                      "never"
0305 ...          *  @return boolean
0306 ...          *  XML sitemap sample:
0307 ...          *                <?xml version="1.0" encoding="UTF-8"?>
0308 ...          *                <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
0309 ...          *
0310 ...          *                   <url>
0311 ...          *                      <loc>http://www.fastwrite.com/</loc>
0312 ...          *                      <lastmod>2006-05-20</lastmod>
0313 ...          *                      <changefreq>weekly</changefreq>
0314 ...          *                      <priority>0.8</priority>
0315 ...          *                   </url>
0316 ...          *                   ...
0317 ...          *                </urlset>
0318 ...          *  The Sitemap protocol format consists of XML tags. All data values
0319 ...          *  in a Sitemap must be entity-escaped.
0320 ...          *  The file itself must be UTF-8 encoded.
0321 ...          *
0322 ...          */
0323 ...         /* ================================================================== */
0324 ...         function Add( $szURL,$szPriority = '0.5',$szFrequency = 'weekly' )
0325 ...         /*--------------------------------------------------------------*/
0326 ...         {
0327 ...             $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : entering function",TRACING_INFO_LEVEL );
0328 ... 
0329 ...             static $iCounter = 0;                                       /* Counter */
0330 ...             $bRetVal         = false;                                   /* Return value of the function (false by default) */
0331 ... 
0332 ...             if ( ! is_null( $this->oDom ) )                             /* If DOM successfully created */
0333 ...             {
0334 ...                 if ( ! is_file( $this->szFile ) )                       /* If XML file cannot be found */
0335 ...                 {
0336 ...                     $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : {$this->szFile} not found",TRACING_INFO_MEDIUM_LEVEL );
0337 ... 
0338 ...                     $szXMLNS = 'http://www.sitemaps.org/schemas/sitemap/0.9';
0339 ... 
0340 ...                     $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : creating a Namespace ({$szXMLNS})",TRACING_INFO_MEDIUM_LEVEL );
0341 ... 
0342 ...                     $oRoot   = $this->oDom->createElementNS( $szXMLNS,'urlset' ); /* Let's create an elment with a namespace qualifier */
0343 ... 
0344 ... /**
0345 ...  *  @todo   Attention, il me manque l'encoding UTF-8
0346 ...  */
0347 ...                     $this->oDom->appendChild( $oRoot );                 /* Add the root to the DOM */
0348 ...                     $this->oDom->save( $this->szFile );                 /* Save everything already */
0349 ...                 }   /* if ( ! is_file( $this->szFile ) ) */
0350 ... 
0351 ...                 if ( $this->oDom->load( $this->szFile ) )               /* Load the XML file */
0352 ...                 {
0353 ...                     $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : {$this->szFile} loaded",TRACING_INFO_HIGH_LEVEL );
0354 ... 
0355 ...                     if ( strncmp( $szURL,'/',1 ) == 0 )                 /* First canonize URLs : if URL starts with a '/' */
0356 ...                     {
0357 ...                         $szFinalURL = "http://" . $_SERVER['SERVER_NAME'] . $szURL;
0358 ...                     }   /* if ( strncmp( $szURL, '/', 1) == 0 ) */
0359 ...                     else   /* Else of ... if ( strncmp( $szURL, '/', 1) == 0 ) */
0360 ...                     {
0361 ...                         $szFinalURL = $szURL;                           /* Final URL is the URL */
0362 ...                     }   /* End of ... Else of ... if ( strncmp( $szURL, '/', 1) == 0 ) */
0363 ... 
0364 ...                     // OLD query
0365 ...                     //$szQuery        = '/*/*/*[local-name()="loc"][text()="' . $szFinalURL . '"]';
0366 ...                     $this->oXPath = new LSXPath( $this->oDom );        /* Create an XPath object */
0367 ... 
0368 ...                     if ( $this->oXPath instanceof LSXPath )             /* If XPath object */
0369 ...                     {
0370 ...                         $szQuery = "//urlset/url/loc[text()=\"{$szFinalURL}\"]"; /* XPath query to execute */
0371 ... 
0372 ...                         $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : XML query = {$szQuery}",TRACING_INFO_HIGH_LEVEL );
0373 ... 
0374 ...                         $allURLs = $this->oXPath->query( $szQuery );    /* Execute XPath query */
0375 ... /**
0376 ... * @todo Si on ajoute un URL et que celui-ci existe déjà ...
0377 ... *       il faut non pas l'ajouter MAIS le modifier avec les
0378 ... *       nouvelles données.
0379 ... */
0380 ... 
0381 ...                         if ( $allURLs->length <= 0 )                    /* If URL not found in XML Sitemap file */
0382 ...                         {
0383 ...                             $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : {$szQuery} not found in sitemap. It must be added to the sitemap.",TRACING_INFO_HIGH_LEVEL );
0384 ... 
0385 ...                             {   /* Create the high level node (<url>) */
0386 ...                                 $oUrlNode           = $this->oDom->createElement( 'url'        );/* <url> */
0387 ...                             }
0388 ... 
0389 ...                             {   /* Create sub-nodes of <url> */
0390 ...                                 $oLocNode           = $this->oDom->createElement( 'loc'        );/*    <loc>...</loc> */
0391 ...                                 $oLastmodNode       = $this->oDom->createElement( 'lastmod'    );/*    <lastmod>...</lastmod> */
0392 ...                                 $oChangeFreqNode    = $this->oDom->createElement( 'changefreq' );/*    <changefreq>...</changefreq> */
0393 ...                                 $oPriorityNode      = $this->oDom->createElement( 'priority'   );/*    <priority>...</priority> */
0394 ...                             }                                                                    /* </url> */
0395 ...                             {   /* Create texts for sub-nodes */
0396 ...                                 $oLocText           = $this->oDom->createTextNode( htmlentities( $szFinalURL ) );
0397 ...                                 $oLastmodText       = $this->oDom->createTextNode( date( "Y-m-d" )             );/* 'c' = ISO 8601  - 'r' = RFC822) */
0398 ...                                 $oChangeFreqText    = $this->oDom->createTextNode( $szFrequency                );
0399 ...                                 $oPriorityText      = $this->oDom->createTextNode( $szPriority                 );
0400 ...                             }
0401 ... 
0402 ...                             {   /* Attach text to high level nodes */
0403 ...                                 /* Let's attach each text node to its container */
0404 ...                                 $oLocNode->appendChild(        $oLocText          ); /* <loc> $oLoctext </loc> */
0405 ...                                 $oLastmodNode->appendChild(    $oLastmodText      ); /* <lastmod> $oLastmodText </lastmod> */
0406 ...                                 $oChangeFreqNode->appendChild( $oChangeFreqText   ); /* <changefreq> $oChangeFreqText </changefreq> */
0407 ...                                 $oPriorityNode->appendChild(   $oPriorityText     ); /* <priority> $oPriorityText </priority> */
0408 ...                             }
0409 ... 
0410 ...                             {   /* Attach high level nodes to <url> node */
0411 ...                                 $oUrlNode->appendChild( $oLocNode           );
0412 ...                                 $oUrlNode->appendChild( $oLastmodNode       );
0413 ...                                 $oUrlNode->appendChild( $oChangeFreqNode    );
0414 ...                                 $oUrlNode->appendChild( $oPriorityNode      );
0415 ...                             }
0416 ... 
0417 ...                             /* Lets' attach the <url> container to the XML file (root) */
0418 ...                             $this->oDom->documentElement->appendChild( $oUrlNode );
0419 ... 
0420 ...                             if ( ( $nBytes = $this->oDom->save( $this->szFile ) ) ) /* Finally ... let's save the XML file (returns the number of bytes written) */
0421 ...                             {
0422 ...                                 $bRetVal = true;                        /* If > 0 ... return logical true */
0423 ...                                 if ( $nBytes > $this->iLimit )          /* Size of XML file cannot exceed 10Mb */
0424 ...                                 {
0425 ...                                     $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : XML file size exceeded ({$nBytes} bytes)",TRACING_WARNING_LEVEL );
0426 ... echo "<p>Problème 1</p>\n";
0427 ...                                     $bRetVal = false;                   /* Return a logical false because the XML size has exceeded the maximum size mentioned by the spec */
0428 ...                                 }   /* if ( $nBytes > $this->iLimit ) */
0429 ...                             }   /* if ( $this->oDom->save( $this->szFile ) ) */
0430 ...                             else   /* Else of ... if ( $this->oDom->save( $this->szFile ) ) */
0431 ...                             {
0432 ...                                 $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : cannot save XML file {$this->szFile}",TRACING_ERROR_LEVEL );
0433 ... echo "<p>Problème 2</p>\n";
0434 ...                                 $bRetVal = false;                       /* Ready to return a logical false */
0435 ...                             }   /* End of ... Else of ... if ( $this->oDom->save( $this->szFile ) ) */
0436 ...                         }   /* if ( $allURLs->length <= 0 ) */
0437 ...                         else   /* Else of ... if ( $allURLs->length <= 0 ) */
0438 ...                         {
0439 ...                             $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : {$szFinalURL} already found in {$this->szFile}",TRACING_INFO_LEVEL );
0440 ...                         }   /* End of ... Else of ... if ( $allURLs->length <= 0 ) */
0441 ...                     }   /* if ( $this->oXPath instanceof LSXPath ) */
0442 ...                     else   /* Else of ... if ( $this->oXPath instanceof LSXPath ) */
0443 ...                     {
0444 ...                         $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : cannot create XPath object",TRACING_ERROR_LEVEL );
0445 ...                     }   /* End of ... Else of ... if ( $this->oXPath instanceof LSXPath ) */
0446 ...                 }   /* if ( $this->oDom->load( $this->szFile ) ) */
0447 ...                 else   /* Else of ... if ( $this->oDom->load( $this->szFile ) ) */
0448 ...                 {
0449 ...                     $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : cannot load XML file ... {$this->szFile}",TRACING_ERROR_LEVEL );
0450 ...                 }   /* End of ... Else of ... if ( $this->oDom->load( $this->szFile ) ) */
0451 ...             }   /* if ( ! is_null( $this->oDom ) ) */
0452 ...             else   /* Else of ... if ( ! is_null( $this->oDom ) ) */
0453 ...             {
0454 ...                 $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : DOM unsuccessful",TRACING_WARNING_LEVEL );
0455 ...             }   /* End of ... Else of ... if ( ! is_null( $this->oDom ) ) */
0456 ... 
0457 ...             $iCounter++;                                                /* Increment counter */
0458 ...             $this->oApp->oTracer->Trace( __METHOD__ . ' (' . basename( __FILE__ ) . ' at line ' . __LINE__ . ") : exiting function (counter = {$iCounter})",TRACING_INFO_LEVEL );
0459 ... 
0460 ...             return ( $bRetVal );                                        /* Return result to caller */
0461 ...         }  /* End of method LSXMLSitemap.Add() */
0462 ...         /* ================================================================== */
0463 ...     }   /* End of class LSXMLSitemap */
0464 ... ?>

< Septembre 2010 >
Lu Ma Me Je Ve Sa Di
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30