fetch() static public method

static public fetch ( $url, $params = [] )
 function poll($crash_ts = NULL)
 {
     // Do nothing but update copy of feed
     $this->simplepie = FeedWordPress::fetch($this->url);
     $this->magpie = new MagpieFromSimplePie($this->simplepie);
     $this->link = $this->magpie;
 }
    function multiadd_box($page, $box = NULL)
    {
        global $fwp_post;
        $localData = NULL;
        if (isset($_FILES['opml_upload']['name']) and strlen($_FILES['opml_upload']['name']) > 0) {
            $in = 'tag:localhost';
            /*FIXME: check whether $_FILES['opml_upload']['error'] === UPLOAD_ERR_OK or not...*/
            $localData = file_get_contents($_FILES['opml_upload']['tmp_name']);
            $merge_all = true;
        } elseif (isset($fwp_post['multilookup'])) {
            $in = $fwp_post['multilookup'];
            $merge_all = false;
        } elseif (isset($fwp_post['opml_lookup'])) {
            $in = $fwp_post['opml_lookup'];
            $merge_all = true;
        } else {
            $in = '';
            $merge_all = false;
        }
        if (strlen($in) > 0) {
            $lines = preg_split("/\\s+/", $in, -1, PREG_SPLIT_NO_EMPTY);
            $i = 0;
            ?>
			<form id="multiadd-form" action="<?php 
            print $this->form_action();
            ?>
" method="post">
			<div><?php 
            FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds');
            ?>
			<input type="hidden" name="multiadd" value="<?php 
            print FWP_SYNDICATE_NEW;
            ?>
" />
			<input type="hidden" name="confirm" value="multiadd" />

			<input type="hidden" name="multiadd" value="<?php 
            print FWP_SYNDICATE_NEW;
            ?>
" />
			<input type="hidden" name="confirm" value="multiadd" /></div>

			<div id="multiadd-status">
			<p><img src="<?php 
            print esc_url(admin_url('images/wpspin_light.gif'));
            ?>
" alt="" />
			Looking up feed information...</p>
			</div>

			<div id="multiadd-buttons">
			<input type="submit" class="button" name="cancel" value="<?php 
            _e(FWP_CANCEL_BUTTON);
            ?>
" />
			<input type="submit" class="button-primary" value="<?php 
            print _e('Subscribe to selected sources →');
            ?>
" />
			</div>
			
			<p><?php 
            _e('Here are the feeds that FeedWordPress has discovered from the addresses that you provided. To opt out of a subscription, unmark the checkbox next to the feed.');
            ?>
</p>
			
			<?php 
            print "<ul id=\"multiadd-list\">\n";
            flush();
            foreach ($lines as $line) {
                $url = trim($line);
                if (strlen($url) > 0) {
                    // First, use FeedFinder to check the URL.
                    if (is_null($localData)) {
                        $finder = new FeedFinder($url, false, 1);
                    } else {
                        $finder = new FeedFinder('tag:localhost', false, 1);
                        $finder->upload_data($localData);
                    }
                    $feeds = array_values(array_unique($finder->find()));
                    $found = false;
                    if (count($feeds) > 0) {
                        foreach ($feeds as $feed) {
                            $pie = FeedWordPress::fetch($feed);
                            if (!is_wp_error($pie)) {
                                $found = true;
                                $short_feed = esc_html(feedwordpress_display_url($feed));
                                $feed = esc_html($feed);
                                $title = esc_html($pie->get_title());
                                $checked = ' checked="checked"';
                                $link = esc_html($pie->get_link());
                                $this->display_multiadd_line(array('feed' => $feed, 'title' => $pie->get_title(), 'link' => $pie->get_link(), 'checked' => ' checked="checked"', 'i' => $i));
                                $i++;
                                // Increment field counter
                                if (!$merge_all) {
                                    // Break out after first find
                                    break;
                                }
                            }
                        }
                    }
                    if (!$found) {
                        $this->display_multiadd_line(array('feed' => $url, 'title' => feedwordpress_display_url($url), 'extra' => " [FeedWordPress couldn't detect any feeds for this URL.]", 'link' => NULL, 'checked' => '', 'i' => $i));
                        $i++;
                        // Increment field counter
                    }
                }
            }
            print "</ul>\n";
            ?>
			</form>
			
			<script type="text/javascript">
				jQuery(document).ready( function () {
					// Hide it now that we're done.
					jQuery('#multiadd-status').fadeOut(500 /*ms*/);
				} );
			</script>
			<?php 
        }
        $this->_sources = NULL;
        // Force reload of sources list
        return true;
        // Continue
    }
	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($this, 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);
		endif;

		$new_count = NULL;

		$resume = ('yes'==$this->setting('update/unfinished'));
		if ($resume) :
			// pick up where we left off
			$processed = array_map('trim', explode("\n", $this->setting('update/processed')));
		else :
			// begin at the beginning
			$processed = array();
		endif;

		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);
			endif;

			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->update_setting('update/last', time(), NULL);
				$ttl = $this->automatic_ttl();
				$ttl = apply_filters('syndicated_feed_ttl', $ttl, $this);
				$ttl = apply_filters('syndicated_feed_ttl_from_error', $ttl, $this);
				$this->update_setting('update/ttl', $ttl, $this);
				$this->update_setting('update/timed', 'automatically');
			endif;
			
			do_action('syndicated_feed_error', $theError, $oldError, $this);
			
			$this->update_setting('update/error', serialize($theError));
			$this->save_settings(/*reload=*/ true);

		elseif (is_object($this->simplepie)) :
			// Success; clear out error setting, if any.
			$this->update_setting('update/error', NULL);

			$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;
			endif;
	
			$update = array();
			if (!$this->hardcode('url') and isset($channel['link'])) :
				$update[] = "link_url = '".$wpdb->escape($channel['link'])."'";
			endif;
	
			if (!$this->hardcode('name') and isset($channel['title'])) :
				$update[] = "link_name = '".$wpdb->escape($channel['title'])."'";
			endif;
	
			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'])."'";
				endif;
			endif;

			$this->merge_settings($channel, 'feed/');

			$this->update_setting('update/last', time());
			list($ttl, $xml) = $this->ttl(/*return element=*/ true);
			
			if (!is_null($ttl)) :
				$this->update_setting('update/ttl', $ttl);
				$this->update_setting('update/xml', $xml);
				$this->update_setting('update/timed', 'feed');
			else :
				$ttl = $this->automatic_ttl();
				$this->update_setting('update/ttl', $ttl);
				$this->update_setting('update/xml', NULL);
				$this->update_setting('update/timed', 'automatically');
			endif;
			$this->update_setting('update/fudge', rand(0, ($ttl/3))*60);
			$this->update_setting('update/ttl', apply_filters(
				'syndicated_feed_ttl',
				$this->setting('update/ttl'),
				$this
			));

			if (!$this->setting('update/hold') != 'ping') :
				$this->update_setting('update/hold', 'scheduled');
			endif;

			$this->update_setting('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("
				UPDATE $wpdb->links
				SET $update_set
				WHERE link_id='$this->id'
			");
			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 this is a complete feed, rather than an incremental feed, we
			// need to prepare to mark everything for presumptive retirement.
			if ($this->is_incremental()) :
				$q = new WP_Query(array(
				'fields' => '_synfrom',
				'post_status__not' => 'fwpretired',
				'ignore_sticky_posts' => true,
				'meta_key' => 'syndication_feed_id',
				'meta_value' => $this->id,
				));
				foreach ($q->posts as $p) :
					update_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id, '1');
				endforeach;
			endif;
			
			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]++;
						endif;

						if (!is_null($crash_ts) and (time() > $crash_ts)) :
							$crashed = true;
							break;
						endif;
					endif;
					unset($post);
				endforeach;
			endif;
			
			if ('yes'==$this->setting('tombstones', 'tombstones', 'yes')) :
				// Check for use of Atom tombstones. Spec:
				// <http://tools.ietf.org/html/draft-snell-atompub-tombstones-18>
				$tombstones = $this->simplepie->get_feed_tags('http://purl.org/atompub/tombstones/1.0', 'deleted-entry');
				if (count($tombstones) > 0) :
					foreach ($tombstones as $tombstone) :
						$ref = NULL;
						foreach (array('', 'http://purl.org/atompub/tombstones/1.0') as $ns) :
							if (isset($tombstone['attribs'][$ns])
							and isset($tombstone['attribs'][$ns]['ref'])) :
								$ref = $tombstone['attribs'][$ns]['ref'];
							endif;
						endforeach;
						
						$q = new WP_Query(array(
						'ignore_sticky_posts' => true,
						'guid' => $ref,
						'meta_key' => 'syndication_feed_id',
						'meta_value' => $this->id, // Only allow a feed to tombstone its own entries.
						));
						
						foreach ($q->posts as $p) :
							$old_status = $p->post_status;
							FeedWordPress::diagnostic('syndicated_posts', 'Retiring existing post # '.$p->ID.' "'.$p->post_title.'" due to Atom tombstone element in feed.');
							set_post_field('post_status', 'fwpretired', $p->ID);
							wp_transition_post_status('fwpretired', $old_status, $p);
						endforeach;
						
					endforeach;
				endif;
			endif;
			
			$suffix = ($crashed ? 'crashed' : 'completed');
			do_action('update_syndicated_feed_items', $this->id, $this);
			do_action("update_syndicated_feed_items_${suffix}", $this->id, $this);

			$this->update_setting('update/processed', $processed);
			if (!$crashed) :
				$this->update_setting('update/unfinished', 'no');
			endif;
			$this->update_setting('link/item count', count($posts));

			// Copy back any changes to feed settings made in the
			// course of updating (e.g. new author rules)
			$update_set = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
			
			// Update the properties of the link from the feed information
			$result = $wpdb->query("
			UPDATE $wpdb->links
			SET $update_set
			WHERE link_id='$this->id'
			");
			
			do_action("update_syndicated_feed_completed", $this->id, $this);
		endif;
		
		// 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();
		endif;
		$this->simplepie = NULL;
		
		return $new_count;
	} /* SyndicatedLink::poll() */
    function display_feedfinder()
    {
        global $wpdb;
        $lookup = isset($_REQUEST['lookup']) ? $_REQUEST['lookup'] : NULL;
        $auth = FeedWordPress::param('link_rss_auth_method');
        $username = FeedWordPress::param('link_rss_username');
        $password = FeedWordPress::param('link_rss_password');
        $credentials = array("authentication" => $auth, "username" => $username, "password" => $password);
        $feeds = array();
        $feedSwitch = false;
        $current = null;
        if ($this->for_feed_settings()) {
            // Existing feed?
            $feedSwitch = true;
            if (is_null($lookup)) {
                // Switch Feed without a specific feed yet suggested
                // Go to the human-readable homepage to look for
                // auto-detection links
                $lookup = $this->link->link->link_url;
                $auth = $this->link->setting('http auth method');
                $username = $this->link->setting('http username');
                $password = $this->link->setting('http password');
                // Guarantee that you at least have the option to
                // stick with what works.
                $current = $this->link->link->link_rss;
                $feeds[] = $current;
            }
            $name = esc_html($this->link->link->link_name);
        } else {
            // Or a new subscription to add?
            $name = "Subscribe to <code>" . esc_html(feedwordpress_display_url($lookup)) . "</code>";
        }
        ?>
		<div class="wrap" id="feed-finder">
		<h2>Feed Finder: <?php 
        echo $name;
        ?>
</h2>

		<?php 
        if ($feedSwitch) {
            $this->display_alt_feed_box($lookup);
        }
        $finder = array();
        if (!is_null($current)) {
            $finder[$current] = new FeedFinder($current);
        }
        $finder[$lookup] = new FeedFinder($lookup);
        foreach ($finder as $url => $ff) {
            $feeds = array_merge($feeds, $ff->find(NULL, $credentials));
        }
        $feeds = array_values($feeds);
        if (count($feeds) > 0) {
            if ($feedSwitch) {
                ?>
				<h3>Feeds Found</h3>
				<?php 
            }
            if (count($feeds) > 1) {
                $option_template = 'Option %d: ';
                $form_class = ' class="multi"';
                ?>
				<p><strong>This web page provides at least <?php 
                print count($feeds);
                ?>
 different feeds.</strong> These feeds may provide the same information
				in different formats, or may track different items. (You can check the Feed Information and the
				Sample Item for each feed to get an idea of what the feed provides.) Please select the feed that you'd like to subscribe to.</p>
				<?php 
            } else {
                $option_template = '';
                $form_class = '';
            }
            global $fwp_credentials;
            foreach ($feeds as $key => $f) {
                $ofc = $fwp_credentials;
                $fwp_credentials = $credentials;
                // Set
                $pie = FeedWordPress::fetch($f);
                $fwp_credentials = $ofc;
                // Re-Set
                $rss = is_wp_error($pie) ? $pie : new MagpieFromSimplePie($pie);
                if ($this->url_for_401($pie)) {
                    $this->display_alt_feed_box($lookup, array("err" => $pie, "auth" => $auth, "username" => $username, "password" => $password));
                    continue;
                }
                if ($rss and !is_wp_error($rss)) {
                    $feed_link = isset($rss->channel['link']) ? $rss->channel['link'] : '';
                    $feed_title = isset($rss->channel['title']) ? $rss->channel['title'] : $feed_link;
                    $feed_type = $rss->feed_type ? $rss->feed_type : 'Unknown';
                    $feed_version_template = '%.1f';
                    $feed_version = $rss->feed_version;
                } else {
                    // Give us some sucky defaults
                    $feed_title = feedwordpress_display_url($lookup);
                    $feed_link = $lookup;
                    $feed_type = 'Unknown';
                    $feed_version_template = '';
                    $feed_version = '';
                }
                ?>
					<form<?php 
                print $form_class;
                ?>
 action="admin.php?page=<?php 
                print $GLOBALS['fwp_path'];
                ?>
/syndication.php" method="post">
					<div class="inside"><?php 
                FeedWordPressCompatibility::stamp_nonce('feedwordpress_switchfeed');
                ?>

					<?php 
                $classes = array('feed-found');
                $currentFeed = '';
                if (!is_null($current) and $current == $f) {
                    $classes[] = 'current';
                    $currentFeed = ' (currently subscribed)';
                }
                if ($key % 2) {
                    $classes[] = 'alt';
                }
                ?>
					<fieldset class="<?php 
                print implode(" ", $classes);
                ?>
">
					<legend><?php 
                printf($option_template, $key + 1);
                print $feed_type . " ";
                printf($feed_version_template, $feed_version);
                ?>
 feed<?php 
                print $currentFeed;
                ?>
</legend>

					<?php 
                $this->stamp_link_id();
                // No feed specified = add new feed; we
                // need to pass along a starting title
                // and homepage URL for the new Link.
                if (!$this->for_feed_settings()) {
                    ?>
						<input type="hidden" name="feed_title" value="<?php 
                    echo esc_html($feed_title);
                    ?>
" />
						<input type="hidden" name="feed_link" value="<?php 
                    echo esc_html($feed_link);
                    ?>
" />
						<?php 
                }
                ?>

					<input type="hidden" name="feed" value="<?php 
                echo esc_html($f);
                ?>
" />
					<input type="hidden" name="action" value="switchfeed" />

					<div>
					<div class="feed-sample">
					<?php 
                $link = NULL;
                $post = NULL;
                if (!is_wp_error($rss) and count($rss->items) > 0) {
                    // Prepare to display Sample Item
                    $link = new MagpieMockLink(array('simplepie' => $pie, 'magpie' => $rss), $f);
                    $post = new SyndicatedPost(array('simplepie' => $rss->originals[0], 'magpie' => $rss->items[0]), $link);
                    ?>
						<h3>Sample Item</h3>
						<ul>
						<li><strong>Title:</strong> <a href="<?php 
                    echo $post->post['meta']['syndication_permalink'];
                    ?>
"><?php 
                    echo $post->post['post_title'];
                    ?>
</a></li>
						<li><strong>Date:</strong> <?php 
                    print date('d-M-y g:i:s a', $post->published());
                    ?>
</li>
						</ul>
						<div class="entry">
						<?php 
                    print $post->post['post_content'];
                    ?>
						</div>
						<?php 
                    do_action('feedwordpress_feed_finder_sample_item', $f, $post, $link);
                } else {
                    if (is_wp_error($rss)) {
                        print '<div class="feed-problem">';
                        print "<h3>Problem:</h3>\n";
                        print "<p>FeedWordPress encountered the following error\n\t\t\t\t\t\t\twhen trying to retrieve this feed:</p>";
                        print '<p style="margin: 1.0em 3.0em"><code>' . $rss->get_error_message() . '</code></p>';
                        print "<p>If you think this is a temporary problem, you can still force FeedWordPress to add the subscription. FeedWordPress will not be able to find any syndicated posts until this problem is resolved.</p>";
                        print "</div>";
                    }
                    ?>
						<h3>No Items</h3>
						<p>FeedWordPress found no posts on this feed.</p>
						<?php 
                }
                ?>
					</div>
	
					<div>
					<h3>Feed Information</h3>
					<ul>
					<li><strong>Homepage:</strong> <a href="<?php 
                echo $feed_link;
                ?>
"><?php 
                echo is_null($feed_title) ? '<em>Unknown</em>' : $feed_title;
                ?>
</a></li>
					<li><strong>Feed URL:</strong> <a title="<?php 
                echo esc_html($f);
                ?>
" href="<?php 
                echo esc_html($f);
                ?>
"><?php 
                echo esc_html(feedwordpress_display_url($f, 40, 10));
                ?>
</a> (<a title="Check feed &lt;<?php 
                echo esc_html($f);
                ?>
&gt; for validity" href="http://feedvalidator.org/check.cgi?url=<?php 
                echo urlencode($f);
                ?>
">validate</a>)</li>
					<li><strong>Encoding:</strong> <?php 
                echo isset($rss->encoding) ? esc_html($rss->encoding) : "<em>Unknown</em>";
                ?>
</li>
					<li><strong>Description:</strong> <?php 
                echo isset($rss->channel['description']) ? esc_html($rss->channel['description']) : "<em>Unknown</em>";
                ?>
</li>
					</ul>
					<?php 
                $this->display_authentication_credentials_box(array('username' => $username, 'password' => $password, 'method' => $auth));
                ?>
					<?php 
                do_action('feedwordpress_feedfinder_form', $f, $post, $link, $this->for_feed_settings());
                ?>
					<div class="submit"><input type="submit" class="button-primary" name="Use" value="&laquo; Use this feed" />
					<input type="submit" class="button" name="Cancel" value="× Cancel" /></div>
					</div>
					</div>
					</fieldset>
					</div> <!-- class="inside" -->
					</form>
					<?php 
                unset($link);
                unset($post);
            }
        } else {
            foreach ($finder as $url => $ff) {
                $url = esc_html($url);
                print "<h3>Searched for feeds at {$url}</h3>\n";
                print "<p><strong>" . __('Error') . ":</strong> " . __("FeedWordPress couldn't find any feeds at") . ' <code><a href="' . htmlspecialchars($lookup) . '">' . htmlspecialchars($lookup) . '</a></code>';
                print ". " . __('Try another URL') . ".</p>";
                // Diagnostics
                print "<div class=\"updated\" style=\"margin-left: 3.0em; margin-right: 3.0em;\">\n";
                print "<h3>" . __('Diagnostic information') . "</h3>\n";
                if (!is_null($ff->error()) and strlen($ff->error()) > 0) {
                    print "<h4>" . __('HTTP request failure') . "</h4>\n";
                    print "<p>" . $ff->error() . "</p>\n";
                } else {
                    print "<h4>" . __('HTTP request completed') . "</h4>\n";
                    print "<p><strong>Status " . $ff->status() . ":</strong> " . $this->HTTPStatusMessages[(int) $ff->status()] . "</p>\n";
                }
                // Do some more diagnostics if the API for it is available.
                if (function_exists('_wp_http_get_object')) {
                    $httpObject = _wp_http_get_object();
                    if (is_callable(array($httpObject, '_getTransport'))) {
                        $transports = $httpObject->_getTransport();
                        print "<h4>" . __('HTTP Transports available') . ":</h4>\n";
                        print "<ol>\n";
                        print "<li>" . implode("</li>\n<li>", array_map('get_class', $transports)) . "</li>\n";
                        print "</ol>\n";
                    } elseif (is_callable(array($httpObject, '_get_first_available_transport'))) {
                        $transport = $httpObject->_get_first_available_transport(array(), $url);
                        print "<h4>" . __("HTTP Transport") . ":</h4>\n";
                        print "<ol>\n";
                        print "<li>" . FeedWordPress::val($transport) . "</li>\n";
                        print "</ol>\n";
                    }
                    print "</div>\n";
                }
            }
        }
        if (!$feedSwitch) {
            $this->display_alt_feed_box($lookup, true);
        }
        ?>
	</div> <!-- class="wrap" -->
		<?php 
        return false;
        // Don't continue
    }
 function fetch()
 {
     $timeout = $this->setting('fetch timeout', 'feedwordpress_fetch_timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT);
     $this->simplepie = apply_filters('syndicated_feed', FeedWordPress::fetch($this, 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);
     }
 }
 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;
 }
 function poll($crash_ts = NULL)
 {
     FeedWordPress::diagnostic('updated_feeds', 'Polling feed <' . $this->link->link_rss . '>');
     $this->simplepie = apply_filters('syndicated_feed', FeedWordPress::fetch($this->link->link_rss), $this);
     // Filter compatibility mode
     if (is_wp_error($this->simplepie)) {
         $this->magpie = $this->simplepie;
     } else {
         $this->magpie = new MagpieFromSimplePie($this->simplepie);
     }
     $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';
         }
         $this->settings['update/error'] = serialize($theError);
         $this->save_settings(true);
     } elseif (is_object($this->simplepie)) {
         // Grab our bookmark we're going to be updating
         $link = get_bookmark($this->id, ARRAY_A);
         if (is_array($link) && !empty($link)) {
             // 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;
             }
             if (!$this->hardcode('url') and isset($channel['link'])) {
                 $link['link_url'] = $channel['link'];
             }
             if (!$this->hardcode('name') and isset($channel['title'])) {
                 $link['link_name'] = $channel['title'];
             }
             if (!$this->hardcode('description')) {
                 if (isset($channel['tagline'])) {
                     $link['link_description'] = $channel['tagline'];
                 } elseif (isset($channel['description'])) {
                     $link['link_description'] = $channel['description'];
                 }
             }
             $this->settings = array_merge($this->settings, $this->flatten_array($channel));
             $this->settings['update/last'] = time();
             $ttl = $this->ttl();
             if (!is_null($ttl)) {
                 $this->settings['update/ttl'] = $ttl;
                 $this->settings['update/timed'] = 'feed';
             } else {
                 $this->settings['update/ttl'] = $this->automatic_ttl();
                 $this->settings['update/timed'] = 'automatically';
             }
             $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->settings['update/ttl'], $this);
             if (!isset($this->settings['update/hold']) or $this->settings['update/hold'] != 'ping') {
                 $this->settings['update/hold'] = 'scheduled';
             }
             $this->settings['update/unfinished'] = 'yes';
             $link['link_notes'] = $this->settings_to_notes();
             // Update the properties of the link from the feed information
             $result = wp_update_link($link);
             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->magpie->originals, $this);
             if (is_array($posts)) {
                 foreach ($posts as $key => $original) {
                     $item = $this->magpie->items[$key];
                     $post = new SyndicatedPost(array('simplepie' => $original, 'magpie' => $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';
             }
             $link['link_notes'] = $this->settings_to_notes();
             // Update the properties of the link from the feed information
             $result = wp_update_link($link);
             do_action("update_syndicated_feed_completed", $this->id, $this);
         }
     }
     return $new_count;
 }