[php5/dom] classe de creation de flux rss via un fichier xml

Description

Cette classe permet de creer un flux rss (version 2.0) grace a un fichier xml. Il y a 4 methodes :
- CreateChannel() qui permet de creer un channel avec son propre id
- DeleteItem() qui permet d'effacer un channel existant
- CreateItem() qui cree un nouvel item dans un channel existant
- DeleteItem() qui permet d'effacer les items d'un channel (avec possibilite de selection de ceux conserver)

Une autre fonction est XMLReader() qui renvoi le contenu d'un fichier (peut etre utile dans certains cas).
La classe cree automatiquement le fichier si il n'existe pas.

Source / Exemple :


<?php
/*
	|----------|
	|Modele RSS|
	|----------|
	
	<?xml version="1.0" encoding="iso-8859-1"?>
	<rss version="2.0">
		<channel id="">
			<description></description>
			<title></title>
			<link></link>
			<language></language>
			<webMaster></webMaster>
			<copyright></copyright>
			<item>
				<title></title>
				<link></link>
				<pubDate></pubDate>
				<description></description>
				<author></author>
			</item>
		</channel>
	</rss>
	
	Nom du code : CRss v 1.1
	Auteur : IoNAce (allias jean84)
	Mail : ionace@c4.fr
	Type de code : Classe permettant la creation d'un fichier rss (format xml) avec mise a jour dynamique du fichier
	Version php : 5 
	Remerciements : A Malalam (admin de CS) qui m'a beaucoup aide grace a ses reponses toujours pertinentes
	
	NOTE : Toutes les fonctions ( sauf XMLReader() ) renvoient la valeur NO_ERROR en cas de succees.
	Sinon, elles renvoient une valeur du tableau $TableOfErrors.

  • /
class CRss { /********************************************************************************/ /* Permet a la classe de connaitre le nom du fichier XML sur lequel travailler */ /********************************************************************************/ private $NameOfXML; /********************************************************************/ /* Permet a la classe de n'ouvrir qu'une seul fois le document XML */ /********************************************************************/ private $Handle; /********************************************************************************************/ /* Tableau contenan toutes les erreurs poivant intervenir durant l'utilisation de la classe */ /********************************************************************************************/ private $TableOfErrors = array( 'NO_XML_FILE', // Appel du constructeur invalide : fichier XML manquant 'CANOT_OPEN_FILE', // Impossible d'ouvrir le fichier specifie 'CANOT_READ_FILE', // Impossible de lire le fcihier specifie 'CHAN_ID_ALLREADY_USED', // L'ID choisi est deja utilise par un autre canal 'NO_CHAN_FOR_THIS_ID', // Aucun canal ne correspond a cet ID 'NO_VALIDATE_RSS_DOCUMENT', // Le document ne contient aucune balise RSS (document non-valide) 'NO_ERROR' // Pas d'erreur ); /************************************************************************************/ /* Constructeur de la classe */ /* Param 1 = $FileXML */ /* [-> Nom du fichier XML a charger. Si le fichier n'existe pas, il sera cree. */ /************************************************************************************/ function __construct($FileXML='') { // Verification if ( empty($FileXML) ) ReturnLastError(0); // On desactive le rapport d'erreur error_reporting(0); // On sauvegarde le nom du fichier en cas de besoin $this->NameOfXML = $FileXML; // Creation d'un nouvel Handle $this->Handle = new DOMDocument('1.0', 'iso-8859-1'); // Si le fichier n'existe pas, on le cree if ( !file_exists($FileXML) ) $this->CreateXMLRSS(); else $this->Handle->load($FileXML); } /****************************************************************************************************************/ /* Creer un fichier RSS avec XML */ /* Aucun param. */ /* [-> Cette fonction cree une balise racine <rss version="2.0"> et sauvegarde le resultat dans un fichier */ /****************************************************************************************************************/ private function CreateXMLRSS() { $HandleXML = $this->Handle; // Creation du noeud racine <rss version="2.0"></racine> $Racine = $HandleXML->createElement('rss'); $Racine->setAttribute('version', '2.0'); $Racine = $HandleXML->appendChild($Racine); // On sauvegarde le fichier $HandleXML->save($this->NameOfXML); } /********************************/ /* Renvoi une date preformatte. */ /* Aucun argument. */ /********************************/ private function GetDateToday() { $TableJour = array('dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'); $TableMois = array('janvier', 'fevrier', 'mars', 'avril', 'mai', 'juin', 'juillet', 'aout', 'septembre', 'octobre', 'novembre', 'decembre'); return $TableJour[date('w')].' '.date('j').' '.$TableMois[date('n')-1].' - '.date('H:i'); } /************************************************/ /* Lit le fichier XML et renvoi son contenu */ /* Aucun param */ /************************************************/ public function XMLReader() { // On ouvre le fichier en lecture $File = fopen($this->NameOfXML, 'rb'); if ( $File === FALSE ) return $TableOfErrors[1]; // On obtient la taille en nombre de caracteres du fichier XML $SizeOfFile = filesize($this->NameOfXML); // Mise en memoire du contenu $Buffer = fread($File, $SizeOfFile); if ( $Buffer === FALSE ) return $TableOfErrors[2]; // On referme le fichier fclose($File); // On renvoi ce que l'on vient de lire return $Buffer; } /************************************************************************/ /* Cree un nouveau canal RSS */ /* Param 1 = $ID */ /* [-> ID propre a ce canal. Doit etre unique pour chaque canal ! */ /* Param 2 = $Description */ /* [-> String permettant de decrire le contenu du canal */ /* Param 3 = $Title */ /* [-> Titre du canal */ /* Param 4 = $Link */ /* [-> Lien vers le site publiant le fichier RSS */ /* Param 5 = $Language */ /* [-> Langue du canal */ /* Param 6 = $MailWebmaster */ /* [-> E-mail du webmaster publiant le fichier RSS */ /* Param 7 = $Copyright */ /* [-> Copyright applique au contenu du fichier RSS */ /************************************************************************/ public function CreateChannel($ID='', $Description='', $Title='', $Link='', $Language='', $MailWebmaster='', $Copyright='') { // Recupere la Handle transmis par la classe $HandleXML = $this->Handle; // Verification $XPath = new DOMXPath($HandleXML); $Value = $XPath->query('/rss[@version="2.0"]/channel[@id="'.$ID.'"]'); // Si un channel existe deja avec l'id voulue, la requete XPath renverra un domnodelist contenant des liens (item) // vers des domnodes. Si ce n'est pas le cas, c'ets quie le channel en question n'existe pas donc on eut le creer // sans probleme if ( empty($Value->item(0)->nodeValue) ) { // --> On se place sur le noeud racine <rss> $Rss = $HandleXML->getElementsByTagName('rss')->item(0); // --> On cree l'element <channel> enfant de rss $ChannelElement = $HandleXML->createElement('channel'); $ChannelElement->setAttribute('id', $ID); $ChannelElement = $Rss->appendChild($ChannelElement); // On cree toutes les balises filles de <channel>. Ici <description> $DescriptionElement = $HandleXML->createElement('description'); $DescriptionElement = $ChannelElement->appendChild($DescriptionElement); $DescriptionValue = $HandleXML->createTextNode($Description); $DescritpionValue = $DescriptionElement->appendChild($DescriptionValue); // <title> $TitleElement = $HandleXML->createElement('title'); $TitleElement = $ChannelElement->appendChild($TitleElement); $TitleValue = $HandleXML->createTextNode($Title); $TitleValue = $TitleElement->appendChild($TitleValue); // <link> $LinkElement = $HandleXML->createElement('link'); $LinkElement = $ChannelElement->appendChild($LinkElement); $LinkValue = $HandleXML->createTextNode($Link); $LinkValue = $LinkElement->appendChild($LinkValue); // <language> $LanguageElement = $HandleXML->createElement('language'); $LanguageElement = $ChannelElement->appendChild($LanguageElement); $LanguageValue = $HandleXML->createTextNode($Language); $LanguageValue = $LanguageElement->appendChild($LanguageValue); // <webMaster> $MailWebmasterElement = $HandleXML->createElement('webMaster'); $MailWebmasterElement = $ChannelElement->appendChild($MailWebmasterElement); $MailWebmasterValue = $HandleXML->createTextNode($MailWebmaster); $MailWebmasterValue = $MailWebmasterElement->appendChild($MailWebmasterValue); // <copyright> $CopyrightElement = $HandleXML->createElement('copyright'); $CopyrightElement = $ChannelElement->appendChild($CopyrightElement); $CopyrightValue = $HandleXML->createTextNode($Copyright); $CopyrightValue = $CopyrightElement->appendChild($CopyrightValue); // <-- Grace aux balises ajoutees, <channel> se ferme ici (</channel>) automatiquement // <-- Pareille pour la balise <rss> qui prend fin ici // Sauvegarde $HandleXML->save($this->NameOfXML); // Pas d'erreur return $TableOfErrors[6]; } else { return $TableOfErrors[3]; } } /****************************************/ /* Efface un canal RSS grace a son id */ /* Param 1 = $ID */ /* [-> ID du canal a effacer. */ /****************************************/ public function DeleteChannel($ID='') { // Recupere le Handle fournis par la classe $HandleXML = $this->Handle; $XPath = new DOMXPath($HandleXML); // Recupere rss $Rss = $HandleXML->getElementsByTagName('rss'); // On verifie que le noeud n'est pas vide if ( is_object($Rss->item(0)) ) { // On ne prend que le premier groupe de balise (si jamais il y a plusieurs balise rss, elles seront ignores) $Rss = $Rss->item(0); // Requete XPath pour recuperer les enfants de rss valide $Element = $XPath->query('/rss[@version="2.0"]/channel[@id="'.$ID.'"]'); // On verifie que le noeud Element n'est pas vide if ( empty($Element->item(0)->nodeValue) === false ) { // Parcours des enfants de l'element obtenu foreach ( $Element as $Index => $Value ) { // On detruit chaque enfant du noeud en cours $Rss->removeChild($Value); } // Sauvegarde du traitement (on suppose qu'il y a eu des modifications si on a atteri ici) $HandleXML->save($this->NameOfXML); // Pas d'erreur return $TableOfErrors[6]; } else { return $TableOfErrors[4]; } } else { return $TableOfErrors[5]; } } /****************************************************************/ /* Function permettant de creer un nouvel item dans un canal */ /* Param 1 = $IDSource */ /* [-> ID de l'element channel parent de l'item */ /* Param 2 = $Title */ /* [-> Titre du nouvel item */ /* Param 3 = $Link */ /* [-> Lien vers l'article correspondant a l'item */ /* Param 4 = $Description */ /* [-> Descriptif de l'item */ /* Param 5 = $MailAuthor */ /* [-> E-mail de l'autheur de l'article */ /****************************************************************/ public function CreateItem($IDChan='', $Title='', $Link='', $Description='', $MailAuthor='') { // Recupere le Handle fournis par la classe $HandleXML = $this->Handle; // Expression XPath recuperant l'id du channel concerne $XPath = new DOMXPath($HandleXML); $XQuery = '/rss[@version="2.0"]/channel[@id="'.$IDChan.'"]'; $ChannelElement = $XPath->query($XQuery)->item(0); // Verifie si $ChannelElement est un objet renvoye par DOMNodeList->item(). Sinon c'est que le chan n'existe pas if ( is_object($ChannelElement) ) { // --> Balise <item> $Item = $HandleXML->createElement('item'); $Item = $ChannelElement->appendChild($Item); // Creation de la balise <title> $TitleElement = $HandleXML->createElement('title'); $TitleElement = $Item->appendChild($TitleElement); $TitleValue = $HandleXML->createTextNode($Title); $TitleValue = $TitleElement->appendCHild($TitleValue); // Creation de la balise <link> $LinkElement = $HandleXML->createElement('link'); $LinkElement = $Item->appendChild($LinkElement); $LinkValue = $HandleXML->createTextNode($Link); $LinkValue = $LinkElement->appendChild($LinkValue); // creation de la balise <pubDate> $DateElement = $HandleXML->createELement('pubDate'); $DateElement = $Item->appendChild($DateElement); $DateValue = $HandleXML->createTextNode(ucfirst($this->GetDateToDay())); $DateValue = $DateElement->appendChild($DateValue); // Creation de la balise <description> $DescritpionElement = $HandleXML->createElement('description'); $DescriptionElement = $Item->appendChild($DescritpionElement); $DescriptionValue = $HandleXML->createTextNode($Description); $DescriptionValue = $DescriptionElement->appendChild($DescriptionValue); // Creation de la balise <author> $AuthorElement = $HandleXML->createElement('author'); $AuthorElement = $Item->appendChild($AuthorElement); $AuthorValue = $HandleXML->createTextNode($MailAuthor); $AutorValue = $AuthorElement->appendChild($AuthorValue); // <-- Fin de la balise <item> // Sauvegarde $HandleXML->save($this->NameOfXML); // Pas d'erreur return $TableOfErrors[6]; } else { return $TableOfErrors[4]; } } /********************************************************************/ /* Vide tous les items d'un channel */ /* Param 1 = $IDChannel */ /* [-> ID du canal a vider */ /* Param 2 = $TableOfExeption */ /* [-> Tableau contenant les titres des items a ne pas effacer */ /********************************************************************/ public function DeleteItem($IDChannel='', $TableOfExeption='') { // Recupere le Handle fournis par la classe $HandleXML = $this->Handle; // Indque si le $TableOfExeption est vide ou non if ( empty($TableOfExeption) ) $MakeExeption = false; else $MakeExeption = true; // Expression XPath recuperant l'id du channel concerne $XPath = new DOMXPath($HandleXML); $XQuery = '/rss[@version="2.0"]/channel[@id="'.$IDChannel.'"]'; $ChannelElement = $XPath->query($XQuery)->item(0); // Verifie si $ChannelElement est un objet renvoye par DOMNodeList->item(). // Si ce n'est pas le cas, c'est que le chan n'existe pas if ( is_object($ChannelElement) ) { // Expression recuperant toutes les balises item de la balise channel concerne $XQuery = '/rss[@version="2.0"]/channel[@id="'.$IDChannel.'"]/item'; $ItemElements = $XPath->query($XQuery); // on efface toutes les node <item> du channel foreach ( $ItemElements as $Node ) { // Permet de savoir si on doit effacer l'item ou pas $DeleteItem = true; // Si un tableau d'exeption a ete transmis, on verifie les enfants de l'item en cours pour recherchee les exeptions // Sinon, on efface directement sans chercher a comprendre :P if ( $MakeExeption ) { // Verifie que le titre de l'item en cours d'effacement n'est pas dans le tableau d'exeption. // Si c'est le cas, on ne l'efface pas $TilteElement = $Node->childNodes; // Parcours de tous les enfants foreach ( $TilteElement as $ChildNodeOfTitle ) { // Si on tombe sur la balise titre if ( $ChildNodeOfTitle->nodeName == 'title' ) { // On verifie si elle est dans le tableau d'exeption if ( in_array($ChildNodeOfTitle->nodeValue, $TableOfExeption) ) $DeleteItem = false; // On arrete la boucle car on a trouve ce que l'on cherchait break; } } } // Apres parcours des elements, si l'item a ete identife et doit etre sauvegarde, on ne fais rien. // Sinon, on supprime if ( $DeleteItem ) $ChannelElement->removeChild($Node); } // Sauvegarde $HandleXML->save($this->NameOfXML); // Pas d'erreur return $TableOfErrors[6]; } else { return $TableOfErrors[4]; } } } ?>

Conclusion :


Petite info sur la fonction DeleteItem() :
Cette fonction attend comme argument un tableau qui contient tous les titres des items a ne pas effacer. Il est possible en quelques secondes de changer le profil de recherche et de ne selectionner que les dates par exemple. J'ai choisi les titres car je n'etais pas sur de la syntaxe a utiliser pour les dates (y en a tellement de differents sur les exemples que j'ai pu voir que j'ai choisi une facon de faire arbitraire). Si vous souhaitez modifier cette syntaxe, il suffit tout simplement de modifier la fonction GetDateToday(), la classe fait appel a elle automatiquement lorsqu'elle en a besoin.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.