<?php

/**
 * adaptation en php de feedfinder.py :
 *
 * """Ultra-liberal feed finder, de Mark Pilgrim
 * <http://diveintomark.org/projects/feed_finder/>
 * Par: courcy.michael@wanadoo.fr
 *
 * adaptation en php, je ne reprends qu'une partie de cette algorithme
 *
 * 0) A chaque etape on verifie si les feed indiques sont reellement des feeds
 * 1) Si l'uri passe est un feed on retourne le resultat tout simplement
 * 2) Si le header de la page contient des balises LINK qui renvoient vers des feed on les retourne
 * 3) on cherche les liens <a> qui se termine par  ".rss", ".rdf", ".xml", ou ".atom"
 * 4) on cherche les liens <a> contenant "rss", "rdf", "xml", ou "atom"
 *
 * j'integre pas l'interrogation  avec xml_rpc de syndic8, mais on peut le faire assez facilement
 * dans la phase de test sur differentes url je n'ai constate aucune diffrerence entre les reponses
 * donnees par feedfinder.py et les miennes donc je ne suis pas sur de voir l'interet
 *
 * Je ne me preoccupe pas comme l'auteur de savoir si mes liens de feed sont sur le meme serveur ou pas
 *
 * exemple d'utilisation
 *
 * print_r (get_feed_from_url("http://willy.boerland.com/myblog/"));
 *
 * on obtient
 *
 * Array
 * (
 *   [0] => http://willy.boerland.com/myblog/atom/feed
 *   [1] => http://willy.boerland.com/myblog/blogapi/rsd
 *   [2] => http://willy.boerland.com/myblog/rss.xml
 *   [3] => http://willy.boerland.com/myblog/node/feed
 * )
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

$verif_complete = 0; // mettez le a 1 si vous voulez controler la validite des feed trouves mais le temps d'execution
// est alors plus long

/**
 * une fonction qui permet de si un lien est un feed ou nom,
 * si c'est un feed elle retourne son type, si c'est pas un feed elle retourne 0,
 * cette verification est évidemment très très légère
 *
 * @param string $url
 *    URL à analyser
 * @return string|0
 *    Retourne son type (rss|atom|rdf) ou 0 si pas feed
 */
function is_feed($url) {

	/**
	 * méthode SPIP
	 */
	if (function_exists('recuperer_url')) {
		$buffer = recuperer_url($url);
		$buffer = $buffer['page'] ?? '';
		if (preg_match('/<(\w*) .*/', $buffer, $matches)) {
			// ici on detecte la premiere balise
			$type_feed = $matches[1];
			switch ($type_feed) {
				case 'rss':
					return 'rss';
				case 'feed':
					return 'atom';
				case 'rdf':
					return 'rdf';
			}
		}

		return '';
	}

	$fp = @fopen($url, 'r');
	if (!$fp) {
		return 0;
	}
	// verifion la nature de ce fichier
	while (!feof($fp)) {
		$buffer = fgets($fp, 4096);
		if (preg_match('/<(\w*) .*/', $buffer, $matches)) {
			// ici on detecte la premiere balise
			$type_feed = $matches[1];
			switch ($type_feed) {
				case 'rss':
					fclose($fp);

					return 'rss';
				case 'feed':
					fclose($fp);

					return 'atom';
				case 'rdf':
					fclose($fp);

					return 'rdf';
				default:
					fclose($fp);

					return 0;
			}
		}
	}
}

/*test is_feed******************************
 * echo is_feed("https://contrib.spip.net/spip.php?page=backend" _EXTENSIO_PHP") . "<br />"; //retourne rss
 * echo is_feed("http://liberation.fr/rss.php") . "<br />"; //retourne rss
 * echo is_feed("http://liberation.fr/rss.php") . "<br />"; //retourne rss
 * echo is_feed("http://willy.boerland.com/myblog/atom/feed") //retourne atom
 * echo is_feed("http://spip.net/") . "<br />"; //retoune 0
 */

