diff --git a/Tests/rssTest.php b/Tests/rssTest.php new file mode 100644 index 0000000..f9c1839 --- /dev/null +++ b/Tests/rssTest.php @@ -0,0 +1,148 @@ +expectException ("Exception", "No title is provided for this RSS"); + $rss = new rss (); + $res = $rss->asXML (); + } + + public function test_functional1 () + { + // Functionnal 1 + $rss = new rss (); + $rss->title ("Global Title") + ->link ("http://localhost") + ->language ("fr-fr") + ->description ("The Super Global Description"); + $rss->addItem ()->title ("Item1 Title") + ->link ("http://Item1Link") + ->description ("Item1 Description"); + $rss->addItem ()->title ("Item2 Title") + ->pubDate ("2017-04-13 12:25:30") + ->link ("http://Item2Link") + ->description ("Item2 Description"); + $res = $rss->asXML (); + $this->assertSame ($res, " + + + Global Title + http://localhost + The Super Global Description + fr-fr + + Item1 Title + http://Item1Link + Item1 Description + + + Item2 Title + http://Item2Link + Item2 Description + Thu, 13 Apr 2017 12:25:30 +0200 + + + +"); + } + + public function test_error1 () + { + // Missing global description + $this->expectException ("Exception", + "No description is provided for this RSS"); + $rss = new rss (); + $rss->title ("Global Title") + ->link ("http://localhost") + ->language ("fr-fr"); + $res = $rss->asXML (); + } + + public function test_error2 () + { + // Missing global link + $this->expectException ("Exception", "No link is provided for this RSS"); + $rss = new rss (); + $rss->title ("Global Title") + ->language ("fr-fr") + ->description ("The Super Global Description"); + $res = $rss->asXML (); + } + + public function test_error3 () + { + // Missing global title + $this->expectException ("Exception", "No title is provided for this RSS"); + $rss = new rss (); + $rss->link ("http://localhost") + ->language ("fr-fr") + ->description ("The Super Global Description"); + $res = $rss->asXML (); + } + + public function test_error4 () + { + // Invalid date provided + $this->expectException ("Exception", + "lastBuildDate provided to RSS is not a valid date"); + $rss = new rss (); + $rss->title ("Global Title") + ->link ("http://localhost") + ->lastBuildDate ("2017-04-33") + ->language ("fr-fr") + ->description ("The Super Global Description"); + $res = $rss->asXML (); + } + + public function test_itemError1 () + { + // Empty Item provided + $this->expectException ("Exception", + "No title nor description defined in the RSS item"); + $rss = new rss (); + $rss->title ("Global Title") + ->link ("http://localhost") + ->lastBuildDate ("2017-04-30 12:35:32") + ->language ("fr-fr") + ->description ("The Super Global Description"); + $rss->addItem (); + $res = $rss->asXML (); + } + + public function test_itemError2 () + { + // Item without Title and Description + $this->expectException ("Exception", + "No title nor description defined in the RSS item"); + $rss = new rss (); + $rss->title ("Global Title") + ->link ("http://localhost") + ->lastBuildDate ("2017-04-30 12:35:32") + ->language ("fr-fr") + ->description ("The Super Global Description"); + $rss->addItem ()->link ("http://localhost/link"); + $res = $rss->asXML (); + } + + public function test_itemError3 () + { + // Item with invalid date + $this->expectException ("Exception", + "pubDate provided to RSS Item is not a valid date"); + $rss = new rss (); + $rss->title ("Global Title") + ->link ("http://localhost") + ->lastBuildDate ("2017-10-30 12:35:32") + ->language ("fr-fr") + ->description ("The Super Global Description"); + $rss->addItem ()->title ("Item title") + ->pubDate ("2017-14-33 12:32:32"); + $res = $rss->asXML (); + } +} diff --git a/rss.php b/rss.php new file mode 100644 index 0000000..3b71e4c --- /dev/null +++ b/rss.php @@ -0,0 +1,353 @@ + */ + +error_reporting (E_ALL); +require_once ("domframework/verify.php"); +require_once ("domframework/convert.php"); + +/** Create the RSS pages for the websites + * Specification http://www.rssboard.org/rss-specification + */ +class rss +{ + /** The title of the site (MANDATORY) + */ + private $title; + + /** The link (URL) to the site (MANDATORY) + */ + private $link; + + /** The Description of the site (MANDATORY) + */ + private $description; + + /** The language of the feed + */ + private $language; + + /** The lastBuildDate + */ + private $lastBuildDate; + + /** The items linked to this RSS + */ + private $items = array (); + + /** Get/Set the value + * @param string|null $title The title to get/set + */ + public function title ($title = null) + { + if ($title === null) + return $this->title; + if (! is_string ($title)) + throw new \Exception ("Title provided to RSS is not a string", 500); + if ($title === "") + $title = null; + $this->title = $title; + return $this; + } + + /** Get/Set the value + * @param string|null $link The link to get/set + */ + public function link ($link = null) + { + if ($link === null) + return $this->link; + if (! is_string ($link)) + throw new \Exception ("Link provided to RSS is not a string", 500); + $verify = new \verify (); + if (! $verify->is_URL ($link)) + throw new \Exception ("Link provided to RSS is not an URL", 500); + if ($link === "") + $link = null; + $this->link = $link; + return $this; + } + + /** Get/Set the value + * @param string|null $description The description to get/set + */ + public function description ($description = null) + { + if ($description === null) + return $this->description; + if (! is_string ($description)) + throw new \Exception ("Description provided to RSS is not a string", 500); + if ($description === "") + $description = null; + $this->description = $description; + return $this; + } + + /** Get/Set the value + * @param string|null $language The language to get/set + */ + public function language ($language = null) + { + if ($language === null) + return $this->language; + if (! is_string ($language)) + throw new \Exception ("Language provided to RSS is not a string", 500); + if (! in_array ($language, + array ("af", "sq", "eu", "be", "bg", "ca", "zh-cn", "zh-tw", "hr", "cs", + "da", "nl", "nl-be", "nl-nl", "en", "en-au", "en-bz", "en-ca", + "en-ie", "en-jm", "en-nz", "en-ph", "en-za", "en-tt", "en-gb", + "en-us", "en-zw", "et", "fo", "fi", "fr", "fr-be", "fr-ca", + "fr-fr", "fr-lu", "fr-mc", "fr-ch", "gl", "gd", "de", "de-at", + "de-de", "de-li", "de-lu", "de-ch", "el", "haw", "hu", "is", + "in", "ga", "it", "it-it", "it-ch", "ja", "ko", "mk", "no", "pl", + "pt", "pt-br", "pt-pt", "ro", "ro-mo", "ro-ro", "ru", "ru-mo", + "ru-ru", "sr", "sk", "sl", "es", "es-ar", "es-bo", "es-cl", + "es-co", "es-cr", "es-do", "es-ec", "es-sv", "es-gt", "es-hn", + "es-mx", "es-ni", "es-pa", "es-py", "es-pe", "es-pr", "es-es", + "es-uy", "es-ve", "sv", "sv-fi", "sv-se", "tr", "uk"))) + throw new \Exception ("Provided language for RSS is not allowed", 500); + if ($language === "") + $language = null; + $this->language = $language; + return $this; + } + + /** Get/Set the value + * The date must be in the SQL format Y-m-d H:i:s + * @param string|null $lastBuildDate The lastBuildDate to get/set + */ + public function lastBuildDate ($lastBuildDate = null) + { + if ($lastBuildDate === null) + return $this->lastBuildDate; + if (! is_string ($lastBuildDate)) + throw new \Exception ("lastBuildDate provided to RSS is not a string", + 500); + $verify = new \verify (); + if (! $verify->is_datetimeSQL ($lastBuildDate)) + throw new \Exception ("lastBuildDate provided to RSS is not a valid date", + 500); + if ($lastBuildDate === "") + $lastBuildDate = null; + else + $lastBuildDate = \convert::convertDate ($lastBuildDate, "Y-m-d H:i:s", + \DateTime::RFC2822); + $this->lastBuildDate = $lastBuildDate; + return $this; + } + + /** Add a new item to the RSS + * Return the new rss object created + */ + public function addItem () + { + $rss_item = new \rss_item (); + $this->items[] = $rss_item; + return $rss_item; + } + + /** Return the complete RSS in XML format + * Throw an exception if there is some mandatory fields missing + */ + public function asXML () + { + if ($this->title === null) + throw new \Exception ("No title is provided for this RSS", 500); + if ($this->link === null) + throw new \Exception ("No link is provided for this RSS", 500); + if ($this->description === null) + throw new \Exception ("No description is provided for this RSS", 500); + $xmlstr = + ''."\n". + ''."\n". + ' '."\n". + ' '."\n". + ''; + $xml = new \SimpleXMLElement ($xmlstr); + $xml->channel->title = $this->title; + $xml->channel->link = $this->link; + $xml->channel->description = $this->description; + if ($this->language !== null) + $xml->channel->language = $this->language; + if ($this->lastBuildDate !== null) + $xml->channel->lastBuildDate = $this->lastBuildDate; + foreach ($this->items as $item) + { + if ($item->title() === null && $item->description() === null) + throw new \Exception ( + "No title nor description defined in the RSS item", 500); + $tmpItem = $xml->channel->addChild ("item"); + if ($item->title () !== null) + $tmpItem->title = $item->title (); + if ($item->link () !== null) + $tmpItem->link = $item->link (); + if ($item->description () !== null) + $tmpItem->description = $item->description (); + if ($item->author () !== null) + $tmpItem->author = $item->author (); + if ($item->comments () !== null) + $tmpItem->comments = $item->comments (); + if ($item->guid () !== null) + $tmpItem->guid = $item->guid (); + if ($item->pubDate () !== null) + $tmpItem->pubDate = $item->pubDate (); + } + // Ident correctely the xml created in SimpleXML + $dom = new DOMDocument('1.0'); + $dom->preserveWhiteSpace = false; + $dom->formatOutput = true; + $dom->loadXML($xml->asXML()); + return $dom->saveXML(); + } +} + +/** Define one item in the RSS + */ +class rss_item +{ + /** The title of the item + */ + private $title; + + /** The URL of the item + */ + private $link; + + /** The item synopsis + */ + private $description; + + /** Email address of the author of the item + */ + private $author; + + /** URL of a page for comments relating to the item + */ + private $comments; + + /** A string that uniquely identifies the item + */ + private $guid; + + /** Indicates when the item was published + */ + private $pubDate; + + /** Get/Set the value + * @param string|null $title The title to get/set + */ + public function title ($title = null) + { + if ($title === null) + return $this->title; + if (! is_string ($title)) + throw new \Exception ("Title provided to RSS Item is not a string", 500); + if ($title === "") + $title = null; + $this->title = $title; + return $this; + } + + /** Get/Set the value + * @param string|null $link The link to get/set + */ + public function link ($link = null) + { + if ($link === null) + return $this->link; + if (! is_string ($link)) + throw new \Exception ("Link provided to RSS Item is not a string", 500); + $verify = new \verify (); + if (! $verify->is_URL ($link)) + throw new \Exception ("Link provided to RSS Item is not an URL", 500); + if ($link === "") + $link = null; + $this->link = $link; + return $this; + } + + /** Get/Set the value + * @param string|null $description The description to get/set + */ + public function description ($description = null) + { + if ($description === null) + return $this->description; + if (! is_string ($description)) + throw new \Exception ("Description provided to RSS Item is not a string", + 500); + if ($description === "") + $description = null; + $this->description = $description; + return $this; + } + + /** Get/Set the value + * @param string|null $author The author to get/set + */ + public function author ($author = null) + { + if ($author === null) + return $this->author; + if (! is_string ($author)) + throw new \Exception ("Author provided to RSS Item is not a string", 500); + if ($author === "") + $author = null; + $this->author = $author; + return $this; + } + + /** Get/Set the value + * @param string|null $comments The comments to get/set + */ + public function comments ($comments = null) + { + if ($comments === null) + return $this->comments; + if (! is_string ($comments)) + throw new \Exception ("Comments provided to RSS Item is not a string", + 500); + if ($comments === "") + $comments = null; + $this->comments = $comments; + return $this; + } + + /** Get/Set the value + * @param string|null $guid The guid to get/set + */ + public function guid ($guid = null) + { + if ($guid === null) + return $this->guid; + if (! is_string ($guid)) + throw new \Exception ("GUID provided to RSS Item is not a string", 500); + if ($guid === "") + $guid = null; + $this->guid = $guid; + return $this; + } + + /** Get/Set the value + * @param string|null $pubDate The pubDate to get/set + */ + public function pubDate ($pubDate = null) + { + if ($pubDate === null) + return $this->pubDate; + if (! is_string ($pubDate)) + throw new \Exception ("pubDate provided to RSS Item is not a string", + 500); + if (! \verify::staticIs_datetimeSQL ($pubDate)) + throw new \Exception ("pubDate provided to RSS Item is not a valid date", + 500); + if ($pubDate === "") + $pubDate = null; + else + $pubDate = \convert::convertDate ($pubDate, "Y-m-d H:i:s", + DateTime::RFC2822); + $this->pubDate = $pubDate; + return $this; + } +}