Page 1 sur 2

class RSS

Posté : 01 nov. 2005, 12:49
par jeff
salut
je recommence un nouveau post car celui sur le salon php et celui sur ce salon ne m'ont pas amener au bout de mes esperance(malgres des reponces pertinantes)
De plus le fait de detaché un sujet sur le salon php a peut etre contribuer a embrouiller la chose

mon but est de realiser une classe rss avec laquelle on peut construire facilement des fil rss 0.91 et 2 ansi que atom1.0, la construction est basé sur le systeme de template SMARTY
et je voudrai etablir une verifictaion simple sur les elments obligatoires de ces flux(c'est a dire la presence des balise et le fait quelle ne soit pas vide)

voici l'etat actuelle du projet
une classe abstraite
<?php
abstract class abstractrss
{ 	
	/**
	 * converti un tableau en données exploitable pour le template
	 *
	 * @param string $name
	 * 
	 * @param string $value
	 */
	private function ArrayTitleLinkDesc($name,$value)
	{
		$arr='';
		foreach($value as $key=>$val)
		{
			$arr[$key]=htmlspecialchars($val);
		}
		$this->return[$name][]=$arr;		
	}
	
	private function verifelements()
	{
		try
		{
			foreach ($this->obli as $key=>$value)
			{
				/*if(is_array($value))
				{
					if(array_key_exists($key,$this->return))
					//$this->verifelements($value);
					{
						//$essai=array_values($key);
						echo $essai;
						echo 'cle :'.$key.' valeur :'.print_r($value)."<br/>";
						foreach ($value as $cle=>$val)
						{
							echo 'cle-1 '.$cle.' valeur-1'.$val.'<br/>';
							foreach ($this->return[$key] as $clef=>$val1 )
							{
								echo '<strong>clef:'.$clef.'- valeur'.print_r($val1).'</strong><br/>';
								echo $this->return[$key][$clef];
							}
							//echo 'variable return'.print_r($this->return[$key][$cle]).'<br/>';
							//if(empty($this->return[$value]))	
							//$tab[$value][$cle]['statut']='vide';	
						}
					}
					else 
						$tab[$key]='manque';
				}
				else 
				{*/
					if(array_key_exists($value,$this->return))
					{	
						if(empty($this->return[$value]))	
							$tab[$value]['statut']='vide';//throw  new MyException('la valeur est vide'.$this->return[$value]);
					}
					else
					{
						//echo 'else'.$value;
						$tab[$value]='manque';//throw new MyException('il manque le champs '.$value);
					}
						
			}
		}
		catch(MyException $e)
		{
			$e->exceptionlog();
		}
		return $tab;
	}
	
	public function __set($name,$value)
	{
		try 
		{
			if(is_string($value))
				$this->return[$name]=htmlspecialchars($value);
			elseif(is_numeric($value))
				$this->valeurs[$name]=$value;
			elseif(is_array($value))
			{
				$this->ArrayTitleLinkDesc($name,$value);
			}
			elseif(is_bool($value))
				$this->valeurs[$name]=$value;
			else 
				throw new MyException('type non attendu');
		}
		catch (MyException $e)
		{
			$e->exceptionlog();
		}
	}
	
	

	
	public function __get($name)
	{
		return	$this->valeurs[$name];
	}
	
	public function send() 
	{
            header("Content-Type: application/xml");
            header("Content-Transfer-Encoding: binary");
            header("Expires: 0");
	}
	
	/**
	 * methode de creation du fichier xml
	 *
	 */
	public function createrss2()
	{	
		print_r($this->verifelements($this->obli));
		//print_r($this->return);
		$path='/../Smarty/libs/Smarty.class.php';
		require_once(dirname(__FILE__).$path);
		include 'E:/wamp/www/projet_ing/configSmarty.php';
		$Smarty = new Smarty_page();
		$Smarty->assign($this->return);
		$this->content=$Smarty->fetch($this->tpl);
		assert(is_string($this->content));
		$xml=new DOMDocument();
     	try
     	{
     		if(strtolower($this->encoding)==='utf')
     			$this->content=utf8_encode($this->content);
     		if(!$xml->loadXML($this->content))
     			throw new DomException('impossible de charger le fichier :'.$this->content);
     		else 
     		{
     			if(!$xml->validate())
     				throw new DomException('document non valide'.$this->content);
     			else 
     			{
     				if(!$xml->save($this->file))
     					throw new DomException('Erreur pendant l\'ecriture du fichier:'.$this->file);
     			}
     		}
     	}
     	catch (DomException $e)
     	{
     		echo $e->getMessage().'<br/>';
     		echo $e->getCode().'<br/>';
     		
     	}
	}
	
	/**
	 * ajoute un item et son contenu
	 *
	 */
	public function __call($nom,$valeur)
	{
		switch($nom)
		{
			case 'add':
			$xml = new DomDocument();
			$xml->load($this->file);
			$xml->documentElement;
			foreach ($xml->childNodes as $node)
			{
				if($node->nodeName==="item")
				{
					$nd=$node->appendSibling('item');
					break;
				}
			}
			$nb=sizeof($arr);
			for($i=0;$i<=$nb;$i++)
			{
				foreach ($arr as $key=>$val)
				{
					$key=$nd->appendChidl('key');
					$key->nodeValue=$val;
				}
			}
			break;
			
			case 'del':break;
			default:
			echo 'methode '.$nom.' non connue';
			break;
		}
	}
	
	public function add_item($arr)
	{
		$xml = new DomDocument();
		$xml->load($this->file);
		$xml->documentElement;
		foreach ($xml->childNodes as $node)
		{
			if($node->nodeName==="item")
			{
				$nd=$node->appendSibling('item');
				break;
			}
		}
		$nb=sizeof($arr);
		for($i=0;$i<=$nb;$i++)
		{
			foreach ($arr as $key=>$val)
			{
				$key=$nd->appendChidl('key');
				$key->nodeValue=$val;
			}
		}
		
		/*
		$link=$nd->appendChild('link');
		$link->nodeValue=$this->return['item'][0]['link'];
		$desc=$nd->appendChild('description');
		$desc->nodeValue=$this->return['item'][0]['descption'];*/
	}
	
	/**
	 * delete un item
	 *
	 */
	public function delete_item($arr)
	{
		$xml = new DomDocument();
		$xml->load($this->file);
		$xml->documentElement;
		foreach ($xml->childNodes as $node)
		{
			if($nb=$node->nodeName==="item")
			{
				$nd->nodeValue=$this->return['item'];
				break;
			}
		}
	}
}
?>
la methode de verification est en court de developpement et pour cause je n'arrive pas a la faire(je n'arrive pas a comparer les deux tableau $this->return et $this->obli

je voudrai inclure egalement des methode de manipulation comme ajouter un item ou en supprimer un

la classe rss2
<?php
class rss2_ab extends abstractrss 
{	
	/**
	 * valeurs retourner a samrty pour la cnstruction du template
	 *
	 * @protected array
	 */
	protected $return;
	/**
	 * valeurs recuperer par la methode set
	 *
	 * @protected array
	 */
	protected $valeurs;
	/**
	 * nom du fichier a sauver
	 *
	 * @protected string
	 */
	protected $file;
	/**
	 * template utiliser pour generer le document
	 *
	 * @protected string
	 */
	protected $tpl;
	/**
	 * chaine recuperer a partir de smarty
	 *
	 * @protected string
	 */
	protected  $content;
	/**
	 * tableau defininissant les variables a tester
	 *
	 * @var unknown_type
	 */
	protected $obli;
	
	
	/**
	 * constructeur de classe
	 *
	 */
	public function __construct()
	{	
		$this->valeurs=array();
		$this->obli=array('channel'=>array('title', 'link', 'description'), 'item'=>array('title', 'link', 'description'), 'image'=>array('title', 'link', 'description'), 'version', 'encoding', 'description');
		$this->return=array();
		$this->file='RSS/actu.xml';		
		$this->tpl='rss/actu_rss2.tpl';	
	}
}
?>
le template

Code : Tout sélectionner

<?xml version="1.0" encoding="{$encoding}" ?> {if !empty($xslt)} <?xml-stylesheet href="{$xslt}" type="text/xsl"?> {/if} <rss version="{$version}"> <channel> <title>{$channel.title}</title> <link>{$channel.link}</link> <description>{$channel.description.0}</description> <language>{$lang}</language> {if !empty($copyright)} <copyright>{$copyright}</copyright> {/if} {if !empty($lastBuildDate)} <lastBuildDate>{$lastBuildDate}</lastBuildDate> {/if} {if !empty($creator)} <generator>{$creator}</generator> {/if} {foreach from=$item item=item key=key name=item1} <item> <title>{$item.title}</title> <link>{$item.link}</link> <description>{$item.description}</description> {if !empty($image_item)} <image> <url>$item.image_item.url</url> <title>$item.image_item.title</title> <link>$item.image_item.link</link> <width>$item.image_item.width</width> <height>$item.image_item.height</height> </image> {/if} </item> {/foreach} </channel> </rss>

et l'utilisation de l'usine a gaz
$mysql=new Mysqldb(SERVEUR,LOGIN,PASS,BASE);
$dao=new DAO($mysql);
$rss=new rss2_ab();
//$rss->send();
$champs=array('date', 'description', 'titre', 'id_a');
$table=array('actu');
$dao->SetVar($table,$champs);
foreach($dao->Select('','Limit 0,4') as $cle=>$tab)
{
    $rss->item=array('title'=>$tab[2], 'description'=>$tab[1], 'link'=>'http://localhost/projet_ing/index.php?module=actu&action=display&id='.$tab[3]);
}
//$rss->Channel=array('title'=>'essai','description'=>'premier test', 'link'=>'http://localhost/projet_ing/', 'date'=>date("d/m/Y-H:i:s"));
$rss->encoding='utf-8';
$rss->lang='fr';
//$rss->lastBuildDate=date('d M Y  H:i');
$rss->createrss2();
//$rss->send();
//echo $rss->content;
?>
donc j'aimerai avoir vos remarque ainsi qu'un petit coup de pouce pour finir cette classe(cat moi je vais avoir de moins en moins de temps a lui consacrer)

voila

merci

Posté : 01 nov. 2005, 13:48
par Liquid
Un document RSS est un document XML et un document XML peut avoir une DTD. DOMDocument->validate() permet de valider un document XML :idea:

Je n'ai pas testé mais il semblerait qu'on puisse capturer les erreurs, voir exemple ici : http://fr2.php.net/manual/fr/function.d ... lidate.php

Posté : 01 nov. 2005, 13:51
par jeff
ouai c'est une question que je me suis posée, mias je l'ai pas encore tester
j'ai trouver des DTD pour 0.91 mais pour 2.0
donc si ca fonction cela pourrai resoudre un de mes problemes

Posté : 01 nov. 2005, 13:55
par Liquid

Posté : 01 nov. 2005, 13:59
par jeff
merci

je n'y connais rien mais une DTD decrit les elements que le "l'interprteur" peut trouver mais il ne garantie pas la presence de ces elements dans le document??

a moin que ce soit c'est ligne la

Code : Tout sélectionner

<!ELEMENT item ((title|description)+,link?,

Posté : 01 nov. 2005, 14:02
par Liquid
Que si ! Une DTD peut être très précise. Tu peux rendre obligatoire ou optionnel des éléments, des attributs, typer les données etc

http://www.w3schools.com/dtd/default.asp

Posté : 01 nov. 2005, 14:06
par jeff
donc il faut que je detecte si en plus le docment comporte du html pour ecrire la bonne dtd
je te remercie de ces infos j'avais regarder sur journaldunet mais leurs articles ne sont pas fini sur le dtd

Posté : 01 nov. 2005, 14:34
par Liquid
Quelle est ta demande en fait, même en lisant ton autre sujet j'ai du mal à la saisir ?

Je ne connais pas plus que toi les spécifications RSS, mais s'il y en a c'est que RSS doit être standardisé et que les DTD des différentes versions doivent être fournies par un tiers, le W3C apparemment. Tu n'as donc pas à écrire de DTD. D'autant qu'il existe des readers et que ces lecteurs de RSS doivent bien se reposer sur des règles (les DTD) pour valider et exploiter le contenu des RSS.

Si tu récupères des RSS, pour moi il n'y a pas grand chose à faire en PHP, juste charger le document et le valider. MAIS en regardant plusieurs documents RSS on remarque qu'il n'y a aucune référence à une DTD ! Normalement une DTD est interne ou un "lien" y fait référence. Le plus simple si on veut utiliser la validation par DTD est de faire une copie du RSS (c'est pas un jeu de mots :) ), et d'écrire une ligne là où il faut pour faire référence à la DTD, fermer le fichier puis valider la copie avec DOMDocument. Je trouve louche qu'il n'y ait pas de DTD dans un RSS !

