function poll($crash_ts = NULL)
{
global $wpdb;
$url = $this->uri(array('add_params' => true));
FeedWordPress::diagnostic('updated_feeds', 'Polling feed [' . $url . ']');
$timeout = $this->setting('fetch timeout', 'feedwordpress_fetch_timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT);
$this->simplepie = apply_filters('syndicated_feed', FeedWordPress::fetch($url, array('timeout' => $timeout)), $this);
// Filter compatibility mode
if (is_wp_error($this->simplepie)) {
$this->magpie = $this->simplepie;
} else {
$this->magpie = new MagpieFromSimplePie($this->simplepie, NULL);
}
$new_count = NULL;
$resume = FeedWordPress::affirmative($this->settings, 'update/unfinished');
if ($resume) {
// pick up where we left off
$processed = array_map('trim', explode("\n", $this->settings['update/processed']));
} else {
// begin at the beginning
$processed = array();
}
if (is_wp_error($this->simplepie)) {
$new_count = $this->simplepie;
// Error; establish an error setting.
$theError = array();
$theError['ts'] = time();
$theError['since'] = time();
$theError['object'] = $this->simplepie;
$oldError = $this->setting('update/error', NULL, NULL);
if (is_string($oldError)) {
$oldError = unserialize($oldError);
}
if (!is_null($oldError)) {
// Copy over the in-error-since timestamp
$theError['since'] = $oldError['since'];
// If this is a repeat error, then we should take
// a step back before we try to fetch it again.
$this->settings['update/last'] = time();
$this->settings['update/ttl'] = $this->automatic_ttl();
$this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->settings['update/ttl'], $this);
$this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl_from_error', $this->settings['update/ttl'], $this);
$this->settings['update/timed'] = 'automatically';
}
do_action('syndicated_feed_error', $theError, $oldError, $this);
$this->settings['update/error'] = serialize($theError);
$this->save_settings(true);
} elseif (is_object($this->simplepie)) {
// Success; clear out error setting, if any.
if (isset($this->settings['update/error'])) {
unset($this->settings['update/error']);
}
$new_count = array('new' => 0, 'updated' => 0);
# -- Update Link metadata live from feed
$channel = $this->magpie->channel;
if (!isset($channel['id'])) {
$channel['id'] = $this->link->link_rss;
}
$update = array();
if (!$this->hardcode('url') and isset($channel['link'])) {
$update[] = "link_url = '" . $wpdb->escape($channel['link']) . "'";
}
if (!$this->hardcode('name') and isset($channel['title'])) {
$update[] = "link_name = '" . $wpdb->escape($channel['title']) . "'";
}
if (!$this->hardcode('description')) {
if (isset($channel['tagline'])) {
$update[] = "link_description = '" . $wpdb->escape($channel['tagline']) . "'";
} elseif (isset($channel['description'])) {
$update[] = "link_description = '" . $wpdb->escape($channel['description']) . "'";
}
}
$this->settings = array_merge($this->settings, $this->flatten_array($channel));
$this->settings['update/last'] = time();
list($ttl, $xml) = $this->ttl(true);
if (!is_null($ttl)) {
$this->settings['update/ttl'] = $ttl;
$this->settings['update/xml'] = $xml;
$this->settings['update/timed'] = 'feed';
} else {
$ttl = $this->automatic_ttl();
$this->settings['update/ttl'] = $ttl;
$this->settings['update/xml'] = NULL;
$this->settings['update/timed'] = 'automatically';
}
$this->settings['update/fudge'] = rand(0, $ttl / 3) * 60;
$this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->setting('update/ttl'), $this);
if (!$this->setting('update/hold') != 'ping') {
$this->settings['update/hold'] = 'scheduled';
}
$this->settings['update/unfinished'] = 'yes';
$update[] = "link_notes = '" . $wpdb->escape($this->settings_to_notes()) . "'";
$update_set = implode(',', $update);
// Update the properties of the link from the feed information
$result = $wpdb->query("\n\t\t\t\tUPDATE {$wpdb->links}\n\t\t\t\tSET {$update_set}\n\t\t\t\tWHERE link_id='{$this->id}'\n\t\t\t");
do_action('update_syndicated_feed', $this->id, $this);
# -- Add new posts from feed and update any updated posts
$crashed = false;
$posts = apply_filters('syndicated_feed_items', $this->simplepie->get_items(), &$this);
$this->magpie->originals = $posts;
if (is_array($posts)) {
foreach ($posts as $key => $item) {
$post = new SyndicatedPost($item, $this);
if (!$resume or !in_array(trim($post->guid()), $processed)) {
$processed[] = $post->guid();
if (!$post->filtered()) {
$new = $post->store();
if ($new !== false) {
$new_count[$new]++;
}
}
if (!is_null($crash_ts) and time() > $crash_ts) {
$crashed = true;
break;
}
}
unset($post);
}
}
$suffix = $crashed ? 'crashed' : 'completed';
do_action('update_syndicated_feed_items', $this->id, $this);
do_action("update_syndicated_feed_items_{$suffix}", $this->id, $this);
// Copy back any changes to feed settings made in the course of updating (e.g. new author rules)
$to_notes = $this->settings;
$this->settings['update/processed'] = $processed;
if (!$crashed) {
$this->settings['update/unfinished'] = 'no';
}
$update_set = "link_notes = '" . $wpdb->escape($this->settings_to_notes()) . "'";
// Update the properties of the link from the feed information
$result = $wpdb->query("\n\t\t\tUPDATE {$wpdb->links}\n\t\t\tSET {$update_set}\n\t\t\tWHERE link_id='{$this->id}'\n\t\t\t");
do_action("update_syndicated_feed_completed", $this->id, $this);
}
// All done; let's clean up.
$this->magpie = NULL;
// Avoid circular-reference memory leak in PHP < 5.3.
// Cf. <http://simplepie.org/wiki/faq/i_m_getting_memory_leaks>
if (method_exists($this->simplepie, '__destruct')) {
$this->simplepie->__destruct();
}
$this->simplepie = NULL;
return $new_count;
}