Reputation: 59
Is there a way to force an array of feeds to sort on date, even if one feed is missing a time/date stamp?
If I understand correctly, one bad feed in the list messes up sorting. From the description of the SimplePieWP plugin, but presumably a general issue:
'... the plugin also supports what we affectionately call “Multifeeds”. This allows you to >merge multiple feeds together and sort the items by time and date ... notice that I said >“sort the items by time and date.” So, what happens if a feed is missing a time/date->stamp? They won't sort. (Duh.) Sorting by date requires ALL individual items in ALL merged >feeds to have time/date-stamps associated with them.'
I think I regularly see the result of this in my sites; feeds are not sorted on date, posts from the top feed in the array are always at the top etc.
In my set-up it is impossible to manually check each feed for a time/date stamp; the feed lists are too long and/or constantly changing and automatically generated.
Is there code I can add somewhere to just filter out feeds without time/date stamps?
Or to give bad feeds a default time/date in the 1970s, so they sort at the bottom?
Or has this issue already been fixed? Am I missing something?
I've done many searches on this over the years, but have never figured it out.
Upvotes: 1
Views: 820
Reputation: 31
SimplePie does an explicit check of each item in SimplePie::merge_items() to determine if any item is missing a date.
You will have to override this method to change sorting behavior for multifeeds. Below is an override to sort multifeeds even when items are missing a date. If the item is missing a date, it is sorted to the bottom. (using SimplePie 1.3).
class SimplePieAlwaysSort extends SimplePie
{
public function get_items($start = 0, $end = 0)
{
if (!isset($this->data['items']))
{
if (!empty($this->multifeed_objects))
{
$this->data['items'] = self::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
}
}
return parent::get_items($start, $end);
}
public static function merge_items($urls, $start = 0, $end = 0, $limit = 0)
{
if (is_array($urls) && sizeof($urls) > 0)
{
$items = array();
foreach ($urls as $arg)
{
if ($arg instanceof SimplePie)
{
$items = array_merge($items, $arg->get_items(0, $limit));
}
else
{
trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
}
}
usort($items, array(get_class($urls[0]), 'sort_items'));
if ($end === 0)
{
return array_slice($items, $start);
}
else
{
return array_slice($items, $start, $end);
}
}
else
{
trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
return array();
}
}
}
$pie = new SimplePieAlwaysSort();
$pie->set_feed_url(array('http://stackoverflow.com/feeds'));
$pie->init();
foreach ($pie->get_items() as $item)
{
// do stuff
}
Upvotes: 3