Si tu veux générer des RSS avec PHP et une base de données par exemple alors il faut effectivement connaître les contraintes de la DTD pour écrire le code générateur de RSS. Si la DTD de référence change (nouvelle version) il faudra "réécrire" le générateur ! A toi de trouver la meilleure solution pour rendre ces évolutions digérables !

Les sources de données sont vraiment une plaie pour le programmeur :!:

Posté : 01 nov. 2005, 14:35
par Liquid
Au fait ce qui me fait mal comprendre ta demande c'est que tu parles de HTML ??!! Quel rapport direct avec un document RSS et sa DTD ?

Posté : 01 nov. 2005, 14:39
par jeff
ba dans la balise description appraement on peut mettre du html
donc il faut je crois une DTD en rapport avec XML et le rss et un ajout pour HTML si le document en contient

ex trouve de DTD

Code : Tout sélectionner

<!DOCTYPE rdf:RDF [ <!ENTITY % HTMLlat1 PUBLIC "-//W3C//ENTITIES Latin 1 for XHTML//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"> %HTMLlat1; ]>

Posté : 02 nov. 2005, 13:52
par jeff
je me demand un truc dans la plupart des fils rss que j'ai trouver, tres souvent il n'y pas de doctype
question est ce que je pourrai pas en cree de simplifier pour tester la validiter de mes document sans l'inclure au final dans ceux-ci :?:

Posté : 02 nov. 2005, 16:55
par Liquid
C'est ce que je proposais. Je ne sais pas si un document RSS peut avoir une DTD (interne ou liée). Si c'est le cas rien ne t'empêche d'insérer la déclaration DOCTYPE puis de valider. S'il ne faut pas de DTD explicite, tu fais la même chose sur une copie, la copie valide alors l'originale l'est aussi.

Posté : 02 nov. 2005, 18:40
par jeff
cette idee me plait bien
merci

Posté : 03 nov. 2005, 17:42
par christophe
Bonjour,

Peut-être ceci peut t'aider http://www.bitfolge.de/rsscreator-en.html

Posté : 03 nov. 2005, 17:50
par rami
Je suis tombé sur ceci par hasard. Ca peut peut-être t'aider ;)