3

I have this feed from picasa (correct but arbitrary, desired order).

The result is messed up

Also, with this feed, for example.

It's fine in regular, sorted by date feeds, but not these. In the object I get from Simplepie it has a messed up order. I don't do anything fancy just loop over the results and display them in the found order using my commercial gallery plugin.

$rss_items = $rss->get_items(0, $rss->get_item_quantity($limit));

I have tried this (hooked into wp_feed_options) but it doesn't change anything: $rss->enable_order_by_date(false);

Also, when I do var_dump($rss_items); I get an array that is represented by 546503 lines of text. I don't believe that's normal, maybe it also hogs the memory, but I can't even look through that data manually to see if the order is inherently bad or just gets mixed up somewhere.

Also I can't tell if it's Simplepie's or WordPress' wrapper's fault.

  • You say "Simplepie return feed items in a wrong order" but what is the correct order then? The feed you provided seems to have the items in an arbitrary order. It's not by date and seems not to be in the order of the file names. I'm not really sure what order are they in, but you want them to appear in the same order as in the link I assume? Just wondering what order that is... – jimihenrik Mar 22 '15 at 22:00
  • For what's it worth it seems I was just too tired yesterday and the feed sure is ordered by date, but not by post date, by the date of when the photos were taken. I wonder if you could arrange the feed based on the date in the body of the text, not the <pubDate> attribute... – jimihenrik Mar 23 '15 at 23:11
  • The feed is generated by Picasa (Google) I have no control over it. I believe it uses EXIF date of photos taken and also the upload time (which is the same for subsets of photos). I have no control over this or other feeds that people may throw at my plugin. It needs to respect the order that you can see if you just open the feed by the browser. I don't think it's such a big thing to ask. If all else fails I'll try another parser. – Firsh - LetsWP.io Mar 24 '15 at 9:37
  • Don't know if you noticed my answer but by taking the stuff after the ? in the URL I got the same order that the link has. – jimihenrik Mar 24 '15 at 10:55
  • 1
    Yes that works but only as a symptomatic treatment. If possible I'd like to understand why is this happening. There may be other feeds - not from Picasa - where this fix is not applicable. – Firsh - LetsWP.io Mar 24 '15 at 19:41
3

At the end of class-simplepie.php there is this line:

usort($items, array(get_class($urls[0]), 'sort_items'));

Which force-sorts feed elements, in case of multifeed.

The $feed->enable_order_by_date(false); is indeed very important and the key to things, BUT it gets disregarded (what I was experiencing) if I use multifeed. Source: in get_items() of class-simplepie.php there is this:

// If we want to order it by date, check if all items have a date, and then sort it
if ($this->order_by_date && empty($this->multifeed_objects))

I used multifeed accidentally for single URLs too. Remember it's a plugin where I didn't know if it was going to be single or multiple URLs so it seemed convenient to always pass an array to fetch_feed().

So it now looks something like this:

$rss_url = explode(',',$rss_url); // Accept multiple URLs

if(count($rss_url) == 1){ // New code
    $rss_url = $rss_url[0];
}

add_action('wp_feed_options', array($this, 'jig_add_force_rss'), 10,2);
$rss = fetch_feed($rss_url);
remove_action('wp_feed_options', array($this, 'jig_add_force_rss'), 10);

And the action is:

function jig_add_force_rss($feed,$url){
    $feed->force_feed(true);
    $feed->enable_order_by_date(false);
}

Your solutions were working becuase you passed the RSS url as a string and not as a one-element array. I compared them with how I was using the methods and this was the difference. Now it works with and without query string in the Picasa feed URL, always same as how it looks in the browser.

  • Awesome, nice investigative work. And of course it would be as trivial to "be a multifeed". Dah. Well at least we'll know for the next time. – jimihenrik Mar 28 '15 at 11:29
1

I think you simply have to replace:

$feed->enable_order_by_date(false);

with

$rss->enable_order_by_date(false);

to disable the descending date ordering.

In the case of a feed error, the fetch_feed() function returns an instance of the \WP_Error class. Otherwise the output is an instance of the \SimplePie class and this class contains the enable_order_by_date() public method.

So you should use it like this:

// Fetch the feed:
$rss = fetch_feed( $feed_url );

// Make sure we don't have and WP_Error instance:
if ( ! is_wp_error( $rss ) )   
{
    // Disable the date ordering:
    $rss->enable_order_by_date( false );

    // ... etc ...
}