/**
 * fonction sans finesse mais efficace
 * on parcourt ligne par ligne a la recherche de balise <a> ou <link>
 * si dans le corps de celle-ci on trouve les mots rss, xml, atom ou rdf
 * alors on recupere la valeur href='<url>', on adapte celle-ci si elle
 * est relative et on verifie que c'est bien un feed si oui on l'ajoute
 * au tableau des feed si on ne trouve rien ou si aucun feed est trouve on retourne
 * un tableau vide
 *
 * @param string $url
 *    L'URL à analyser
 * @return array
 *    Le tableau des feed trouvés dans la page
 */
function get_feed_from_url($url, $buffer = false) {
	global $verif_complete;
	// j'ai prevenu ce sera pas fin
	if (!preg_match('/^https?:\/\/.*/', $url)) {
		$url = 'http://' . $url;
	}
	if (!$buffer) {
		$buffer = @file_get_contents($url);
	}

	include_spip('inc/filtres');

	$feed_list = [];
	// extraction des <link>
	if ($links = extraire_balises($buffer, 'link')) {
		// y a t-y rss atom rdf ou xml dans ces balises
		foreach ($links as $link) {
			if (
				(strpos($link, 'rss')
					|| strpos($link, 'rdf')
					|| strpos($link, 'atom')
					|| strpos($link, 'xml'))
				&&
				(!strpos($link, 'opensearch') && !strpos($link, 'oembed'))
			) {
				// voila un candidat on va extraire sa partie href et la placer dans notre tableau
				if ($href = extraire_attribut($link, 'href')) {
					// on aura pris soin de verifier si ce lien est relatif d'en faire un absolu
					$href = suivre_lien($url, $href);
					if (!$verif_complete or is_feed($href)) {
						$feed_list[] = $href;
					}
				}
			}
		}
	}
	// extraction des <a>
	if ($links = extraire_balises($buffer, 'a')) {
		// y a t-y rss atom rdf ou xml dans ces balises
		foreach ($links as $link) {
			if (
				(strpos($link, 'rss')
					|| strpos($link, 'rdf')
					|| strpos($link, 'atom')
					|| strpos($link, 'xml'))
				&&
				(!strpos($link, 'opensearch') && !strpos($link, 'oembed'))
			) {
				// voila un candidat on va extraire sa partie href et la placer dans notre tableau
				if ($href = extraire_attribut($link, 'href')) {
					// on aura pris soin de verifier si ce lien est relatif d'en faire un absolu
					$href = suivre_lien($url, $href);
					if (!$verif_complete or is_feed($href)) {
						$feed_list[] = $href;
					}
				}
			}
		}
	}

	// si c'est un site SPIP, tentons l'url connue
	if (
		!count($feed_list)
		and (
			strpos($url, 'spip') or stripos($buffer, 'spip')
		)
	) {
		$href = suivre_lien($url, 'spip.php?page=backend');
		if (is_feed($href)) {
			$feed_list[] = $href;
		}
	}

	return $feed_list;
}

/* getFeed ****************************
 * print_r (get_feed_from_url("contrib.spip.net"));
 * print_r (get_feed_from_url("http://liberation.fr/"));
 * print_r (get_feed_from_url("cnn.com"));
 * print_r (get_feed_from_url("http://willy.boerland.com/myblog/"));
 *****************************    Resultat *****************************************
 * Array
 * (
 * [0] => https://contrib.spip.net/backend.php
 * )
 * Array
 * (
 * [0] => http://www.liberation.fr/rss.php
 * )
 * Array
 * (
 * [0] => http://rss.cnn.com/rss/cnn_topstories.rss
 * [1] => http://rss.cnn.com/rss/cnn_latest.rss
 * [2] => http://www.cnn.com/services/rss/
 * [3] => http://www.cnn.com/services/rss/
 * [4] => http://www.cnn.com/services/rss/
 * )
 * Array
 * (
 * [0] => http://willy.boerland.com/myblog/atom/feed
 * [1] => http://willy.boerland.com/myblog/blogapi/rsd
 * [2] => http://willy.boerland.com/myblog/rss.xml
 * [3] => http://willy.boerland.com/myblog/node/feed
 * )
 */
