PluginProbe
FeedWordPress / 2010.0127
FeedWordPress v2010.0127
trunk 0.8 0.9 0.91 0.95 0.96 0.97 0.98 0.981 0.99 0.991 0.992 0.993 2008.1030 2008.1101 2008.1105 2008.1214 2009.0612 2009.0613 2009.0618 2009.0707 2009.1111 2009.1112 2010.0127 2010.0528 All 65 releases
← All changes | feedwordpress.php +234 -332 2010.05282010.0127 View file →
@@ -2,19 +2,14 @@
2 2 /*
3 3 Plugin Name: FeedWordPress
4 4 Plugin URI: http://feedwordpress.radgeek.com/
5 5 Description: simple and flexible Atom/RSS syndication for WordPress
6 -Version: 2010.0528
6 +Version: 2010.0127
7 7 Author: Charles Johnson
8 8 Author URI: http://radgeek.com/
9 9 License: GPL
10 10 */
11 11
12 -/**
13 - * @package FeedWordPress
14 - * @version 2010.0528
15 - */
16 -
17 12 # This uses code derived from:
18 13 # - wp-rss-aggregate.php by Kellan Elliot-McCrea <kellan@protest.net>
19 14 # - HTTP Navigator 2 by Keyvan Minoukadeh <keyvan@k1m.com>
20 15 # - Ultra-Liberal Feed Finder by Mark Pilgrim <mark@diveintomark.org>
@@ -32,9 +27,9 @@
32 27 # or use a cron job.
33 28
34 29 # -- Don't change these unless you know what you're doing...
35 30
36 -define ('FEEDWORDPRESS_VERSION', '2010.0528');
31 +define ('FEEDWORDPRESS_VERSION', '2010.0127');
37 32 define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
38 33
39 34 // Defaults
40 35 define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
@@ -70,8 +65,9 @@
70 65 if (FEEDWORDPRESS_DEBUG) :
71 66 // Help us to pick out errors, if any.
72 67 ini_set('error_reporting', E_ALL & ~E_NOTICE);
73 68 ini_set('display_errors', true);
69 + define('MAGPIE_DEBUG', true);
74 70
75 71 // When testing we don't want cache issues to interfere. But this is
76 72 // a VERY BAD SETTING for a production server. Webmasters will eat your
77 73 // face for breakfast if you use it, and the baby Jesus will cry. So
@@ -76,25 +72,24 @@
76 72 // a VERY BAD SETTING for a production server. Webmasters will eat your
77 73 // face for breakfast if you use it, and the baby Jesus will cry. So
78 74 // make sure FEEDWORDPRESS_DEBUG is FALSE for any site that will be
79 75 // used for more than testing purposes!
80 - define('FEEDWORDPRESS_CACHE_AGE', 1);
81 - define('FEEDWORDPRESS_CACHE_LIFETIME', 1);
82 - define('FEEDWORDPRESS_FETCH_TIME_OUT', 60);
76 + define('MAGPIE_CACHE_AGE', 1);
83 77 else :
84 - // Hold onto data all day for conditional GET purposes,
85 - // but consider it stale after 1 min (requiring a conditional GET)
86 - define('FEEDWORDPRESS_CACHE_LIFETIME', 24*60*60);
87 - define('FEEDWORDPRESS_CACHE_AGE', 1*60);
88 - define('FEEDWORDPRESS_FETCH_TIME_OUT', 10);
78 + define('MAGPIE_DEBUG', false);
79 +
80 + define('MAGPIE_CACHE_AGE', 1*60);
89 81 endif;
90 82
91 -// Use our the cache settings that we want.
92 -add_filter('wp_feed_cache_transient_lifetime', array('FeedWordPress', 'cache_lifetime'));
83 +// Note that the rss-functions.php that comes prepackaged with WordPress is
84 +// old & busted. For the new hotness, drop a copy of rss.php from
85 +// this archive into wp-includes/rss.php
93 86
94 -// Ensure that we have SimplePie loaded up and ready to go.
95 -// We no longer need a MagpieRSS upgrade module. Hallelujah!
96 -require_once(ABSPATH . WPINC . '/feed.php');
87 +if (is_readable(ABSPATH . WPINC . '/rss.php')) :
88 + require_once (ABSPATH . WPINC . '/rss.php');
89 +else :
90 + require_once (ABSPATH . WPINC . '/rss-functions.php');
91 +endif;
97 92
98 93 if (isset($wp_db_version)) :
99 94 if ($wp_db_version >= FWP_SCHEMA_23) :
100 95 require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
@@ -181,15 +176,8 @@
181 176
182 177 # Filter in original permalinks if the user wants that
183 178 add_filter('post_link', 'syndication_permalink', 1);
184 179
185 - # When foreign URLs are used for permalinks in feeds or display
186 - # contexts, they need to be escaped properly.
187 - add_filter('the_permalink', 'syndication_permalink_escaped');
188 - add_filter('the_permalink_rss', 'syndication_permalink_escaped');
189 -
190 - add_filter('post_comments_feed_link', 'syndication_comments_feed_link');
191 -
192 180 # WTF? By default, wp_insert_link runs incoming link_url and link_rss
193 181 # URIs through default filters that include `wp_kses()`. But `wp_kses()`
194 182 # just happens to escape any occurrence of & to &amp; -- which just
195 183 # happens to fuck up any URI with a & to separate GET parameters.
@@ -198,8 +186,10 @@
198 186
199 187 # Admin menu
200 188 add_action('admin_menu', 'fwp_add_pages');
201 189 add_action('admin_notices', 'fwp_check_debug');
190 + add_action('admin_notices', 'fwp_check_magpie');
191 + add_action('init', 'feedwordpress_check_for_magpie_fix');
202 192
203 193 add_action('admin_menu', 'feedwordpress_add_post_edit_controls');
204 194 add_action('save_post', 'feedwordpress_save_post_edit_controls');
205 195
@@ -225,18 +215,14 @@
225 215 add_action('feedwordpress_check_feed', 'log_feedwordpress_check_feed', 100);
226 216 add_action('feedwordpress_update_complete', 'log_feedwordpress_update_complete', 100);
227 217 endif;
228 218
229 - if (FeedWordPress::update_requested()) :
230 - if (FEEDWORDPRESS_DEBUG) :
231 - add_action('post_syndicated_item', 'debug_out_feedwordpress_post', 100);
232 - add_action('update_syndicated_item', 'debug_out_feedwordpress_update_post', 100);
233 - add_action('feedwordpress_update', 'debug_out_feedwordpress_update_feeds', 100);
234 - add_action('feedwordpress_check_feed', 'debug_out_feedwordpress_check_feed', 100);
235 - add_action('feedwordpress_update_complete', 'debug_out_feedwordpress_update_complete', 100);
236 - endif;
237 -
238 - add_action('feedwordpress_check_feed_complete', 'debug_out_feedwordpress_feed_error', 100, 3);
219 + if (FeedWordPress::update_requested() and FEEDWORDPRESS_DEBUG) :
220 + add_action('post_syndicated_item', 'debug_out_feedwordpress_post', 100);
221 + add_action('update_syndicated_item', 'debug_out_feedwordpress_update_post', 100);
222 + add_action('feedwordpress_update', 'debug_out_feedwordpress_update_feeds', 100);
223 + add_action('feedwordpress_check_feed', 'debug_out_feedwordpress_check_feed', 100);
224 + add_action('feedwordpress_update_complete', 'debug_out_feedwordpress_update_complete', 100);
239 225 endif;
240 226
241 227 # Cron-less auto-update. Hooray!
242 228 $autoUpdateHook = get_option('feedwordpress_automatic_updates');
@@ -255,11 +241,44 @@
255 241 # Hook in the menus, which will just point to the upgrade interface
256 242 add_action('admin_menu', 'fwp_add_pages');
257 243 endif; // if (!FeedWordPress::needs_upgrade())
258 244
245 +function feedwordpress_check_for_magpie_fix () {
246 + if (isset($_POST['action']) and $_POST['action']=='fix_magpie_version') :
247 + FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_fix_magpie', /*capability=*/ 'edit_files');
248 +
249 + $back_to = $_SERVER['REQUEST_URI'];
250 + if (isset($_POST['ignore'])) :
251 + // kill error message by telling it we ignored the upgrade request for this version
252 + update_option('feedwordpress_magpie_ignored_upgrade_to', EXPECTED_MAGPIE_VERSION);
253 + $ret = 'ignored';
254 + elseif (isset($_POST['upgrade'])) :
255 + $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss.php";
256 + $destination = ABSPATH . WPINC . '/rss.php';
257 + $success = @copy($source, $destination);
258 +
259 + // Copy over rss-functions.php, too, to avoid collisions
260 + // on pre-lapsarian versions of WordPress.
261 + if ($success) :
262 + $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss-functions.php";
263 + $destination = ABSPATH . WPINC . '/rss-functions.php';
264 + $success = @copy($source, $destination);
265 + endif;
266 + $ret = (int) $success;
267 + endif;
268 +
269 + if (strpos($back_to, '?')===false) : $sep = '?';
270 + else : $sep = '&';
271 + endif;
272 +
273 + header("Location: {$back_to}{$sep}feedwordpress_magpie_fix=".$ret);
274 + exit;
275 + endif;
276 +} /* feedwordpress_check_for_magpie_fix() */
277 +
259 278 function feedwordpress_auto_update () {
260 279 if (FeedWordPress::stale()) :
261 - $feedwordpress = new FeedWordPress;
280 + $feedwordpress =& new FeedWordPress;
262 281 $feedwordpress->update();
263 282 endif;
264 283 } /* feedwordpress_auto_update () */
265 284
@@ -267,9 +286,9 @@
267 286 global $wpdb;
268 287
269 288 // Explicit update request in the HTTP request (e.g. from a cron job)
270 289 if (FeedWordPress::update_requested()) :
271 - $feedwordpress = new FeedWordPress;
290 + $feedwordpress =& new FeedWordPress;
272 291 $feedwordpress->update(FeedWordPress::update_requested_url());
273 292
274 293 if (FEEDWORDPRESS_DEBUG and count($wpdb->queries) > 0) :
275 294 $mysqlTime = 0.0;
@@ -366,33 +385,13 @@
366 385 .(is_null($delta) ? "Error: I don't syndicate that URI"
367 386 : implode(' and ', $mesg))."\n");
368 387 }
369 388
370 -function debug_out_feedwordpress_feed_error ($feed, $added, $dt) {
371 - if (is_wp_error($added)) :
372 - $mesgs = $added->get_error_messages();
373 - foreach ($mesgs as $mesg) :
374 - echo "[feedwordpress] Error updating [{$feed['link/uri']}]: $mesg\n";
375 - endforeach;
376 - endif;
377 -}
378 -
379 389 ################################################################################
380 390 ## TEMPLATE API: functions to make your templates syndication-aware ############
381 391 ################################################################################
382 392
383 -/**
384 - * is_syndicated: Tests whether the current post in a Loop context, or a post
385 - * given by ID number, was syndicated by FeedWordPress. Useful for templates
386 - * to determine whether or not to retrieve syndication-related meta-data in
387 - * displaying a post.
388 - *
389 - * @param int $id The post to check for syndicated status. Defaults to the current post in a Loop context.
390 - * @return bool TRUE if the post's meta-data indicates it was syndicated; FALSE otherwise
391 - */
392 -function is_syndicated ($id = NULL) {
393 - return (strlen(get_syndication_feed_id($id)) > 0);
394 -} /* function is_syndicated() */
393 +function is_syndicated ($id = NULL) { return (strlen(get_syndication_feed_id($id)) > 0); }
395 394
396 395 function get_syndication_source_link ($original = NULL, $id = NULL) {
397 396 if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
398 397 endif;
@@ -422,9 +421,8 @@
422 421 // Reassemble bit-by-bit with minimum of crufty elements
423 422 $url = (isset($bits['user'])?$bits['user'].'@':'')
424 423 .(isset($bits['host'])?$bits['host']:'')
425 424 .(isset($bits['path'])?$bits['path']:'')
426 - .(isset($uri_bits['port'])?':'.$uri_bits['port']:'')
427 425 .(isset($bits['query'])?'?'.$bits['query']:'');
428 426
429 427 if (strlen($url) > ($before+$after)) :
430 428 $url = substr($url, 0, $before).'…'.substr($url, 0 - $after, $after);
@@ -503,30 +501,22 @@
503 501 function get_syndication_feed_id ($id = NULL) { list($u) = get_post_custom_values('syndication_feed_id', $id); return $u; }
504 502 function the_syndication_feed_id ($id = NULL) { echo get_syndication_feed_id($id); }
505 503
506 504 $feedwordpress_linkcache = array (); // only load links from database once
507 -function get_syndication_feed_object ($id = NULL) {
508 - global $feedwordpress_linkcache;
509 505
510 - $link = NULL;
506 +function get_feed_meta ($key, $id = NULL) {
507 + global $wpdb, $feedwordpress_linkcache;
508 + $feed_id = get_syndication_feed_id($id);
511 509
512 - $feed_id = get_syndication_feed_id($id);
510 + $ret = NULL;
513 511 if (strlen($feed_id) > 0):
514 512 if (isset($feedwordpress_linkcache[$feed_id])) :
515 513 $link = $feedwordpress_linkcache[$feed_id];
516 514 else :
517 - $link = new SyndicatedLink($feed_id);
515 + $link =& new SyndicatedLink($feed_id);
518 516 $feedwordpress_linkcache[$feed_id] = $link;
519 517 endif;
520 - endif;
521 - return $link;
522 -}
523 518
524 -function get_feed_meta ($key, $id = NULL) {
525 - $ret = NULL;
526 -
527 - $link = get_syndication_feed_object($id);
528 - if (is_object($link) and isset($link->settings[$key])) :
529 519 $ret = $link->settings[$key];
530 520 endif;
531 521 return $ret;
532 522 } /* get_feed_meta() */
@@ -537,55 +527,13 @@
537 527 function the_syndication_permalink ($id = NULL) {
538 528 echo get_syndication_permalink($id);
539 529 }
540 530
541 -/**
542 - * get_local_permalink: returns a string containing the internal permalink
543 - * for a post (whether syndicated or not) on your local WordPress installation.
544 - * This may be useful if you want permalinks to point to the original source of
545 - * an article for most purposes, but want to retrieve a URL for the local
546 - * representation of the post for one or two limited purposes (for example,
547 - * linking to a comments page on your local aggregator site).
548 - *
549 - * @param $id The numerical ID of the post to get the permalink for. If empty,
550 - * defaults to the current post in a Loop context.
551 - * @return string The URL of the local permalink for this post.
552 - *
553 - * @uses get_permalink()
554 - * @global $feedwordpress_the_original_permalink
555 - *
556 - * @since 2010.0217
557 - */
558 -function get_local_permalink ($id = NULL) {
559 - global $feedwordpress_the_original_permalink;
560 -
561 - // get permalink, and thus activate filter and force global to be filled
562 - // with original URL.
563 - $url = get_permalink($id);
564 - return $feedwordpress_the_original_permalink;
565 -} /* get_local_permalink() */
566 -
567 -/**
568 - * the_original_permalink: displays the contents of get_original_permalink()
569 - *
570 - * @param $id The numerical ID of the post to get the permalink for. If empty,
571 - * defaults to the current post in a Loop context.
572 - *
573 - * @uses get_local_permalinks()
574 - * @uses apply_filters
575 - *
576 - * @since 2010.0217
577 - */
578 -function the_local_permalink ($id = NULL) {
579 - print apply_filters('the_permalink', get_local_permalink($id));
580 -} /* function the_local_permalink() */
581 -
582 531 ################################################################################
583 532 ## FILTERS: syndication-aware handling of post data for templates and feeds ####
584 533 ################################################################################
585 534
586 535 $feedwordpress_the_syndicated_content = NULL;
587 -$feedwordpress_the_original_permalink = NULL;
588 536
589 537 function feedwordpress_preserve_syndicated_content ($text) {
590 538 global $feedwordpress_the_syndicated_content;
591 539
@@ -636,131 +584,17 @@
636 584 <?php
637 585 endif;
638 586 }
639 587
640 -/**
641 - * syndication_permalink: Allow WordPress to use the original remote URL of
642 - * syndicated posts as their permalink. Can be turned on or off by by setting in
643 - * Syndication => Posts & Links. Saves the old internal permalink in a global
644 - * variable for later use.
645 - *
646 - * @param string $permalink The internal permalink
647 - * @return string The new permalink. Same as the old if the post is not
648 - * syndicated, or if FWP is set to use internal permalinks, or if the post
649 - * was syndicated, but didn't have a proper permalink recorded.
650 - *
651 - * @uses FeedWordPress::munge_permalinks()
652 - * @uses get_syndication_permalink()
653 - * @global $feedwordpress_the_original_permalink
654 - */
655 588 function syndication_permalink ($permalink = '') {
656 - global $feedwordpress_the_original_permalink;
657 -
658 - // Save the local permalink in case we need to retrieve it later.
659 - $feedwordpress_the_original_permalink = $permalink;
660 -
661 - // Map this permalink to a post ID so we can get the correct permalink
662 - // even outside of the Post Loop. Props Björn.
663 - $id = url_to_postid($permalink);
664 -
665 - $munge = false;
666 - $link = get_syndication_feed_object($id);
667 - if (is_object($link)) :
668 - $munge = ($link->setting('munge permalink', 'munge_permalink', 'yes') != 'no');
589 + if (get_option('feedwordpress_munge_permalink') != 'no'):
590 + $uri = get_syndication_permalink();
591 + return ((strlen($uri) > 0) ? $uri : $permalink);
592 + else:
593 + return $permalink;
669 594 endif;
595 +} // function syndication_permalink ()
670 596
671 - if ($munge):
672 - $uri = get_syndication_permalink($id);
673 - $permalink = ((strlen($uri) > 0) ? $uri : $permalink);
674 - endif;
675 - return $permalink;
676 -} /* function syndication_permalink () */
677 -
678 -/**
679 - * syndication_permalink_escaped: Escape XML special characters in syndicated
680 - * permalinks when used in feed contexts and HTML display contexts.
681 - *
682 - * @param string $permalink
683 - * @return string
684 - *
685 - * @uses is_syndicated()
686 - * @uses FeedWordPress::munge_permalinks()
687 - *
688 - */
689 -function syndication_permalink_escaped ($permalink) {
690 - if (is_syndicated() and FeedWordPress::munge_permalinks()) :
691 - // This is a foreign link; WordPress can't vouch for its not
692 - // having any entities that need to be &-escaped. So we'll do
693 - // it here.
694 - $permalink = esc_html($permalink);
695 - endif;
696 - return $permalink;
697 -} /* function syndication_permalink_escaped() */
698 -
699 -/**
700 - * syndication_comments_feed_link: Escape XML special characters in comments
701 - * feed links
702 - *
703 - * @param string $link
704 - * @return string
705 - *
706 - * @uses is_syndicated()
707 - * @uses FeedWordPress::munge_permalinks()
708 - */
709 -function syndication_comments_feed_link ($link) {
710 - global $feedwordpress_the_original_permalink, $id;
711 -
712 - if (is_syndicated() and FeedWordPress::munge_permalinks()) :
713 - // If the source post provided a comment feed URL using
714 - // wfw:commentRss or atom:link/@rel="replies" we can make use of
715 - // that value here.
716 - $source = get_syndication_feed_object();
717 - $replacement = NULL;
718 - if ($source->setting('munge comments feed links', 'munge_comments_feed_links', 'yes') != 'no') :
719 - $commentFeeds = get_post_custom_values('wfw:commentRSS');
720 - if (
721 - is_array($commentFeeds)
722 - and (count($commentFeeds) > 0)
723 - and (strlen($commentFeeds[0]) > 0)
724 - ) :
725 - $replacement = $commentFeeds[0];
726 -
727 - // This is a foreign link; WordPress can't vouch for its not
728 - // having any entities that need to be &-escaped. So we'll do it
729 - // here.
730 - $replacement = esc_html($replacement);
731 - endif;
732 - endif;
733 -
734 - if (is_null($replacement)) :
735 - // Q: How can we get the proper feed format, since the
736 - // format is, stupidly, not passed to the filter?
737 - // A: Kludge kludge kludge kludge!
738 - $fancy_permalinks = ('' != get_option('permalink_structure'));
739 - if ($fancy_permalinks) :
740 - preg_match('|/feed(/([^/]+))?/?$|', $link, $ref);
741 -
742 - $format = (isset($ref[2]) ? $ref[2] : '');
743 - if (strlen($format) == 0) : $format = get_default_feed(); endif;
744 -
745 - $replacement = trailingslashit($feedwordpress_the_original_permalink) . 'feed';
746 - if ($format != get_default_feed()) :
747 - $replacement .= '/'.$format;
748 - endif;
749 - $replacement = user_trailingslashit($replacement, 'single_feed');
750 - else :
751 - // No fancy permalinks = no problem
752 - // WordPress doesn't call get_permalink() to
753 - // generate the comment feed URL, so the
754 - // comments feed link is never munged by FWP.
755 - endif;
756 - endif;
757 -
758 - if (!is_null($replacement)) : $link = $replacement; endif;
759 - endif;
760 - return $link;
761 -} /* function syndication_comments_feed_link() */
762 -
763 597 ################################################################################
764 598 ## ADMIN MENU ADD-ONS: register Dashboard management pages #####################
765 599 ################################################################################
766 600
@@ -803,8 +637,97 @@
803 637 <?php
804 638 endif;
805 639 } /* function fwp_check_debug () */
806 640
641 +define('EXPECTED_MAGPIE_VERSION', '2010.0122');
642 +function fwp_check_magpie () {
643 + if (isset($_REQUEST['feedwordpress_magpie_fix'])) :
644 + if ($_REQUEST['feedwordpress_magpie_fix']=='ignored') :
645 +?>
646 +<div class="updated fade">
647 +<p>O.K., we'll ignore the problem for now. FeedWordPress will not display any
648 +more error messages.</p>
649 +</div>
650 +<?php
651 + elseif ((bool) $_REQUEST['feedwordpress_magpie_fix']) :
652 +?>
653 +<div class="updated fade">
654 +<p>Congratulations! Your MagpieRSS has been successfully upgraded to the version
655 +shipped with FeedWordPress.</p>
656 +</div>
657 +<?php
658 + else :
659 + $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss.php";
660 + $destination = ABSPATH . WPINC . '/rss.php';
661 + $cmd = "cp '".htmlspecialchars(addslashes($source))."' '".htmlspecialchars(addslashes($destination))."'";
662 + $cmd = wordwrap($cmd, /*width=*/ 75, /*break=*/ " \\\n\t");
663 +
664 +?>
665 +<div class="error">
666 +<p><strong>FeedWordPress was unable to automatically upgrade your copy of MagpieRSS.</strong></p>
667 +<p>It's likely that you need to change the file permissions on <code><?php print htmlspecialchars($source); ?></code>
668 +to allow FeedWordPress to overwrite it.</p>
669 +<p><strong>To perform the upgrade manually,</strong> you can
670 +use a SFTP or FTP client to upload a copy of <code>rss.php</code> from the
671 +<code>MagpieRSS-upgrades/</code> directory of your FeedWordPress archive so that
672 +it overwrites <code><?php print htmlspecialchars($destination); ?></code>. Or,
673 +if your web host provides shell access, you can issue the following command from
674 +a command prompt to perform the upgrade:</p>
675 +<pre>
676 +<samp>$</samp> <kbd><?php print $cmd; ?></kbd>
677 +</pre>
678 +<p><strong>If you've fixed the file permissions,</strong> you can try the
679 +automatic upgrade again.</p>
680 +
681 +<?php feedwordpress_upgrade_old_and_busted_buttons(); ?>
682 +</div>
683 +<?php
684 + endif;
685 + else :
686 + $magpie_version = FeedWordPress::magpie_version();
687 +
688 + $ignored = get_option('feedwordpress_magpie_ignored_upgrade_to');
689 + if (EXPECTED_MAGPIE_VERSION != $magpie_version and EXPECTED_MAGPIE_VERSION != $ignored) :
690 + if (current_user_can('edit_files')) :
691 + $youAre = 'you are';
692 + $itIsRecommendedThatYou = 'It is <strong>strongly recommended</strong> that you';
693 + else :
694 + $youAre = 'this site is';
695 + $itIsRecommendedThatYou = 'You may want to contact the administrator of the site; it is <strong>strongly recommended</strong> that they';
696 + endif;
697 + print '<div class="error">';
698 +?>
699 +<p style="font-style: italic"><strong>FeedWordPress has detected that <?php print $youAre; ?> currently using a version of
700 +MagpieRSS other than the upgraded version that ships with this version of FeedWordPress.</strong></p>
701 +<ul>
702 +<li><strong>Currently running:</strong> MagpieRSS <?php print $magpie_version; ?></li>
703 +<li><strong>Version included with FeedWordPress <?php print FEEDWORDPRESS_VERSION; ?>:</strong> MagpieRSS <?php print EXPECTED_MAGPIE_VERSION; ?></li>
704 +</ul>
705 +<p><?php print $itIsRecommendedThatYou; ?> install the upgraded
706 +version of MagpieRSS supplied with FeedWordPress. The version of
707 +MagpieRSS that ships with WordPress is very old and buggy, and
708 +encounters a number of errors when trying to parse modern Atom
709 +and RSS feeds.</p>
710 +<?php
711 + feedwordpress_upgrade_old_and_busted_buttons();
712 + print '</div>';
713 + endif;
714 + endif;
715 +}
716 +
717 +function feedwordpress_upgrade_old_and_busted_buttons() {
718 + if (current_user_can('edit_files')) :
719 +?>
720 +<form action="" method="post"><div>
721 +<?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_fix_magpie'); ?>
722 +<input type="hidden" name="action" value="fix_magpie_version" />
723 +<input class="button-secondary" type="submit" name="ignore" value="<?php _e('Ignore this problem'); ?>" />
724 +<input class="button-primary" type="submit" name="upgrade" value="<?php _e('Upgrade'); ?>" />
725 +</div></form>
726 +<?php
727 + endif;
728 +}
729 +
807 730 ################################################################################
808 731 ## fwp_hold_pings() and fwp_release_pings(): Outbound XML-RPC ping reform ####
809 732 ## ... 'coz it's rude to send 500 pings the first time your aggregator runs ####
810 733 ################################################################################
@@ -873,10 +796,10 @@
873 796
874 797 if (is_syndicated($post->ID)) :
875 798 ?>
876 799 <p>This is a syndicated post, which originally appeared at
877 - <cite><?php print esc_html(get_syndication_source(NULL, $post->ID)); ?></cite>.
878 - <a href="<?php print esc_html(get_syndication_permalink($post->ID)); ?>">View original post</a>.</p>
800 + <cite><?php print wp_specialchars(get_syndication_source(NULL, $post->ID)); ?></cite>.
801 + <a href="<?php print wp_specialchars(get_syndication_permalink($post->ID)); ?>">View original post</a>.</p>
879 802
880 803 <p><input type="hidden" name="feedwordpress_noncename" id="feedwordpress_noncename" value="<?php print wp_create_nonce(plugin_basename(__FILE__)); ?>" />
881 804 <label><input type="checkbox" name="freeze_updates" value="yes" <?php if ($frozen_post) : ?>checked="checked"<?php endif; ?> /> <strong>Manual editing.</strong>
882 805 If set, FeedWordPress will not overwrite the changes you make manually
@@ -962,9 +885,9 @@
962 885 function FeedWordPress () {
963 886 $this->feeds = array ();
964 887 $links = FeedWordPress::syndicated_links();
965 888 if ($links): foreach ($links as $link):
966 - $this->feeds[] = new SyndicatedLink($link);
889 + $this->feeds[] =& new SyndicatedLink($link);
967 890 endforeach; endif;
968 891 } // FeedWordPress::FeedWordPress ()
969 892
970 893 # function update (): polls for updates on one or more Contributor feeds
@@ -1068,12 +991,10 @@
1068 991 $start_ts = time();
1069 992 $added = $feed->poll($crash_ts);
1070 993 do_action('feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts);
1071 994
1072 - if (is_array($added)) : // Success
1073 - if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
1074 - if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
1075 - endif;
995 + if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
996 + if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
1076 997 endif;
1077 998 endforeach;
1078 999
1079 1000 do_action('feedwordpress_update_complete', $delta);
@@ -1227,19 +1148,8 @@
1227 1148 $ret = get_option('feedwordpress_use_aggregator_source_data');
1228 1149 return apply_filters('syndicated_post_use_aggregator_source_data', ($ret=='yes'));
1229 1150 }
1230 1151
1231 - /**
1232 - * FeedWordPress::munge_permalinks: check whether or not FeedWordPress
1233 - * should rewrite permalinks for syndicated items to reflect their
1234 - * original location.
1235 - *
1236 - * @return bool TRUE if FeedWordPress SHOULD rewrite permalinks; FALSE otherwise
1237 - */
1238 - /*static*/ function munge_permalinks () {
1239 - return (get_option('feedwordpress_munge_permalink', /*default=*/ 'yes') != 'no');
1240 - } /* FeedWordPress::munge_permalinks() */
1241 -
1242 1152 function syndicated_links () {
1243 1153 $contributors = FeedWordPress::link_category_id();
1244 1154 if (function_exists('get_bookmarks')) :
1245 1155 $links = get_bookmarks(array("category" => $contributors));
@@ -1323,14 +1233,58 @@
1323 1233
1324 1234 if (is_null($from) or $from <= 0.96) : $from = 0.96; endif;
1325 1235
1326 1236 switch ($from) :
1327 - case 0.96:
1328 - // Dropping legacy upgrade code. If anyone is still
1329 - // using 0.96 and just now decided to upgrade, well, I'm
1330 - // sorry about that. You'll just have to cope with a few
1331 - // duplicate posts.
1237 + case 0.96: // account for changes to syndication custom values and guid
1238 + echo "<p>Upgrading database from {$from} to ".FEEDWORDPRESS_VERSION."...</p>\n";
1332 1239
1240 + $cat_id = FeedWordPress::link_category_id();
1241 +
1242 + // Avoid duplicates
1243 + $wpdb->query("DELETE FROM `{$wpdb->postmeta}` WHERE meta_key = 'syndication_feed_id'");
1244 +
1245 + // Look up all the link IDs
1246 + $wpdb->query("
1247 + CREATE TEMPORARY TABLE tmp_custom_values
1248 + SELECT
1249 + NULL AS meta_id,
1250 + post_id,
1251 + 'syndication_feed_id' AS meta_key,
1252 + link_id AS meta_value
1253 + FROM `{$wpdb->postmeta}`, `{$wpdb->links}`
1254 + WHERE
1255 + meta_key='syndication_feed'
1256 + AND meta_value=link_rss
1257 + AND link_category = {$cat_id}
1258 + ");
1259 +
1260 + // Now attach them to their posts
1261 + $wpdb->query("INSERT INTO `{$wpdb->postmeta}` SELECT * FROM tmp_custom_values");
1262 +
1263 + // And clean up after ourselves.
1264 + $wpdb->query("DROP TABLE tmp_custom_values");
1265 +
1266 + // Now fix the guids to avoid duplicate posts
1267 + echo "<ul>";
1268 + foreach ($this->feeds as $syndicatedLink) :
1269 + $feed = $syndicatedLink->settings;
1270 + echo "<li>Fixing post meta-data for <cite>".$feed['link/name']."</cite> &#8230; "; flush();
1271 + $rss = @fetch_rss($feed['link/uri']);
1272 + if (is_array($rss->items)) :
1273 + foreach ($rss->items as $item) :
1274 + $post = new SyndicatedPost($item, $syndicatedLink);
1275 + $guid = $wpdb->escape($post->guid()); // new GUID algorithm
1276 + $link = $wpdb->escape($item['link']);
1277 +
1278 + $wpdb->query("
1279 + UPDATE `{$wpdb->posts}` SET guid='{$guid}' WHERE guid='{$link}'
1280 + ");
1281 + endforeach;
1282 + endif;
1283 + echo "<strong>complete.</strong></li>\n";
1284 + endforeach;
1285 + echo "</ul>\n";
1286 +
1333 1287 // Mark the upgrade as successful.
1334 1288 update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1335 1289 endswitch;
1336 1290 echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
@@ -1335,27 +1289,8 @@
1335 1289 endswitch;
1336 1290 echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
1337 1291 } /* FeedWordPress::upgrade_database() */
1338 1292
1339 - function has_guid_index () {
1340 - global $wpdb;
1341 -
1342 - $found = false; // Guilty until proven innocent.
1343 -
1344 - $results = $wpdb->get_results("
1345 - SHOW INDEXES FROM {$wpdb->posts}
1346 - ");
1347 - if ($results) :
1348 - foreach ($results as $index) :
1349 - if (isset($index->Column_name)
1350 - and ('guid' == $index->Column_name)) :
1351 - $found = true;
1352 - endif;
1353 - endforeach;
1354 - endif;
1355 - return $found;
1356 - } /* FeedWordPress::has_guid_index () */
1357 -
1358 1293 function create_guid_index () {
1359 1294 global $wpdb;
1360 1295
1361 1296 $wpdb->query("
@@ -1362,71 +1297,29 @@
1362 1297 CREATE INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}(guid)
1363 1298 ");
1364 1299 } /* FeedWordPress::create_guid_index () */
1365 1300
1366 - function remove_guid_index () {
1367 - global $wpdb;
1368 -
1369 - $wpdb->query("
1370 - DROP INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}
1371 - ");
1372 - }
1373 -
1374 - /*static*/ function fetch ($url) {
1375 - require_once (ABSPATH . WPINC . '/class-feed.php');
1376 - $feed = new SimplePie();
1377 - $feed->set_feed_url($url);
1378 - $feed->set_cache_class('WP_Feed_Cache');
1379 - $feed->set_file_class('WP_SimplePie_File');
1380 - $feed->set_cache_duration(FeedWordPress::cache_duration());
1381 - $feed->init();
1382 - $feed->handle_content_type();
1383 -
1384 - if ($feed->error()) :
1385 - $ret = new WP_Error('simplepie-error', $feed->error());
1386 - else :
1387 - $ret = $feed;
1388 - endif;
1389 - return $ret;
1390 - } /* FeedWordPress::fetch () */
1391 -
1392 1301 function clear_cache () {
1393 1302 global $wpdb;
1394 1303
1395 - // The WordPress SimplePie module stores its cached feeds as
1396 - // transient records in the options table. The data itself is
1397 - // stored in `_transient_feed_{md5 of url}` and the last-modified
1398 - // timestamp in `_transient_feed_mod_{md5 of url}`. Timeouts for
1399 - // these records are stored in `_transient_timeout_feed_{md5}`.
1400 - // Since the md5 is always 32 characters in length, the
1401 - // option_name is always over 32 characters.
1304 + // MagpieRSS stores its cached feeds in options table rows with
1305 + // name = `rss_{md5 of url}` and timestamps for cached feeds in
1306 + // table rows with name = `rss_{md5 of url}_ts`. The md5 is
1307 + // always 32 characters in length, so the total option_name is
1308 + // always over 32 characters.
1402 1309 $wpdb->query("
1403 1310 DELETE FROM {$wpdb->options}
1404 - WHERE option_name LIKE '_transient%_feed_%' AND LENGTH(option_name) > 32
1311 + WHERE LOCATE('rss_', option_name) AND LENGTH(option_name) > 32
1405 1312 ");
1406 1313 } /* FeedWordPress::clear_cache () */
1407 1314
1408 - function cache_duration () {
1409 - $duration = NULL;
1410 - if (defined('FEEDWORDPRESS_CACHE_AGE')) :
1411 - $duration = FEEDWORDPRESS_CACHE_AGE;
1315 + function magpie_version () {
1316 + if (!defined('MAGPIE_VERSION')) : $magpie_version = $GLOBALS['wp_version'].'-default';
1317 + else : $magpie_version = MAGPIE_VERSION;
1412 1318 endif;
1413 - return $duration;
1319 + return $magpie_version;
1414 1320 }
1415 - function cache_lifetime ($duration) {
1416 - // Check for explicit setting of a lifetime duration
1417 - if (defined('FEEDWORDPRESS_CACHE_LIFETIME')) :
1418 - $duration = FEEDWORDPRESS_CACHE_LIFETIME;
1419 1321
1420 - // Fall back to the cache freshness duration
1421 - elseif (defined('FEEDWORDPRESS_CACHE_AGE')) :
1422 - $duration = FEEDWORDPRESS_CACHE_AGE;
1423 - endif;
1424 -
1425 - // Fall back to WordPress default
1426 - return $duration;
1427 - } /* FeedWordPress::cache_lifetime () */
1428 -
1429 1322 # Utility functions for handling text settings
1430 1323 function negative ($f, $setting) {
1431 1324 $nego = array ('n', 'no', 'f', 'false');
1432 1325 return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
@@ -1441,12 +1334,17 @@
1441 1334 # Internal debugging functions
1442 1335 function critical_bug ($varname, $var, $line) {
1443 1336 global $wp_version;
1444 1337
1338 + if (defined('MAGPIE_VERSION')) : $mv = MAGPIE_VERSION;
1339 + else : $mv = 'WordPress '.$wp_version.' default.';
1340 + endif;
1341 +
1445 1342 echo '<p>There may be a bug in FeedWordPress. Please <a href="'.FEEDWORDPRESS_AUTHOR_CONTACT.'">contact the author</a> and paste the following information into your e-mail:</p>';
1446 1343 echo "\n<plaintext>";
1447 1344 echo "Triggered at line # ".$line."\n";
1448 1345 echo "FeedWordPress version: ".FEEDWORDPRESS_VERSION."\n";
1346 + echo "MagpieRSS version: {$mv}\n";
1449 1347 echo "WordPress version: {$wp_version}\n";
1450 1348 echo "PHP version: ".phpversion()."\n";
1451 1349 echo "\n";
1452 1350 echo $varname.": "; var_dump($var); echo "\n";
@@ -1472,9 +1370,9 @@
1472 1370 return $args;
1473 1371 }
1474 1372
1475 1373 function feedwordpress_pong ($args) {
1476 - $feedwordpress = new FeedWordPress;
1374 + $feedwordpress =& new FeedWordPress;
1477 1375 $delta = @$feedwordpress->update($args[1]);
1478 1376 if (is_null($delta)):
1479 1377 return array('flerror' => true, 'message' => "Sorry. I don't syndicate <$args[1]>.");
1480 1378 else:
@@ -1485,9 +1383,13 @@
1485 1383 return array('flerror' => false, 'message' => "Thanks for the ping.".implode(' and', $mesg));
1486 1384 endif;
1487 1385 }
1488 1386
1489 -require_once(dirname(__FILE__) . '/relative_uri.class.php');
1387 +# The upgraded MagpieRSS also uses this class. So if we have it loaded
1388 +# in, don't load it again.
1389 +if (!class_exists('Relative_URI')) {
1390 + require_once(dirname(__FILE__) . '/relative_uri.class.php');
1391 +}
1490 1392
1491 1393 // take your best guess at the realname and e-mail, given a string
1492 1394 define('FWP_REGEX_EMAIL_ADDY', '([^@"(<\s]+@[^"@(<\s]+\.[^"@(<\s]+)');
1493 1395 define('FWP_REGEX_EMAIL_NAME', '("([^"]*)"|([^"<(]+\S))');