0

I am having a problem with converting a JSON feed into a RSS feed. I am attempting to do this in a single function, seen below.

I found code on GitHub — but it doesn't work properly — and I don't know how to fix it.

In the bottom of the PHP code: echo convert_jsonfeed_to_rss($content)."\n"; I am expecting this to print out the RSS XML feed — it doesn't.

<?php

//Convert JSONfeed to RSS in a single function as a drop in to make adding JSONfeed
//support to an aggregator easier
function convert_jsonfeed_to_rss($content = NULL, $max = NULL)
{
    //Test if the content is actual JSON
    json_decode($content);
    if( json_last_error() !== JSON_ERROR_NONE) return FALSE;

    //Now, is it valid JSONFeed?
    $jsonFeed = json_decode($content, TRUE);
    if (!isset($jsonFeed['version'])) return FALSE;
    if (!isset($jsonFeed['title'])) return FALSE;
    if (!isset($jsonFeed['items'])) return FALSE;

    //Decode the feed to a PHP array
    $jf = json_decode($content, TRUE);

    //Get the latest item publish date to use as the channel pubDate
    $latestDate = 0;
    foreach ($jf['items'] as $item) {
        if (strtotime($item['date_published']) > $latestDate) $latestDate = strtotime($item['date_published']);
    }
    $lastBuildDate = date(DATE_RSS, $latestDate);

    //Create the RSS feed
    $xmlFeed = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"></rss>');
    $xmlFeed->addChild("channel");

    //Required elements
    $xmlFeed->channel->addChild("title", $jf['title']);
    $xmlFeed->channel->addChild("pubDate", $lastBuildDate);
    $xmlFeed->channel->addChild("lastBuildDate", $lastBuildDate);

    //Optional elements
    if (isset($jf['description'])) $xmlFeed->channel->description = $jf['description'];
    if (isset($jf['home_page_url'])) $xmlFeed->channel->link = $jf['home_page_url'];

    //Items
    foreach ($jf['items'] as $item) {
        $newItem = $xmlFeed->channel->addChild('item');

        //Standard stuff
        if (isset($item['id'])) $newItem->addChild('guid', $item['id']);
        if (isset($item['title'])) $newItem->addChild('title', $item['title']);
        if (isset($item['content_text'])) $newItem->addChild('description', $item['content_text']);
        if (isset($item['content_html'])) $newItem->addChild('description', $item['content_html']);
        if (isset($item['date_published'])) $newItem->addChild('pubDate', $item['date_published']);
        if (isset($item['url'])) $newItem->addChild('link', $item['url']);

        //Enclosures?
        if(isset($item['attachments'])) {
            foreach($item['attachments'] as $attachment) {
                $enclosure = $newItem->addChild('enclosure');
                $enclosure['url'] = $attachment['url'];
                $enclosure['type'] = $attachment['mime_type'];
                $enclosure['length'] = $attachment['size_in_bytes'];
            }
        }
    }

    //Make the output pretty
    $dom = new DOMDocument("1.0");
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $dom->loadXML($xmlFeed->asXML());
    return $dom->saveXML();
}


$content = @file_get_contents("http://timetable.manton.org/feed.json");
echo convert_jsonfeed_to_rss($content)."\n";

I tried to put the $content variable before the convert_jsonfeed_to_rss function — same problem.

$content = @file_get_contents("http://timetable.manton.org/feed.json");

1 Answer 1

1

The conversion to a DOMDocument at the end seems to be the issue, it objects to a few parts of the document.

A quicker way (and seems to be more reliable in this case) is to just use dom_import_simplexml()

$dom = dom_import_simplexml($xmlFeed)->ownerDocument;
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
return $dom->saveXML();

(from https://stackoverflow.com/a/799792/1213708).

Edit

From your updated code, you aren't using the hierarchy properly (and probably don't have errors enabled to show what is not working).

You need something like...

foreach ($jf['data']['feed'] as $item1) {
//      foreach ($item1['feed'] as $item) {

        $item = $item1['article'];
Sign up to request clarification or add additional context in comments.

5 Comments

Hi thank you for help now works but i have problems to implement my JSON script to that program see my code: pastebin.com/70yNggze i add 2 foreach functions first work but second not work here is my JSON feed: pastebin.com/fhWt1ery @Nigel Ren
I've updated the answer, you will need to check as there are still other errors, but the loop should generate some data.
now works but i need to add thumbnail url in item rss section. The problem is the browser dont add media: before thumbnail only add <thumbnail url="example.com/images.jpg"> i need to force browser to add media before thumbnail like this: <media:thumbnail url="example.com/image.jpg"> i try: if (isset($item['image_url'])) $newItem->addChild('media:thumbnail url="'.$item['image_url'].'"'); but not add media before thumbnail? @Nigel Ren
EDIT: I use CDATA on the description section and fix the image issue, in previous foreach function I see that not print tags and categories from JSON: pastebin.com/fhWt1ery I see that I need to add new foreach for tags and categories is that right? @Nigel Ren
If you have multiple data like tags and categories, it's easier to use another level of foreach().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.