where we (implicitly) make sure we have an instance of the \SimplePie class.

  • Sorry no, I use $feed in a WP filter, where it's the correct variable name, sorry if it was confusing but it doesn't change anything. It's like pastebin.com/jt8v9Vse – Firsh - LetsWP.io Mar 23 '15 at 22:40
  • I tested your feed with the Codex fetch_feed() example: Example #1 is the plain codex example and the output is ordered by descending pubdate. Example #2 is the codex example with the wp_feed_options hooks. The output has the same order as the feed itself. Example #3 is the codex example where we modify the 'enable_order_by_date' property directly. The output has the same order as the feed itself. @Firsh – birgire Mar 24 '15 at 4:54
  • So example #2 and #3 have the same output. I wonder if you get the same result on your dev install? Try for example the #3 approach to make sure other hook callbacks are not interfering with your setup. You just have to make sure to modify the order_by_date attribute through the enable_order_by_date() method before the get_items() method is called. @Firsh – birgire Mar 24 '15 at 4:59
  • ps: unrelated to this problem, but I just modified the fetch_feed() Codex example, with $maxitems = 0 to avoid a PHP notice on feed errors. – birgire Mar 24 '15 at 5:13
  • and the other PHP strict notice related to fetch_feed() is already being worked on in ticket #29204. – birgire Mar 24 '15 at 5:28
1
+100

I have no idea what's happening with this feed but with this code

include_once( ABSPATH . WPINC . '/feed.php' );
$rss = fetch_feed( 'https://picasaweb.google.com/data/feed/base/user/110981376645512804522/albumid/5638371435917293985' );

foreach ($rss->get_items() as $item) {
    if ($enclosure = $item->get_enclosure()) {
        echo '<img src="'.$enclosure->get_link().'">';
    }
}

I get the same order that I get when opening that feed with my browser. If I leave the ?alt=rss&kind=photo&hl=en_US in the url, it gives the problems you described and the items are in the wrong order.

No idea why, but maybe you can work forward from here.

Edit: So in short, maybe the problem was the url of the feed?


Here's a hacky way to get the right feed:

$url = 'https://picasaweb.google.com/data/feed/base/user/110981376645512804522/albumid/5638371435917293985?alt=json';
// or https://picasaweb.google.com/data/feed/base/user/117541338986679044195/albumid/6129832223894216561?alt=json&kind=photo&hl=en_US&imgmax=800
$json = json_decode(file_get_contents($url));
$feed = (array)$json->feed;
foreach ($feed['entry'] as $entry) {
    $i = 0;
    foreach ($entry->content as $image) {
        if($i % 2 != 0) { echo '<img src="'.$image.'" />'; }
        $i++;
    }
}

So I switched to json feed and parse it kinda uglily. But it gets the job done :D the $entry->content gives both image type and source which is why there's that extra if($i % 2 != 0) to get only every other node.

Still, I have no clue why the RSS does that, but here's alternative way anyway.

edit: to add again you said you really couldn't parse the rss manually so I'll just say that you can add &prettyprint=true to the url to get a prettier feed if you'd like to read it.


edit number thousand: Alternative way!

include_once( ABSPATH . WPINC . '/feed.php' );
$rss = fetch_feed( 'https://picasaweb.google.com/data/feed/base/user/117541338986679044195/albumid/6129832223894216561?alt=rss&fields=item(media:group(media:content(@url)))' );

foreach ($rss->get_items() as $item) {
    if ($enclosure = $item->get_enclosure()) {
        //echo $enclosure->get_link().'<br>';
      echo '<img src="'.$enclosure->get_link().'">';
    }
}

by adding ?alt=rss&fields=item(media:group(media:content(@url))) I got the two feeds you have provided thus far to work correctly! I got all the funny information to try out from here.

  • It does not work for this feed – Firsh - LetsWP.io Mar 26 '15 at 11:14
  • edit: Scrap that, does not work. – jimihenrik Mar 26 '15 at 11:19
  • So we can confirm it's something in Simplepie / WP and rule out the current use (me / my plugin) doing something weird? – Firsh - LetsWP.io Mar 26 '15 at 11:25
  • Well yeah, it's definitely not you. I'm just not sure that where the RSS feed gets rearranged. – jimihenrik Mar 26 '15 at 13:08
  • I appreciate your dedication! Your snippets lead me to the solution, while the exact reason behind the problem was more trivial, it couldn't have been guessed as I didn't post the full code. Fore more info see my answer. It was in a part that I didn't think would matter. However I compared your code with mine and found the difference that messed up my results. The hacky way is interesting but unfortunately it was only aimed at Picasa, while this is a general purpose plugin for any kind of feeds. The third solution worked because it lacks date info, in which case Simplepie doesn't sort. – Firsh - LetsWP.io Mar 28 '15 at 11:21
1

The simplest fix for someone who is experiencing this issue is this:

function my_add_force_rss($feed,$url){
   $feed->force_feed(true);
   $feed->enable_order_by_date(false);
}
add_action('wp_feed_options', 'my_add_force_rss', 10,2);

Placing this in your functions.php will force any feed to be displayed in the order that it is received.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.