PluginProbe
FeedWordPress / 2009.1111
FeedWordPress v2009.1111
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 +238 -428 2010.05282009.1111 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: 2009.1111
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', '2009.0803');
37 32 define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
38 33
39 34 // Defaults
40 35 define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
@@ -64,14 +59,14 @@
64 59 define ('FWP_SCHEMA_25', 7558); // Database schema # for WP 2.5
65 60 define ('FWP_SCHEMA_26', 8201); // Database schema # for WP 2.6
66 61 define ('FWP_SCHEMA_27', 9872); // Database schema # for WP 2.7
67 62 define ('FWP_SCHEMA_28', 11548); // Database schema # for WP 2.8
68 -define ('FWP_SCHEMA_29', 12329); // Database schema # for WP 2.9
69 63
70 64 if (FEEDWORDPRESS_DEBUG) :
71 65 // Help us to pick out errors, if any.
72 66 ini_set('error_reporting', E_ALL & ~E_NOTICE);
73 67 ini_set('display_errors', true);
68 + define('MAGPIE_DEBUG', true);
74 69
75 70 // When testing we don't want cache issues to interfere. But this is
76 71 // a VERY BAD SETTING for a production server. Webmasters will eat your
77 72 // face for breakfast if you use it, and the baby Jesus will cry. So
@@ -76,25 +71,24 @@
76 71 // a VERY BAD SETTING for a production server. Webmasters will eat your
77 72 // face for breakfast if you use it, and the baby Jesus will cry. So
78 73 // make sure FEEDWORDPRESS_DEBUG is FALSE for any site that will be
79 74 // 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);
75 + define('MAGPIE_CACHE_AGE', 1);
83 76 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);
77 + define('MAGPIE_DEBUG', false);
78 +
79 + define('MAGPIE_CACHE_AGE', 1*60);
89 80 endif;
90 81
91 -// Use our the cache settings that we want.
92 -add_filter('wp_feed_cache_transient_lifetime', array('FeedWordPress', 'cache_lifetime'));
82 +// Note that the rss-functions.php that comes prepackaged with WordPress is
83 +// old & busted. For the new hotness, drop a copy of rss.php from
84 +// this archive into wp-includes/rss.php
93 85
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');
86 +if (is_readable(ABSPATH . WPINC . '/rss.php')) :
87 + require_once (ABSPATH . WPINC . '/rss.php');
88 +else :
89 + require_once (ABSPATH . WPINC . '/rss-functions.php');
90 +endif;
97 91
98 92 if (isset($wp_db_version)) :
99 93 if ($wp_db_version >= FWP_SCHEMA_23) :
100 94 require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
@@ -127,20 +121,13 @@
127 121 else : // Something went wrong. Let's just guess.
128 122 $fwp_path = 'feedwordpress';
129 123 endif;
130 124
131 -function feedwordpress_admin_scripts () {
132 - wp_enqueue_script('post'); // for magic tag and category boxes
133 - wp_enqueue_script('admin-forms'); // for checkbox selection
134 -}
135 -
136 125 // If this is a FeedWordPress admin page, queue up scripts for AJAX functions that FWP uses
137 126 // If it is a display page or a non-FeedWordPress admin page, don't.
138 127 if (is_admin() and isset($_REQUEST['page']) and preg_match("|^{$fwp_path}/|", $_REQUEST['page'])) :
139 128 if (function_exists('wp_enqueue_script')) :
140 - if (FeedWordPressCompatibility::test_version(FWP_SCHEMA_29)) :
141 - add_action('admin_print_scripts', 'feedwordpress_admin_scripts');
142 - elseif (FeedWordPressCompatibility::test_version(FWP_SCHEMA_25)) :
129 + if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
143 130 wp_enqueue_script('post'); // for magic tag and category boxes
144 131 wp_enqueue_script('thickbox'); // for fold-up boxes
145 132 wp_enqueue_script('admin-forms'); // for checkbox selection
146 133 else :
@@ -181,15 +168,8 @@
181 168
182 169 # Filter in original permalinks if the user wants that
183 170 add_filter('post_link', 'syndication_permalink', 1);
184 171
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 172 # WTF? By default, wp_insert_link runs incoming link_url and link_rss
193 173 # URIs through default filters that include `wp_kses()`. But `wp_kses()`
194 174 # just happens to escape any occurrence of & to &amp; -- which just
195 175 # happens to fuck up any URI with a & to separate GET parameters.
@@ -198,12 +178,11 @@
198 178
199 179 # Admin menu
200 180 add_action('admin_menu', 'fwp_add_pages');
201 181 add_action('admin_notices', 'fwp_check_debug');
182 + add_action('admin_notices', 'fwp_check_magpie');
183 + add_action('init', 'feedwordpress_check_for_magpie_fix');
202 184
203 - add_action('admin_menu', 'feedwordpress_add_post_edit_controls');
204 - add_action('save_post', 'feedwordpress_save_post_edit_controls');
205 -
206 185 # Inbound XML-RPC update methods
207 186 add_filter('xmlrpc_methods', 'feedwordpress_xmlrpc_hook');
208 187
209 188 # Outbound XML-RPC ping reform
@@ -225,18 +204,14 @@
225 204 add_action('feedwordpress_check_feed', 'log_feedwordpress_check_feed', 100);
226 205 add_action('feedwordpress_update_complete', 'log_feedwordpress_update_complete', 100);
227 206 endif;
228 207
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);
208 + if (FeedWordPress::update_requested() and FEEDWORDPRESS_DEBUG) :
209 + add_action('post_syndicated_item', 'debug_out_feedwordpress_post', 100);
210 + add_action('update_syndicated_item', 'debug_out_feedwordpress_update_post', 100);
211 + add_action('feedwordpress_update', 'debug_out_feedwordpress_update_feeds', 100);
212 + add_action('feedwordpress_check_feed', 'debug_out_feedwordpress_check_feed', 100);
213 + add_action('feedwordpress_update_complete', 'debug_out_feedwordpress_update_complete', 100);
239 214 endif;
240 215
241 216 # Cron-less auto-update. Hooray!
242 217 $autoUpdateHook = get_option('feedwordpress_automatic_updates');
@@ -255,44 +230,55 @@
255 230 # Hook in the menus, which will just point to the upgrade interface
256 231 add_action('admin_menu', 'fwp_add_pages');
257 232 endif; // if (!FeedWordPress::needs_upgrade())
258 233
234 +function feedwordpress_check_for_magpie_fix () {
235 + if (isset($_POST['action']) and $_POST['action']=='fix_magpie_version') :
236 + FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_fix_magpie', /*capability=*/ 'edit_files');
237 +
238 + $back_to = $_SERVER['REQUEST_URI'];
239 + if (isset($_POST['ignore'])) :
240 + // kill error message by telling it we ignored the upgrade request for this version
241 + update_option('feedwordpress_magpie_ignored_upgrade_to', EXPECTED_MAGPIE_VERSION);
242 + $ret = 'ignored';
243 + elseif (isset($_POST['upgrade'])) :
244 + $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss.php";
245 + $destination = ABSPATH . WPINC . '/rss.php';
246 + $success = @copy($source, $destination);
247 +
248 + // Copy over rss-functions.php, too, to avoid collisions
249 + // on pre-lapsarian versions of WordPress.
250 + if ($success) :
251 + $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss-functions.php";
252 + $destination = ABSPATH . WPINC . '/rss-functions.php';
253 + $success = @copy($source, $destination);
254 + endif;
255 + $ret = (int) $success;
256 + endif;
257 +
258 + if (strpos($back_to, '?')===false) : $sep = '?';
259 + else : $sep = '&';
260 + endif;
261 +
262 + header("Location: {$back_to}{$sep}feedwordpress_magpie_fix=".$ret);
263 + exit;
264 + endif;
265 +} /* feedwordpress_check_for_magpie_fix() */
266 +
259 267 function feedwordpress_auto_update () {
260 268 if (FeedWordPress::stale()) :
261 - $feedwordpress = new FeedWordPress;
269 + $feedwordpress =& new FeedWordPress;
262 270 $feedwordpress->update();
263 271 endif;
264 272 } /* feedwordpress_auto_update () */
265 273
266 274 function feedwordpress_update_magic_url () {
267 - global $wpdb;
268 -
269 275 // Explicit update request in the HTTP request (e.g. from a cron job)
270 276 if (FeedWordPress::update_requested()) :
271 - $feedwordpress = new FeedWordPress;
277 + $feedwordpress =& new FeedWordPress;
272 278 $feedwordpress->update(FeedWordPress::update_requested_url());
273 279
274 - if (FEEDWORDPRESS_DEBUG and count($wpdb->queries) > 0) :
275 - $mysqlTime = 0.0;
276 - $byTime = array();
277 - foreach ($wpdb->queries as $query) :
278 - $time = $query[1] * 1000000.0;
279 - $mysqlTime += $query[1];
280 - if (!isset($byTime[$time])) : $byTime[$time] = array(); endif;
281 - $byTime[$time][] = $query[0]. ' // STACK: ' . $query[2];
282 - endforeach;
283 - krsort($byTime);
284 -
285 - foreach ($byTime as $time => $querySet) :
286 - foreach ($querySet as $query) :
287 - print "[".(sprintf('%4.4f', $time/1000.0)) . "ms] $query\n";
288 - endforeach;
289 - endforeach;
290 - echo "[feedwordpress] $wpdb->num_queries queries. $mysqlTime seconds in MySQL. Total of "; timer_stop(1); print " seconds.";
291 - endif;
292 -
293 -
294 - // Magic URL should return nothing but a 200 OK header packet
280 + // Magic URL should return nothing but a 200 OK header packet
295 281 // when successful.
296 282 exit;
297 283 endif;
298 284 } /* feedwordpress_magic_update_url () */
@@ -366,33 +352,13 @@
366 352 .(is_null($delta) ? "Error: I don't syndicate that URI"
367 353 : implode(' and ', $mesg))."\n");
368 354 }
369 355
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 356 ################################################################################
380 357 ## TEMPLATE API: functions to make your templates syndication-aware ############
381 358 ################################################################################
382 359
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() */
360 +function is_syndicated ($id = NULL) { return (strlen(get_syndication_feed_id($id)) > 0); }
395 361
396 362 function get_syndication_source_link ($original = NULL, $id = NULL) {
397 363 if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
398 364 endif;
@@ -422,9 +388,8 @@
422 388 // Reassemble bit-by-bit with minimum of crufty elements
423 389 $url = (isset($bits['user'])?$bits['user'].'@':'')
424 390 .(isset($bits['host'])?$bits['host']:'')
425 391 .(isset($bits['path'])?$bits['path']:'')
426 - .(isset($uri_bits['port'])?':'.$uri_bits['port']:'')
427 392 .(isset($bits['query'])?'?'.$bits['query']:'');
428 393
429 394 if (strlen($url) > ($before+$after)) :
430 395 $url = substr($url, 0, $before).'…'.substr($url, 0 - $after, $after);
@@ -503,30 +468,22 @@
503 468 function get_syndication_feed_id ($id = NULL) { list($u) = get_post_custom_values('syndication_feed_id', $id); return $u; }
504 469 function the_syndication_feed_id ($id = NULL) { echo get_syndication_feed_id($id); }
505 470
506 471 $feedwordpress_linkcache = array (); // only load links from database once
507 -function get_syndication_feed_object ($id = NULL) {
508 - global $feedwordpress_linkcache;
509 472
510 - $link = NULL;
473 +function get_feed_meta ($key, $id = NULL) {
474 + global $wpdb, $feedwordpress_linkcache;
475 + $feed_id = get_syndication_feed_id($id);
511 476
512 - $feed_id = get_syndication_feed_id($id);
477 + $ret = NULL;
513 478 if (strlen($feed_id) > 0):
514 479 if (isset($feedwordpress_linkcache[$feed_id])) :
515 480 $link = $feedwordpress_linkcache[$feed_id];
516 481 else :
517 - $link = new SyndicatedLink($feed_id);
482 + $link =& new SyndicatedLink($feed_id);
518 483 $feedwordpress_linkcache[$feed_id] = $link;
519 484 endif;
520 - endif;
521 - return $link;
522 -}
523 485
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 486 $ret = $link->settings[$key];
530 487 endif;
531 488 return $ret;
532 489 } /* get_feed_meta() */
@@ -537,55 +494,13 @@
537 494 function the_syndication_permalink ($id = NULL) {
538 495 echo get_syndication_permalink($id);
539 496 }
540 497
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 498 ################################################################################
583 499 ## FILTERS: syndication-aware handling of post data for templates and feeds ####
584 500 ################################################################################
585 501
586 502 $feedwordpress_the_syndicated_content = NULL;
587 -$feedwordpress_the_original_permalink = NULL;
588 503
589 504 function feedwordpress_preserve_syndicated_content ($text) {
590 505 global $feedwordpress_the_syndicated_content;
591 506
@@ -615,16 +530,16 @@
615 530 // In a post context....
616 531 if (is_syndicated()) :
617 532 ?>
618 533 <source>
619 - <title><?php print htmlspecialchars(get_syndication_source()); ?></title>
620 - <link rel="alternate" type="text/html" href="<?php print htmlspecialchars(get_syndication_source_link()); ?>" />
621 - <link rel="self" href="<?php print htmlspecialchars(get_syndication_feed()); ?>" />
534 + <title><?php the_syndication_source(); ?></title>
535 + <link rel="alternate" type="text/html" href="<?php the_syndication_source_link(); ?>" />
536 + <link rel="self" href="<?php the_syndication_feed(); ?>" />
622 537 <?php
623 538 $id = get_syndication_feed_guid();
624 539 if (strlen($id) > 0) :
625 540 ?>
626 - <id><?php print htmlspecialchars($id); ?></id>
541 + <id><?php print $id; ?></id>
627 542 <?php
628 543 endif;
629 544 $updated = get_feed_meta('feed/updated');
630 545 if (strlen($updated) > 0) : ?>
@@ -636,131 +551,17 @@
636 551 <?php
637 552 endif;
638 553 }
639 554
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 555 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');
556 + if (get_option('feedwordpress_munge_permalink') != 'no'):
557 + $uri = get_syndication_permalink();
558 + return ((strlen($uri) > 0) ? $uri : $permalink);
559 + else:
560 + return $permalink;
669 561 endif;
562 +} // function syndication_permalink ()
670 563
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 564 ################################################################################
764 565 ## ADMIN MENU ADD-ONS: register Dashboard management pages #####################
765 566 ################################################################################
766 567
@@ -803,8 +604,97 @@
803 604 <?php
804 605 endif;
805 606 } /* function fwp_check_debug () */
806 607
608 +define('EXPECTED_MAGPIE_VERSION', '2009.0725');
609 +function fwp_check_magpie () {
610 + if (isset($_REQUEST['feedwordpress_magpie_fix'])) :
611 + if ($_REQUEST['feedwordpress_magpie_fix']=='ignored') :
612 +?>
613 +<div class="updated fade">
614 +<p>O.K., we'll ignore the problem for now. FeedWordPress will not display any
615 +more error messages.</p>
616 +</div>
617 +<?php
618 + elseif ((bool) $_REQUEST['feedwordpress_magpie_fix']) :
619 +?>
620 +<div class="updated fade">
621 +<p>Congratulations! Your MagpieRSS has been successfully upgraded to the version
622 +shipped with FeedWordPress.</p>
623 +</div>
624 +<?php
625 + else :
626 + $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss.php";
627 + $destination = ABSPATH . WPINC . '/rss.php';
628 + $cmd = "cp '".htmlspecialchars(addslashes($source))."' '".htmlspecialchars(addslashes($destination))."'";
629 + $cmd = wordwrap($cmd, /*width=*/ 75, /*break=*/ " \\\n\t");
630 +
631 +?>
632 +<div class="error">
633 +<p><strong>FeedWordPress was unable to automatically upgrade your copy of MagpieRSS.</strong></p>
634 +<p>It's likely that you need to change the file permissions on <code><?php print htmlspecialchars($source); ?></code>
635 +to allow FeedWordPress to overwrite it.</p>
636 +<p><strong>To perform the upgrade manually,</strong> you can
637 +use a SFTP or FTP client to upload a copy of <code>rss.php</code> from the
638 +<code>MagpieRSS-upgrades/</code> directory of your FeedWordPress archive so that
639 +it overwrites <code><?php print htmlspecialchars($destination); ?></code>. Or,
640 +if your web host provides shell access, you can issue the following command from
641 +a command prompt to perform the upgrade:</p>
642 +<pre>
643 +<samp>$</samp> <kbd><?php print $cmd; ?></kbd>
644 +</pre>
645 +<p><strong>If you've fixed the file permissions,</strong> you can try the
646 +automatic upgrade again.</p>
647 +
648 +<?php feedwordpress_upgrade_old_and_busted_buttons(); ?>
649 +</div>
650 +<?php
651 + endif;
652 + else :
653 + $magpie_version = FeedWordPress::magpie_version();
654 +
655 + $ignored = get_option('feedwordpress_magpie_ignored_upgrade_to');
656 + if (EXPECTED_MAGPIE_VERSION != $magpie_version and EXPECTED_MAGPIE_VERSION != $ignored) :
657 + if (current_user_can('edit_files')) :
658 + $youAre = 'you are';
659 + $itIsRecommendedThatYou = 'It is <strong>strongly recommended</strong> that you';
660 + else :
661 + $youAre = 'this site is';
662 + $itIsRecommendedThatYou = 'You may want to contact the administrator of the site; it is <strong>strongly recommended</strong> that they';
663 + endif;
664 + print '<div class="error">';
665 +?>
666 +<p style="font-style: italic"><strong>FeedWordPress has detected that <?php print $youAre; ?> currently using a version of
667 +MagpieRSS other than the upgraded version that ships with this version of FeedWordPress.</strong></p>
668 +<ul>
669 +<li><strong>Currently running:</strong> MagpieRSS <?php print $magpie_version; ?></li>
670 +<li><strong>Version included with FeedWordPress <?php print FEEDWORDPRESS_VERSION; ?>:</strong> MagpieRSS <?php print EXPECTED_MAGPIE_VERSION; ?></li>
671 +</ul>
672 +<p><?php print $itIsRecommendedThatYou; ?> install the upgraded
673 +version of MagpieRSS supplied with FeedWordPress. The version of
674 +MagpieRSS that ships with WordPress is very old and buggy, and
675 +encounters a number of errors when trying to parse modern Atom
676 +and RSS feeds.</p>
677 +<?php
678 + feedwordpress_upgrade_old_and_busted_buttons();
679 + print '</div>';
680 + endif;
681 + endif;
682 +}
683 +
684 +function feedwordpress_upgrade_old_and_busted_buttons() {
685 + if (current_user_can('edit_files')) :
686 +?>
687 +<form action="" method="post"><div>
688 +<?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_fix_magpie'); ?>
689 +<input type="hidden" name="action" value="fix_magpie_version" />
690 +<input class="button-secondary" type="submit" name="ignore" value="<?php _e('Ignore this problem'); ?>" />
691 +<input class="button-primary" type="submit" name="upgrade" value="<?php _e('Upgrade'); ?>" />
692 +</div></form>
693 +<?php
694 + endif;
695 +}
696 +
807 697 ################################################################################
808 698 ## fwp_hold_pings() and fwp_release_pings(): Outbound XML-RPC ping reform ####
809 699 ## ... 'coz it's rude to send 500 pings the first time your aggregator runs ####
810 700 ################################################################################
@@ -860,65 +750,8 @@
860 750 endif;
861 751 endif;
862 752 }
863 753
864 - function feedwordpress_add_post_edit_controls () {
865 - add_meta_box('feedwordpress-post-controls', __('Syndication'), 'feedwordpress_post_edit_controls', 'post', 'side', 'high');
866 - } // function FeedWordPress::postEditControls
867 -
868 - function feedwordpress_post_edit_controls () {
869 - global $post;
870 -
871 - $frozen_values = get_post_custom_values('_syndication_freeze_updates', $post->ID);
872 - $frozen_post = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
873 -
874 - if (is_syndicated($post->ID)) :
875 - ?>
876 - <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>
879 -
880 - <p><input type="hidden" name="feedwordpress_noncename" id="feedwordpress_noncename" value="<?php print wp_create_nonce(plugin_basename(__FILE__)); ?>" />
881 - <label><input type="checkbox" name="freeze_updates" value="yes" <?php if ($frozen_post) : ?>checked="checked"<?php endif; ?> /> <strong>Manual editing.</strong>
882 - If set, FeedWordPress will not overwrite the changes you make manually
883 - to this post, if the syndicated content is updated on the
884 - feed.</label></p>
885 - <?php
886 - else :
887 - ?>
888 - <p>This post was created locally at this website.</p>
889 - <?php
890 - endif;
891 - } // function feedwordpress_post_edit_controls () */
892 -
893 - function feedwordpress_save_post_edit_controls ( $post_id ) {
894 - global $post;
895 -
896 - if (!isset($_POST['feedwordpress_noncename']) or !wp_verify_nonce($_POST['feedwordpress_noncename'], plugin_basename(__FILE__))) :
897 - return $post_id;
898 - endif;
899 -
900 - // Verify if this is an auto save routine. If it is our form has
901 - // not been submitted, so we don't want to do anything.
902 - if ( defined('DOING_AUTOSAVE') and DOING_AUTOSAVE ) :
903 - return $post_id;
904 - endif;
905 -
906 - // Check permissions
907 - if ( !current_user_can( 'edit_'.$_POST['post_type'], $post_id) ) :
908 - return $post_id;
909 - endif;
910 -
911 - // OK, we're golden. Now let's save some data.
912 - if (isset($_POST['freeze_updates'])) :
913 - update_post_meta($post_id, '_syndication_freeze_updates', $_POST['freeze_updates']);
914 - else :
915 - delete_post_meta($post_id, '_syndication_freeze_updates');
916 - endif;
917 -
918 - return $_POST['freeze_updates'];
919 - } // function feedwordpress_save_edit_controls
920 -
921 754 ################################################################################
922 755 ## class FeedWordPress #########################################################
923 756 ################################################################################
924 757
@@ -962,9 +795,9 @@
962 795 function FeedWordPress () {
963 796 $this->feeds = array ();
964 797 $links = FeedWordPress::syndicated_links();
965 798 if ($links): foreach ($links as $link):
966 - $this->feeds[] = new SyndicatedLink($link);
799 + $this->feeds[] =& new SyndicatedLink($link);
967 800 endforeach; endif;
968 801 } // FeedWordPress::FeedWordPress ()
969 802
970 803 # function update (): polls for updates on one or more Contributor feeds
@@ -1068,12 +901,10 @@
1068 901 $start_ts = time();
1069 902 $added = $feed->poll($crash_ts);
1070 903 do_action('feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts);
1071 904
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;
905 + if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
906 + if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
1076 907 endif;
1077 908 endforeach;
1078 909
1079 910 do_action('feedwordpress_update_complete', $delta);
@@ -1188,10 +1019,8 @@
1188 1019 );
1189 1020
1190 1021 if (is_string($override)) :
1191 1022 $ret = strtolower($override);
1192 - else :
1193 - $ret = NULL;
1194 1023 endif;
1195 1024
1196 1025 if (!is_numeric($override) and !in_array($ret, $set[$what])) :
1197 1026 $ret = get_option('feedwordpress_unfamiliar_'.$what);
@@ -1227,19 +1056,8 @@
1227 1056 $ret = get_option('feedwordpress_use_aggregator_source_data');
1228 1057 return apply_filters('syndicated_post_use_aggregator_source_data', ($ret=='yes'));
1229 1058 }
1230 1059
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 1060 function syndicated_links () {
1243 1061 $contributors = FeedWordPress::link_category_id();
1244 1062 if (function_exists('get_bookmarks')) :
1245 1063 $links = get_bookmarks(array("category" => $contributors));
@@ -1323,14 +1141,58 @@
1323 1141
1324 1142 if (is_null($from) or $from <= 0.96) : $from = 0.96; endif;
1325 1143
1326 1144 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.
1145 + case 0.96: // account for changes to syndication custom values and guid
1146 + echo "<p>Upgrading database from {$from} to ".FEEDWORDPRESS_VERSION."...</p>\n";
1332 1147
1148 + $cat_id = FeedWordPress::link_category_id();
1149 +
1150 + // Avoid duplicates
1151 + $wpdb->query("DELETE FROM `{$wpdb->postmeta}` WHERE meta_key = 'syndication_feed_id'");
1152 +
1153 + // Look up all the link IDs
1154 + $wpdb->query("
1155 + CREATE TEMPORARY TABLE tmp_custom_values
1156 + SELECT
1157 + NULL AS meta_id,
1158 + post_id,
1159 + 'syndication_feed_id' AS meta_key,
1160 + link_id AS meta_value
1161 + FROM `{$wpdb->postmeta}`, `{$wpdb->links}`
1162 + WHERE
1163 + meta_key='syndication_feed'
1164 + AND meta_value=link_rss
1165 + AND link_category = {$cat_id}
1166 + ");
1167 +
1168 + // Now attach them to their posts
1169 + $wpdb->query("INSERT INTO `{$wpdb->postmeta}` SELECT * FROM tmp_custom_values");
1170 +
1171 + // And clean up after ourselves.
1172 + $wpdb->query("DROP TABLE tmp_custom_values");
1173 +
1174 + // Now fix the guids to avoid duplicate posts
1175 + echo "<ul>";
1176 + foreach ($this->feeds as $syndicatedLink) :
1177 + $feed = $syndicatedLink->settings;
1178 + echo "<li>Fixing post meta-data for <cite>".$feed['link/name']."</cite> &#8230; "; flush();
1179 + $rss = @fetch_rss($feed['link/uri']);
1180 + if (is_array($rss->items)) :
1181 + foreach ($rss->items as $item) :
1182 + $post = new SyndicatedPost($item, $syndicatedLink);
1183 + $guid = $wpdb->escape($post->guid()); // new GUID algorithm
1184 + $link = $wpdb->escape($item['link']);
1185 +
1186 + $wpdb->query("
1187 + UPDATE `{$wpdb->posts}` SET guid='{$guid}' WHERE guid='{$link}'
1188 + ");
1189 + endforeach;
1190 + endif;
1191 + echo "<strong>complete.</strong></li>\n";
1192 + endforeach;
1193 + echo "</ul>\n";
1194 +
1333 1195 // Mark the upgrade as successful.
1334 1196 update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1335 1197 endswitch;
1336 1198 echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
@@ -1335,27 +1197,8 @@
1335 1197 endswitch;
1336 1198 echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
1337 1199 } /* FeedWordPress::upgrade_database() */
1338 1200
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 1201 function create_guid_index () {
1359 1202 global $wpdb;
1360 1203
1361 1204 $wpdb->query("
@@ -1362,71 +1205,29 @@
1362 1205 CREATE INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}(guid)
1363 1206 ");
1364 1207 } /* FeedWordPress::create_guid_index () */
1365 1208
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 1209 function clear_cache () {
1393 1210 global $wpdb;
1394 1211
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.
1212 + // MagpieRSS stores its cached feeds in options table rows with
1213 + // name = `rss_{md5 of url}` and timestamps for cached feeds in
1214 + // table rows with name = `rss_{md5 of url}_ts`. The md5 is
1215 + // always 32 characters in length, so the total option_name is
1216 + // always over 32 characters.
1402 1217 $wpdb->query("
1403 1218 DELETE FROM {$wpdb->options}
1404 - WHERE option_name LIKE '_transient%_feed_%' AND LENGTH(option_name) > 32
1219 + WHERE LOCATE('rss_', option_name) AND LENGTH(option_name) > 32
1405 1220 ");
1406 1221 } /* FeedWordPress::clear_cache () */
1407 1222
1408 - function cache_duration () {
1409 - $duration = NULL;
1410 - if (defined('FEEDWORDPRESS_CACHE_AGE')) :
1411 - $duration = FEEDWORDPRESS_CACHE_AGE;
1223 + function magpie_version () {
1224 + if (!defined('MAGPIE_VERSION')) : $magpie_version = $GLOBALS['wp_version'].'-default';
1225 + else : $magpie_version = MAGPIE_VERSION;
1412 1226 endif;
1413 - return $duration;
1227 + return $magpie_version;
1414 1228 }
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 1229
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 1230 # Utility functions for handling text settings
1430 1231 function negative ($f, $setting) {
1431 1232 $nego = array ('n', 'no', 'f', 'false');
1432 1233 return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
@@ -1441,12 +1242,17 @@
1441 1242 # Internal debugging functions
1442 1243 function critical_bug ($varname, $var, $line) {
1443 1244 global $wp_version;
1444 1245
1246 + if (defined('MAGPIE_VERSION')) : $mv = MAGPIE_VERSION;
1247 + else : $mv = 'WordPress '.$wp_version.' default.';
1248 + endif;
1249 +
1445 1250 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 1251 echo "\n<plaintext>";
1447 1252 echo "Triggered at line # ".$line."\n";
1448 1253 echo "FeedWordPress version: ".FEEDWORDPRESS_VERSION."\n";
1254 + echo "MagpieRSS version: {$mv}\n";
1449 1255 echo "WordPress version: {$wp_version}\n";
1450 1256 echo "PHP version: ".phpversion()."\n";
1451 1257 echo "\n";
1452 1258 echo $varname.": "; var_dump($var); echo "\n";
@@ -1472,9 +1278,9 @@
1472 1278 return $args;
1473 1279 }
1474 1280
1475 1281 function feedwordpress_pong ($args) {
1476 - $feedwordpress = new FeedWordPress;
1282 + $feedwordpress =& new FeedWordPress;
1477 1283 $delta = @$feedwordpress->update($args[1]);
1478 1284 if (is_null($delta)):
1479 1285 return array('flerror' => true, 'message' => "Sorry. I don't syndicate <$args[1]>.");
1480 1286 else:
@@ -1485,9 +1291,13 @@
1485 1291 return array('flerror' => false, 'message' => "Thanks for the ping.".implode(' and', $mesg));
1486 1292 endif;
1487 1293 }
1488 1294
1489 -require_once(dirname(__FILE__) . '/relative_uri.class.php');
1295 +# The upgraded MagpieRSS also uses this class. So if we have it loaded
1296 +# in, don't load it again.
1297 +if (!class_exists('Relative_URI')) {
1298 + require_once(dirname(__FILE__) . '/relative_uri.class.php');
1299 +}
1490 1300
1491 1301 // take your best guess at the realname and e-mail, given a string
1492 1302 define('FWP_REGEX_EMAIL_ADDY', '([^@"(<\s]+@[^"@(<\s]+\.[^"@(<\s]+)');
1493 1303 define('FWP_REGEX_EMAIL_NAME', '("([^"]*)"|([^"<(]+\S))');