Fixing a broken ATOM Feed

Fixing a broken ATOM Feed

My city is not known for being technologically adept, and I’m at least lucky they have a website with a CMS. Sadly though, the website offers only a broken ATOM 1.0 feed, a standard that’s old enough to drink in some countries.

Unfortunately, this doesn’t work with NewsBlur, so I had to sort to building a proxy that would parse the XML and output a JSON Feed.

Through the power of Phpfastcache (only for a little bit of caching), I am embarassed to show you this cobbled together mess:

<?php
define( 'DEBUG', false );

if ( defined( 'DEBUG') && DEBUG ) {
	ini_set('display_errors', 1);
	ini_set('display_startup_errors', 1);
	error_reporting(E_ALL);
}

use Phpfastcache\Helper\Psr16Adapter;
require 'vendor/autoload.php';

$cache     = new Psr16Adapter( 'Files' );
$url       = 'https://www.cityoflinton.com/egov/api/request.egov?request=feed;dateformat=%25B%20%25d%20at%20%25X%23%23%25b%2B%2B%25d;featured=3;title=Upcoming%20Events;ctype=1;order=revdate';
$cache_key = 'atom-feed_' . md5( $url );

// Get and/or fill the cache.
if ( ! $cache->has( $cache_key ) ) {
	$atom_feed = file_get_contents( $url );
	$cache->set( $cache_key, $atom_feed, 60 * 60 * 1 ); // 1 hour.
} else {
	$atom_feed = $cache->get( $cache_key );
}

$feed_data = new SimpleXMLElement( $atom_feed );

$json_feed = array(
	'version'       => 'https://jsonfeed.org/version/1.1',
	'title'         => filter_var( trim( $feed_data->title ) ?? 'Upcoming Events for the City of Linton', FILTER_SANITIZE_STRING ),
	'home_page_url' => 'https://www.cityoflinton.com/',
	'feed_url'      => 'https://decarbonated.org/tools/cityoflinton-rss/',
	'language'      => 'en-US',
	'items'         => array(),
);

foreach( $feed_data->entry as $entry ) {
	$json_feed['items'][] = array(
		'id'            => md5( $entry->id ),
		'url'           => filter_var( trim( $entry->link['href'] ) ?? 'NO LINK FOUND', FILTER_SANITIZE_URL ),
		'title'         => filter_var( trim( $entry->title ) ?? 'NO TITLE FOUND', FILTER_SANITIZE_STRING ),
		'content_text'  => filter_var( trim( $entry->summary ) ?? 'NO CONTENT FOUND', FILTER_SANITIZE_STRING ),
		'date_modified' => ( new DateTime( trim( $entry->updated ) ?? now(), new DateTimeZone( 'America/New_York' ) ) )->format( DateTimeInterface::RFC3339 ),
	);
}

if ( defined( 'DEBUG ' ) && DEBUG ) {
	header( 'Content-Type: text/plain' );
	var_dump( $json_feed );
} else {
	header( 'Content-Type: application/feed+json' );
	echo json_encode( $json_feed );
}

This will convert the XML from (prettified):

<?xml version="1.0" encoding="ISO-8859-1"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>Upcoming Events</title>
	<link rel="self" href="https://www.cityoflinton.com/egov/api/request.egov?request=feed;dateformat=%25B%20%25d%20at%20%25X%23%23%25b%2B%2B%25d;featured=3;title=Upcoming%20Events;ctype=1;order=revdate" />
	<updated>2021-12-09T10:14:40</updated>
	<id>https://www.cityoflinton.com/egov/api/request.egov?request=feed;dateformat=%25B%20%25d%20at%20%25X%23%23%25b%2B%2B%25d;featured=3;title=Upcoming%20Events;ctype=1;order=revdate</id>
	<author>
		<name>Organization Information</name>
	</author>
	<entry>
		<title>City Hall Closed</title>
		<link rel="alternate" href="https://www.cityoflinton.com/egov/apps/events/calendar.egov?view=detail;id=501" />
		<updated>2021-12-09T10:14:40</updated>
		<id>https://www.cityoflinton.com/egov/apps/events/calendar.egov?view=detail;id=501</id>
		<featured>0</featured>
		<summary type="html">City Hall Closed</summary>
	</entry>
</feed>

to JSON like:

{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Upcoming Events",
  "home_page_url": "https://www.cityoflinton.com/",
  "feed_url": "https://decarbonated.org/tools/cityoflinton-rss/",
  "language": "en-US",
  "items": [
    {
      "id": "9b0bcc229cdc4266e539a785d77b4a8f",
      "url": "https://www.cityoflinton.com/egov/apps/events/calendar.egov?view=detail;id=501",
      "title": "City Hall Closed",
      "content_text": "City Hall Closed",
      "date_modified": "2021-12-09T10:14:40-05:00"
    }
  ]
}

That’s all ¯\_(ツ)_/¯


Leave a Reply

%d bloggers like this: