* @copyright (c) 2025, Robert Strutts * @license MIT */ namespace CodeHydrater; class rss_feed { public static function generate_rss_feed(array $root, array $items) { // Create the XML document $rss = new \DOMDocument('1.0', 'UTF-8'); $rss->formatOutput = true; // Create the RSS root element $rssElement = $rss->createElement('rss'); $rssElement->setAttribute('version', '2.0'); $rssElement->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom'); $rssRoot = $rss->appendChild($rssElement); // Create the channel element $channel = $rss->createElement('channel'); $channel = $rssRoot->appendChild($channel); // Add atom:link for self-reference $atomLink = $rss->createElement('atom:link'); $rss_feed_link = $root['feed_link'] ?? false; if ($rss_feed_link === false) { throw new \Exception("Unknown Feed Link"); } $atomLink->setAttribute('href', $rss_feed_link); $atomLink->setAttribute('rel', 'self'); $atomLink->setAttribute('type', 'application/rss+xml'); $channel->appendChild($atomLink); // Add required channel elements $title = $root["title"] ?? "News"; $channel->appendChild($rss->createElement('title', $title)); $site_link = $root["site_link"] ?? false; if ($site_link === false) { throw new \Exception("Unknown Site Link"); } $channel->appendChild($rss->createElement('link', $site_link)); $desc = $root["description"] ?? "Latest news from My Website"; $channel->appendChild($rss->createElement('description', $desc)); // Optional channel elements $lang = $root['lang'] ?? "en-us"; $channel->appendChild($rss->createElement('language', $lang)); $pub_date = $root['pub_date'] ?? date(DATE_RSS); $channel->appendChild($rss->createElement('pubDate', $pub_date)); $build_date = $root['last_build_date'] ?? date(DATE_RSS); $channel->appendChild($rss->createElement('lastBuildDate', $build_date)); $channel->appendChild($rss->createElement('generator', 'RSS Generator')); // Add items to the channel foreach ($items as $itemData) { $item = $rss->createElement('item'); $item = $channel->appendChild($item); $item->appendChild($rss->createElement('title', $itemData['title'])); $item->appendChild($rss->createElement('link', $itemData['link'])); $item->appendChild($rss->createElement('description', $itemData['description'])); $item->appendChild($rss->createElement('pubDate', $itemData['pubDate'])); // GUID should be a permalink $guid = $rss->createElement('guid', $itemData['guid']); $guid->setAttribute('isPermaLink', 'true'); $item->appendChild($guid); // Optional item elements if (isset($itemData['author'])) { $item->appendChild($rss->createElement('author', $itemData['author'])); } } return $rss; } public static function save_to_xml_file(\DOMDocument $rss, string $filename = "feed") { if (! defined("BaseDir") ) { throw new \Exception("BaseDir not Set!"); } $safe_file = BaseDir . "/public/" . preg_replace('/[^A-Za-z0-9]/', '', $filename) . ".xml"; $result = $rss->save($safe_file); if ($result === false) { throw new \Exception("Failed to save RSS feed to file"); } // echo "Saved XML file: " . $safe_file; return true; } public static function output_rss(\DOMDocument $rss): void { // Set the content type to XML header('Content-Type: application/rss+xml; charset=utf-8'); echo $rss->saveXML(); } public static function get_rss(\DOMDocument $rss): string { return $rss->saveXML(); } } /** // Sample items - in a real application, these would come from a database $items = [ [ 'title' => 'First Article', 'link' => 'http://example.com/article1', 'description' => 'This is the description of the first article.', 'pubDate' => date(DATE_RSS, strtotime('-2 days')), 'guid' => 'http://example.com/article1', 'author' => 'author@example.com (John Doe)' ], [ 'title' => 'Second Article', 'link' => 'http://example.com/article2', 'description' => 'This is the description of the second article.', 'pubDate' => date(DATE_RSS, strtotime('-1 day')), 'guid' => 'http://example.com/article2', 'author' => 'author@example.com (Jane Smith)' ] ]; */