FeedWordPress - Version 2011.0721

Version Description

  • BUGFIX: SERIOUS BUG CAUSING RARE UNEXPECTED DELETION OF PAGES AND OTHER CONTENT. A bug in the guid-checking code for some rare kinds of guids could cause content in the wp_posts table to seemingly disappear at random after FeedWordPress updates.This most frequently but not exclusively affected static pages. What actually happened is that in these rare cases the existing static page was mistaken for an older version of the new incoming syndicated post, which was then stored as a new revision of the original page. The bug that caused these mistaken identities has been fixed.

  • BUGFIX: UNWANTED AUTOMATIC PAGE-LOAD-BASED UPDATES NO LONGER A NUISANCE. Some users encountered a bug in which FeedWordPress would adopt an automatic page-load-based update method, even if they had requested that it not do so, and that it use a manual or cron job update method instead. The bug causing this has been fixed, and page-load-based updates should no longer trigger unless explicitly turned on.

  • WP 3.2 USER INTERFACE COMPATIBILITY: POST TAGS BOX NOW WORKS AGAIN. The release of WordPress 3.2 caused a breakage in the tags box which prevented you from adding or removing tags under Syndication --> Categories & Tags. (The breakage was the result of an incompatibility introduced by the new release of jQuery.) This breakage has now been fixed, and the tags box should work correctly again.

  • FEED UPDATE SCHEDULING IMPROVEMENTS: UI. The Syndicated Sources table now provides considerably more data to understand update scheduling, when specific scheduling decisions are made because of, e.g., requests from the feed producer.

  • FEED UPDATE SCHEDULING IMPROVEMENTS: ENFORCEABLE "MINIMUM INTERVAL" SETTIN TO SPACE OUT UPDATES. Some feeds request specific update schedules, using standard elements such as sy:updateFrequency and rss:ttl. Normally, FeedWordPress respects any scheduling requests that a feed makes -- if it requests a longer gap between polls than what FWP would normally adopt, then FWP slows down to meet the request. If it indicates a shorter gap than what FWP would normally adopt, FWP speeds up and checks that feed for updates more often than it normally would. Now, there should not be any way for user settings to override an explicit slow-down request from the feed producer -- if producers indicate a particular update schedule, then polling the feed more frequently than they request is considered abusive behavior. But there's no reason why users should not be able -- if they so desire -- to override speed-up requests, and poll a feed less frequently than the indicated update schedule, if the FWP user wants to space update checkins over a longer interval of time. Before, they could not do this: FWP always sped up to meet the indicated update schedule. Now, they can do this, by using the new "Minimum Interval" setting in Syndication --> Feeds & Updates..

Download this release

Release Info

Developer radgeek
Plugin Icon wp plugin FeedWordPress
Version 2011.0721
Comparing to
See all releases

Code changes from version 2011.0706 to 2011.0721

admin-ui.php CHANGED
@@ -746,38 +746,68 @@ function fwp_option_box_closer () {
746
  }
747
 
748
  function fwp_tags_box ($tags, $object, $params = array()) {
 
 
 
 
 
 
 
 
 
 
749
  if (!is_array($tags)) : $tags = array(); endif;
750
- $tax_name = (isset($params['taxonomy']) ? $params['taxonomy'] : 'post_tag');
 
 
 
 
751
  $desc = "<p style=\"font-size:smaller;font-style:bold;margin:0\">Tag $object as...</p>";
752
 
753
- if (isset($params['textarea_name'])) :
754
- $textAreaName = $params['textarea_name'];
755
- else :
756
- $textAreaName = "tax_input[$tax_name]";
 
 
 
 
 
 
 
 
 
 
 
757
  endif;
 
758
  print $desc;
759
  $helps = __('Separate tags with commas.');
760
  $box['title'] = __('Tags');
761
  ?>
762
- <div class="tagsdiv" id="<?php echo $tax_name; ?>">
763
- <div class="jaxtag">
764
- <div class="nojs-tags hide-if-js">
765
- <p><?php _e('Add or remove tags'); ?></p>
766
- <textarea name="<?php echo esc_html($textAreaName); ?>" class="the-tags" id="tax-input[<?php echo $tax_name; ?>]"><?php echo esc_attr(implode(",", $tags)); ?></textarea></div>
 
 
 
 
 
 
 
 
 
 
 
767
 
768
- <div class="ajaxtag hide-if-no-js">
769
- <label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $box['title']; ?></label>
770
- <div class="taghint"><?php _e('Add new tag'); ?></div>
771
- <p>
772
- <input type="text" id="new-tag-<?php echo $tax_name; ?>" name="newtag[<?php echo $tax_name; ?>]" class="newtag form-input-tip" size="16" autocomplete="off" value="" />
773
- <input type="button" class="button tagadd" value="<?php esc_attr_e('Add'); ?>" tabindex="3" />
774
- </p>
775
- </div></div>
776
- <p class="howto"><?php echo $helps; ?></p>
777
- <div class="tagchecklist"></div>
778
- </div>
779
- <p class="hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php printf( __('Choose from the most used tags in %s'), $box['title'] ); ?></a></p>
780
- <?php
781
  }
782
 
783
  function fwp_category_box ($checked, $object, $tags = array(), $params = array()) {
@@ -1082,7 +1112,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
1082
  // Prep: Get last updated timestamp
1083
  $sLink = new SyndicatedLink($link->link_id);
1084
  if (!is_null($sLink->setting('update/last'))) :
1085
- $lastUpdated = fwp_time_elapsed($sLink->setting('update/last'));
1086
  else :
1087
  $lastUpdated = __('None yet');
1088
  endif;
@@ -1107,19 +1137,41 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
1107
  ."</div>\n";
1108
  endif;
1109
 
1110
- $nextUpdate = "<div style='font-style:italic;size:0.9em'>Ready for next update ";
1111
- if (isset($sLink->settings['update/ttl']) and is_numeric($sLink->settings['update/ttl'])) :
1112
- if (isset($sLink->settings['update/timed']) and $sLink->settings['update/timed']=='automatically') :
1113
- $next = $sLink->settings['update/last'] + ((int) $sLink->settings['update/ttl'] * 60);
 
 
 
 
 
 
 
1114
  $nextUpdate .= fwp_time_elapsed($next);
1115
  if (FEEDWORDPRESS_DEBUG) : $nextUpdate .= " [".(($next-time())/60)." minutes]"; endif;
1116
  else :
1117
- $nextUpdate .= "every ".$sLink->settings['update/ttl']." minute".(($sLink->settings['update/ttl']!=1)?"s":"");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1118
  endif;
1119
  else:
1120
- $nextUpdate .= "as soon as possible";
1121
  endif;
1122
- $nextUpdate .= "</div>";
1123
 
1124
  unset($sLink);
1125
 
746
  }
747
 
748
  function fwp_tags_box ($tags, $object, $params = array()) {
749
+ $params = wp_parse_args($params, array( // Default values
750
+ 'taxonomy' => 'post_tag',
751
+ 'textarea_name' => NULL,
752
+ 'textarea_id' => NULL,
753
+ 'input_id' => NULL,
754
+ 'input_name' => NULL,
755
+ 'id' => NULL,
756
+ 'box_title' => __('Post Tags'),
757
+ ));
758
+
759
  if (!is_array($tags)) : $tags = array(); endif;
760
+
761
+ $tax_name = $params['taxonomy'];
762
+ $taxonomy = get_taxonomy($params['taxonomy']);
763
+ $disabled = (!current_user_can($taxonomy->cap->assign_terms) ? 'disabled="disabled"' : '');
764
+
765
  $desc = "<p style=\"font-size:smaller;font-style:bold;margin:0\">Tag $object as...</p>";
766
 
767
+ if (is_null($params['textarea_name'])) :
768
+ $params['textarea_name'] = "tax_input[$tax_name]";
769
+ endif;
770
+ if (is_null($params['textarea_id'])) :
771
+ $params['textarea_id'] = "tax-input-${tax_name}";
772
+ endif;
773
+ if (is_null($params['input_id'])) :
774
+ $params['input_id'] = "new-tag-${tax_name}";
775
+ endif;
776
+ if (is_null($params['input_name'])) :
777
+ $params['input_name'] = "newtag[$tax_name]";
778
+ endif;
779
+
780
+ if (is_null($params['id'])) :
781
+ $params['id'] = $tax_name;
782
  endif;
783
+
784
  print $desc;
785
  $helps = __('Separate tags with commas.');
786
  $box['title'] = __('Tags');
787
  ?>
788
+ <div class="tagsdiv" id="<?php echo $params['id']; ?>">
789
+ <div class="jaxtag">
790
+ <div class="nojs-tags hide-if-js">
791
+ <p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
792
+ <textarea name="<?php echo $params['textarea_name']; ?>" class="the-tags" id="<?php echo $params['textarea_id']; ?>"><?php echo esc_attr(implode(",", $tags)); ?></textarea></div>
793
+
794
+ <?php if ( current_user_can($taxonomy->cap->assign_terms) ) :?>
795
+ <div class="ajaxtag hide-if-no-js">
796
+ <label class="screen-reader-text" for="<?php echo $params['input_id']; ?>"><?php echo $params['box_title']; ?></label>
797
+ <div class="taghint"><?php echo $taxonomy->labels->add_new_item; ?></div>
798
+ <p><input type="text" id="<?php print $params['input_id']; ?>" name="<?php print $params['input_name']; ?>" class="newtag form-input-tip" size="16" autocomplete="off" value="" />
799
+ <input type="button" class="button tagadd" value="<?php esc_attr_e('Add'); ?>" tabindex="3" /></p>
800
+ </div>
801
+ <p class="howto"><?php echo esc_attr( $taxonomy->labels->separate_items_with_commas ); ?></p>
802
+ <?php endif; ?>
803
+ </div>
804
 
805
+ <div class="tagchecklist"></div>
806
+ </div>
807
+ <?php if ( current_user_can($taxonomy->cap->assign_terms) ) : ?>
808
+ <p class="hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php echo $taxonomy->labels->choose_from_most_used; ?></a></p>
809
+ <?php endif;
810
+
 
 
 
 
 
 
 
811
  }
812
 
813
  function fwp_category_box ($checked, $object, $tags = array(), $params = array()) {
1112
  // Prep: Get last updated timestamp
1113
  $sLink = new SyndicatedLink($link->link_id);
1114
  if (!is_null($sLink->setting('update/last'))) :
1115
+ $lastUpdated = 'Last checked '. fwp_time_elapsed($sLink->setting('update/last'));
1116
  else :
1117
  $lastUpdated = __('None yet');
1118
  endif;
1137
  ."</div>\n";
1138
  endif;
1139
 
1140
+ $nextUpdate = "<div style='max-width: 30.0em; font-size: 0.9em;'><div style='font-style:italic;'>";
1141
+
1142
+ $ttl = $sLink->setting('update/ttl');
1143
+ if (is_numeric($ttl)) :
1144
+ $next = $sLink->setting('update/last') + $sLink->setting('update/fudge') + ((int) $ttl * 60);
1145
+ if ('automatically'==$sLink->setting('update/timed')) :
1146
+ if ($next < time()) :
1147
+ $nextUpdate .= 'Ready and waiting to be updated since ';
1148
+ else :
1149
+ $nextUpdate .= 'Scheduled for next update ';
1150
+ endif;
1151
  $nextUpdate .= fwp_time_elapsed($next);
1152
  if (FEEDWORDPRESS_DEBUG) : $nextUpdate .= " [".(($next-time())/60)." minutes]"; endif;
1153
  else :
1154
+ $lastUpdated .= " &middot; Next ";
1155
+ if ($next < time()) :
1156
+ $lastUpdated .= 'ASAP';
1157
+ elseif ($next - time() < 60) :
1158
+ $lastUpdated .= fwp_time_elapsed($next);
1159
+ elseif ($next - time() < 60*60*24) :
1160
+ $lastUpdated .= gmdate('g:ia', $next + (get_option('gmt_offset') * 3600));
1161
+ else :
1162
+ $lastUpdated .= gmdate('F j', $next + (get_option('gmt_offset') * 3600));
1163
+ endif;
1164
+
1165
+ $nextUpdate .= "Scheduled to be checked for updates every ".$ttl." minute".(($ttl!=1)?"s":"")."</div><div style='size:0.9em; margin-top: 0.5em'> This update schedule was requested by the feed provider";
1166
+ if ($sLink->setting('update/xml')) :
1167
+ $nextUpdate .= " using a standard <code style=\"font-size: inherit; padding: 0; background: transparent\">&lt;".$sLink->setting('update/xml')."&gt;</code> element";
1168
+ endif;
1169
+ $nextUpdate .= ".";
1170
  endif;
1171
  else:
1172
+ $nextUpdate .= "Scheduled for update as soon as possible";
1173
  endif;
1174
+ $nextUpdate .= "</div></div>";
1175
 
1176
  unset($sLink);
1177
 
diagnostics-page.php CHANGED
@@ -238,6 +238,7 @@ testing but absolutely inappropriate for a production server.</p>
238
  $hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
239
  $fields = apply_filters('feedwordpress_diagnostics', array(
240
  'Update Diagnostics' => array(
 
241
  'updated_feeds' => 'as each feed is checked for updates',
242
  'updated_feeds:errors:persistent' => 'when attempts to update a feed have resulted in errors</label> <label>for at least <input type="number" min="1" max="360" step="1" name="diagnostics_persistent_error_hours" value="'.$hours.'" /> hours',
243
  'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
238
  $hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
239
  $fields = apply_filters('feedwordpress_diagnostics', array(
240
  'Update Diagnostics' => array(
241
+ 'update_schedule:check' => 'whenever a FeedWordPress checks in on the update schedule',
242
  'updated_feeds' => 'as each feed is checked for updates',
243
  'updated_feeds:errors:persistent' => 'when attempts to update a feed have resulted in errors</label> <label>for at least <input type="number" min="1" max="360" step="1" name="diagnostics_persistent_error_hours" value="'.$hours.'" /> hours',
244
  'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
feeds-page.php CHANGED
@@ -175,7 +175,8 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
175
  } /* FeedWordPressFeedsPage::updated_posts_box() */
176
 
177
  /*static*/ function global_feeds_box ($page, $box = NULL) {
178
- $automatic_updates = get_option('feedwordpress_automatic_updates');
 
179
  $update_time_limit = (int) get_option('feedwordpress_update_time_limit');
180
 
181
  // Hey, ho, let's go...
@@ -263,6 +264,30 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
263
  ?></td>
264
  </tr>
265
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  <?php if ($this->for_default_settings()) : ?>
267
 
268
  <tr>
@@ -905,7 +930,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
905
  update_option('feedwordpress_cat_id', $post['syndication_category']);
906
 
907
  if (!isset($post['automatic_updates']) or !in_array($post['automatic_updates'], array('init', 'shutdown'))) :
908
- $automatic_updates = false;
909
  else :
910
  $automatic_updates = $post['automatic_updates'];
911
  endif;
@@ -939,6 +964,10 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
939
  endif;
940
  $this->update_setting('fetch timeout', $timeout);
941
  endif;
 
 
 
 
942
 
943
  $this->updatedPosts->accept_POST($post);
944
  parent::save_settings($post);
175
  } /* FeedWordPressFeedsPage::updated_posts_box() */
176
 
177
  /*static*/ function global_feeds_box ($page, $box = NULL) {
178
+ global $feedwordpress;
179
+ $automatic_updates = $feedwordpress->automatic_update_hook(array('setting only' => true));
180
  $update_time_limit = (int) get_option('feedwordpress_update_time_limit');
181
 
182
  // Hey, ho, let's go...
264
  ?></td>
265
  </tr>
266
 
267
+ <tr>
268
+ <th scope="row"><?php print __('Minimum Interval:'); ?></th>
269
+ <td><p style="margin-top:0px">Some feeds include standard elements that
270
+ request a specific update schedule. If the interval requested by the
271
+ feed provider is <em>longer</em> than FeedWordPress's normal scheduling,
272
+ FeedWordPress will always respect their request to slow down. But what
273
+ should it do if the update interval is <em>shorter</em> than the schedule set above?</p>
274
+ <?php
275
+ $this->setting_radio_control(
276
+ 'update/minimum', 'update_minimum',
277
+ /*options=*/ array(
278
+ 'no' => 'Speed up and accept the interval from the feed provider',
279
+ 'yes' => 'Keep pace and use the longer scheduling from FeedWordPress',
280
+ ),
281
+ /*params=*/ array(
282
+ 'setting-default' => NULL,
283
+ 'global-setting-default' => 'no',
284
+ 'default-input-value' => 'default',
285
+ )
286
+ );
287
+ ?>
288
+ </td>
289
+ </tr>
290
+
291
  <?php if ($this->for_default_settings()) : ?>
292
 
293
  <tr>
930
  update_option('feedwordpress_cat_id', $post['syndication_category']);
931
 
932
  if (!isset($post['automatic_updates']) or !in_array($post['automatic_updates'], array('init', 'shutdown'))) :
933
+ $automatic_updates = NULL;
934
  else :
935
  $automatic_updates = $post['automatic_updates'];
936
  endif;
964
  endif;
965
  $this->update_setting('fetch timeout', $timeout);
966
  endif;
967
+
968
+ if (isset($post['update_minimum'])) :
969
+ $this->update_setting('update/minimum', $post['update_minimum']);
970
+ endif;
971
 
972
  $this->updatedPosts->accept_POST($post);
973
  parent::save_settings($post);
feedwordpress-elements.js CHANGED
@@ -62,7 +62,7 @@ fwpList = {
62
 
63
  if ( !s ) { return false; }
64
 
65
- if ( !e.is("[class^=add:" + list.id + ":]") ) { return !fwpList.add.call( list, e, s ); }
66
 
67
  if ( !s.element ) { return true; }
68
 
@@ -91,6 +91,7 @@ fwpList = {
91
  if ( true === res ) { return true; }
92
 
93
  jQuery.each( res.responses, function() {
 
94
  fwpList.add.call( list, this.data, $.extend( {}, s, { // this.firstChild.nodevalue
95
  pos: this.position || 0,
96
  id: this.id || 0,
@@ -321,11 +322,11 @@ fwpList = {
321
  process: function(el) {
322
  var list = this;
323
 
324
- $("[class^=add:" + list.id + ":]", el || null)
325
  .filter('form').submit( function() { return list.fwpList.add(this); } ).end()
326
  .not('form').click( function() { return list.fwpList.add(this); } );
327
- $("[class^=delete:" + list.id + ":]", el || null).click( function() { return list.fwpList.del(this); } );
328
- $("[class^=dim:" + list.id + ":]", el || null).click( function() { return list.fwpList.dim(this); } );
329
  },
330
 
331
  recolor: function() {
62
 
63
  if ( !s ) { return false; }
64
 
65
+ if ( !e.is('[class^="add:' + list.id + ':"]') ) { return !fwpList.add.call( list, e, s ); }
66
 
67
  if ( !s.element ) { return true; }
68
 
91
  if ( true === res ) { return true; }
92
 
93
  jQuery.each( res.responses, function() {
94
+ // FIXME: Causes ownerDocument is undefined breakage in WP3.2
95
  fwpList.add.call( list, this.data, $.extend( {}, s, { // this.firstChild.nodevalue
96
  pos: this.position || 0,
97
  id: this.id || 0,
322
  process: function(el) {
323
  var list = this;
324
 
325
+ $('[class^="add:' + list.id + ':"]', el || null)
326
  .filter('form').submit( function() { return list.fwpList.add(this); } ).end()
327
  .not('form').click( function() { return list.fwpList.add(this); } );
328
+ $('[class^="delete:' + list.id + ':"]', el || null).click( function() { return list.fwpList.del(this); } );
329
+ $('[class^="dim:' + list.id + ':"]', el || null).click( function() { return list.fwpList.dim(this); } );
330
  },
331
 
332
  recolor: function() {
feedwordpress.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: FeedWordPress
4
  Plugin URI: http://feedwordpress.radgeek.com/
5
  Description: simple and flexible Atom/RSS syndication for WordPress
6
- Version: 2011.0706
7
  Author: Charles Johnson
8
  Author URI: http://radgeek.com/
9
  License: GPL
@@ -11,7 +11,7 @@ License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
- * @version 2011.0706
15
  */
16
 
17
  # This uses code derived from:
@@ -34,7 +34,7 @@ License: GPL
34
 
35
  # -- Don't change these unless you know what you're doing...
36
 
37
- define ('FEEDWORDPRESS_VERSION', '2011.0706');
38
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
39
 
40
  if (!defined('FEEDWORDPRESS_BLEG')) :
@@ -983,6 +983,13 @@ class FeedWordPress {
983
  if (!is_null($uri) and $uri != '*') :
984
  $uri = trim($uri);
985
  else : // Update all
 
 
 
 
 
 
 
986
  update_option('feedwordpress_last_update_all', time());
987
  endif;
988
 
@@ -992,6 +999,8 @@ class FeedWordPress {
992
  $crash_ts = $this->crash_ts();
993
  endif;
994
 
 
 
995
  // Randomize order for load balancing purposes
996
  $feed_set = $this->feeds;
997
  shuffle($feed_set);
@@ -999,12 +1008,20 @@ class FeedWordPress {
999
  $feed_set = apply_filters('feedwordpress_update_feeds', $feed_set, $uri);
1000
 
1001
  // Loop through and check for new posts
1002
- $delta = NULL;
1003
  foreach ($feed_set as $feed) :
1004
- if (!is_null($crash_ts) and (time() > $crash_ts)) : // Check whether we've exceeded the time limit
 
 
 
 
 
 
 
 
1005
  break;
1006
  endif;
1007
-
1008
  $pinged_that = (is_null($uri) or ($uri=='*') or in_array($uri, array($feed->uri(), $feed->homepage())));
1009
 
1010
  if (!is_null($uri)) : // A site-specific ping always updates
@@ -1018,6 +1035,8 @@ class FeedWordPress {
1018
  endif;
1019
 
1020
  if ($pinged_that and $timely) :
 
 
1021
  do_action('feedwordpress_check_feed', $feed->settings);
1022
  $start_ts = time();
1023
  $added = $feed->poll($crash_ts);
@@ -1055,31 +1074,61 @@ class FeedWordPress {
1055
  }
1056
 
1057
  function has_secret () {
1058
- return (isset($_REQUEST['feedwordpress_key']) and ($_REQUEST['feedwordpress_key']==$this->secret_key()));
1059
  }
1060
 
1061
- function automatic_update_hook () {
 
 
 
 
 
 
 
 
 
 
 
 
 
1062
  $hook = get_option('feedwordpress_automatic_updates', NULL);
1063
- if ($this->has_secret() and isset($_REQUEST['automatic_update'])) : // For forced behavior in testing.
 
 
 
 
 
 
 
1064
  $hook = $_REQUEST['automatic_update'];
 
1065
  endif;
1066
 
1067
- if (!is_null($hook)) :
 
 
1068
  if ($hook != 'init') : // Constrain values.
1069
  $hook = 'shutdown';
1070
  endif;
1071
  endif;
 
 
 
 
 
1072
  return $hook;
1073
  }
1074
  function last_update_all () {
1075
  $last = get_option('feedwordpress_last_update_all');
1076
- if ($this->has_secret() and isset($_REQUEST['automatic_update']) and ((strlen($_REQUEST['automatic_update']) > 0))) :
1077
  $last = 1; // A long, long time ago.
 
 
1078
  endif;
1079
  return $last;
1080
  }
1081
  function force_update_all () {
1082
- return ($this->has_secret() and isset($_REQUEST['force_update_feeds']) and !!$_REQUEST['force_update_feeds']);
1083
  }
1084
 
1085
  function stale () {
@@ -1184,6 +1233,8 @@ class FeedWordPress {
1184
 
1185
  // Explicit update request in the HTTP request (e.g. from a cron job)
1186
  if ($this->update_requested()) :
 
 
1187
  $this->update($this->update_requested_url());
1188
 
1189
  if (FEEDWORDPRESS_DEBUG and count($wpdb->queries) > 0) :
@@ -1227,10 +1278,7 @@ class FeedWordPress {
1227
  } /* FeedWordPress::clear_cache_requested() */
1228
 
1229
  function update_requested () {
1230
- return (
1231
- isset($_REQUEST['update_feedwordpress'])
1232
- and $_REQUEST['update_feedwordpress']
1233
- );
1234
  } // FeedWordPress::update_requested()
1235
 
1236
  function update_requested_url () {
@@ -1740,6 +1788,8 @@ class FeedWordPress {
1740
  // No news is good news; only send if
1741
  // there are some messages to send.
1742
  $body = NULL;
 
 
1743
  foreach ($dlog['mesg'] as $sect => $mesgs) :
1744
  if (count($mesgs) > 0) :
1745
  if (is_null($body)) : $body = ''; endif;
3
  Plugin Name: FeedWordPress
4
  Plugin URI: http://feedwordpress.radgeek.com/
5
  Description: simple and flexible Atom/RSS syndication for WordPress
6
+ Version: 2011.0721
7
  Author: Charles Johnson
8
  Author URI: http://radgeek.com/
9
  License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
+ * @version 2011.0721
15
  */
16
 
17
  # This uses code derived from:
34
 
35
  # -- Don't change these unless you know what you're doing...
36
 
37
+ define ('FEEDWORDPRESS_VERSION', '2011.0721');
38
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
39
 
40
  if (!defined('FEEDWORDPRESS_BLEG')) :
983
  if (!is_null($uri) and $uri != '*') :
984
  $uri = trim($uri);
985
  else : // Update all
986
+ if ($this->update_hooked) :
987
+ $diag = $this->update_hooked;
988
+ else :
989
+ $diag = 'Initiating a MANUAL check-in on the update schedule at '.date('r', time());
990
+ endif;
991
+ $this->diagnostic('update_schedule:check', $diag);
992
+
993
  update_option('feedwordpress_last_update_all', time());
994
  endif;
995
 
999
  $crash_ts = $this->crash_ts();
1000
  endif;
1001
 
1002
+ $max_polls = apply_filters('feedwordpress_polls_per_update', get_option('feedwordpress_polls_per_update', 10), $uri);
1003
+
1004
  // Randomize order for load balancing purposes
1005
  $feed_set = $this->feeds;
1006
  shuffle($feed_set);
1008
  $feed_set = apply_filters('feedwordpress_update_feeds', $feed_set, $uri);
1009
 
1010
  // Loop through and check for new posts
1011
+ $delta = NULL; $remaining = $max_polls;
1012
  foreach ($feed_set as $feed) :
1013
+
1014
+ // Has this process overstayed its welcome?
1015
+ if (
1016
+ // Over time limit?
1017
+ (!is_null($crash_ts) and (time() > $crash_ts))
1018
+
1019
+ // Over feed count?
1020
+ or ($remaining == 0)
1021
+ ) :
1022
  break;
1023
  endif;
1024
+
1025
  $pinged_that = (is_null($uri) or ($uri=='*') or in_array($uri, array($feed->uri(), $feed->homepage())));
1026
 
1027
  if (!is_null($uri)) : // A site-specific ping always updates
1035
  endif;
1036
 
1037
  if ($pinged_that and $timely) :
1038
+ $remaining = $remaining - 1;
1039
+
1040
  do_action('feedwordpress_check_feed', $feed->settings);
1041
  $start_ts = time();
1042
  $added = $feed->poll($crash_ts);
1074
  }
1075
 
1076
  function has_secret () {
1077
+ return ($this->by_request('feedwordpress_key', $this->secret_key()));
1078
  }
1079
 
1080
+ // Utility function so I don't have to repeat myself w/ 1,000,003 isset()'s
1081
+ function by_request ($param, $eq = NULL) {
1082
+ $match = false;
1083
+ if (isset($_REQUEST[$param])) :
1084
+ $match = (is_null($eq) ? $_REQUEST[$param] : ($eq==$_REQUEST[$param]));
1085
+ endif;
1086
+ return $match;
1087
+ }
1088
+
1089
+ var $update_hooked = NULL;
1090
+ function automatic_update_hook ($params = array()) {
1091
+ $params = wp_parse_args($params, array( // Defaults
1092
+ 'setting only' => false,
1093
+ ));
1094
  $hook = get_option('feedwordpress_automatic_updates', NULL);
1095
+ $method = 'FeedWordPress option';
1096
+
1097
+ // Allow for forced behavior in testing.
1098
+ if (
1099
+ !$params['setting only']
1100
+ and $this->has_secret()
1101
+ and $this->by_request('automatic_update')
1102
+ ) :
1103
  $hook = $_REQUEST['automatic_update'];
1104
+ $method = 'URL parameter';
1105
  endif;
1106
 
1107
+ $exact = $hook; // Before munging
1108
+
1109
+ if (!!$hook) :
1110
  if ($hook != 'init') : // Constrain values.
1111
  $hook = 'shutdown';
1112
  endif;
1113
  endif;
1114
+
1115
+ if ($hook) :
1116
+ $this->update_hooked = "Initiating an AUTOMATIC CHECK FOR UPDATES ON PAGE LOAD ".$hook." due to ".$method." = ".trim($this->val($exact));
1117
+ endif;
1118
+
1119
  return $hook;
1120
  }
1121
  function last_update_all () {
1122
  $last = get_option('feedwordpress_last_update_all');
1123
+ if ($this->has_secret() and $this->by_request('automatic_update')) :
1124
  $last = 1; // A long, long time ago.
1125
+ elseif ($this->has_secret() and $this->by_request('last_update_all')) :
1126
+ $last = $_REQUEST['last_update_all'];
1127
  endif;
1128
  return $last;
1129
  }
1130
  function force_update_all () {
1131
+ return ($this->has_secret() and $this->by_request('force_update_feeds'));
1132
  }
1133
 
1134
  function stale () {
1233
 
1234
  // Explicit update request in the HTTP request (e.g. from a cron job)
1235
  if ($this->update_requested()) :
1236
+ $this->update_hooked = "Initiating a CRON JOB CHECK-IN ON UPDATE SCHEDULE due to URL parameter = ".trim($this->val($_REQUEST['update_feedwordpress']));
1237
+
1238
  $this->update($this->update_requested_url());
1239
 
1240
  if (FEEDWORDPRESS_DEBUG and count($wpdb->queries) > 0) :
1278
  } /* FeedWordPress::clear_cache_requested() */
1279
 
1280
  function update_requested () {
1281
+ return FeedWordPress::by_request('update_feedwordpress');
 
 
 
1282
  } // FeedWordPress::update_requested()
1283
 
1284
  function update_requested_url () {
1788
  // No news is good news; only send if
1789
  // there are some messages to send.
1790
  $body = NULL;
1791
+ if (!isset($dlog['mesg'])) : $dlog['mesg'] = array(); endif;
1792
+
1793
  foreach ($dlog['mesg'] as $sect => $mesgs) :
1794
  if (count($mesgs) > 0) :
1795
  if (is_null($body)) : $body = ''; endif;
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://feedwordpress.radgeek.com/
4
  Tags: syndication, aggregation, feed, atom, rss
5
  Requires at least: 3.0
6
  Tested up to: 3.2
7
- Stable tag: 2011.0706
8
 
9
  FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
10
 
@@ -15,11 +15,12 @@ FeedWordPress syndicates content from feeds you choose into your WordPress weblo
15
  * License: GPL 2. See License below for copyright jots and tittles.
16
 
17
  FeedWordPress is an Atom/RSS aggregator for WordPress. It syndicates content
18
- from feeds that you choose into your WordPress weblog; if you syndicate several
19
- feeds then you can use WordPress's posts database and templating engine as the
20
- back-end of an aggregation ("planet") website. It was developed, originally,
21
- because I needed a more flexible replacement for [Planet][]
22
- to use at [Feminist Blogs][].
 
23
 
24
  [Planet]: http://www.planetplanet.org/
25
  [Feminist Blogs]: http://feministblogs.org/
@@ -93,6 +94,55 @@ outs, see the documentation at the [FeedWordPress project homepage][].
93
 
94
  == Changelog ==
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  = 2011.0706 =
97
 
98
  * WP 3.2 COMPATIBILITY: ELIMINATES FATAL ERROR "Call to undefined method
4
  Tags: syndication, aggregation, feed, atom, rss
5
  Requires at least: 3.0
6
  Tested up to: 3.2
7
+ Stable tag: 2011.0721
8
 
9
  FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
10
 
15
  * License: GPL 2. See License below for copyright jots and tittles.
16
 
17
  FeedWordPress is an Atom/RSS aggregator for WordPress. It syndicates content
18
+ from feeds that you choose into your WordPress weblog; the content it syndicates
19
+ appears as a series of special posts in your WordPress posts database. If you
20
+ syndicate several feeds then you can use WordPress's posts database and
21
+ templating engine as the back-end of an aggregation ("planet") website. It was
22
+ developed, originally, because I needed a more flexible replacement for
23
+ [Planet][] to use at [Feminist Blogs][].
24
 
25
  [Planet]: http://www.planetplanet.org/
26
  [Feminist Blogs]: http://feministblogs.org/
94
 
95
  == Changelog ==
96
 
97
+ = 2011.0721 =
98
+
99
+ * BUGFIX: SERIOUS BUG CAUSING RARE UNEXPECTED DELETION OF PAGES AND OTHER
100
+ CONTENT. A bug in the guid-checking code for some rare kinds of guids could
101
+ cause content in the wp_posts table to seemingly disappear at random after
102
+ FeedWordPress updates.This most frequently but not exclusively affected
103
+ static pages. What actually happened is that in these rare cases the
104
+ existing static page was mistaken for an older version of the new incoming
105
+ syndicated post, which was then stored as a new revision of the original
106
+ page. The bug that caused these mistaken identities has been fixed.
107
+
108
+ * BUGFIX: UNWANTED AUTOMATIC PAGE-LOAD-BASED UPDATES NO LONGER A NUISANCE.
109
+ Some users encountered a bug in which FeedWordPress would adopt an automatic
110
+ page-load-based update method, even if they had requested that it not do
111
+ so, and that it use a manual or cron job update method instead. The bug
112
+ causing this has been fixed, and page-load-based updates should no longer
113
+ trigger unless explicitly turned on.
114
+
115
+ * WP 3.2 USER INTERFACE COMPATIBILITY: POST TAGS BOX NOW WORKS AGAIN. The
116
+ release of WordPress 3.2 caused a breakage in the tags box which prevented
117
+ you from adding or removing tags under Syndication --> Categories & Tags.
118
+ (The breakage was the result of an incompatibility introduced by the new
119
+ release of jQuery.) This breakage has now been fixed, and the tags box
120
+ should work correctly again.
121
+
122
+ * FEED UPDATE SCHEDULING IMPROVEMENTS: UI. The Syndicated Sources table now
123
+ provides considerably more data to understand update scheduling, when
124
+ specific scheduling decisions are made because of, e.g., requests from the
125
+ feed producer.
126
+
127
+ * FEED UPDATE SCHEDULING IMPROVEMENTS: ENFORCEABLE "MINIMUM INTERVAL" SETTIN
128
+ TO SPACE OUT UPDATES. Some feeds request specific update schedules, using
129
+ standard elements such as sy:updateFrequency and rss:ttl. Normally,
130
+ FeedWordPress respects any scheduling requests that a feed makes -- if it
131
+ requests a longer gap between polls than what FWP would normally adopt, then
132
+ FWP slows down to meet the request. If it indicates a shorter gap than what
133
+ FWP would normally adopt, FWP speeds up and checks that feed for updates
134
+ more often than it normally would. Now, there should not be any way for user
135
+ settings to override an explicit slow-down request from the feed producer --
136
+ if producers indicate a particular update schedule, then polling the feed
137
+ more frequently than they request is considered abusive behavior. But
138
+ there's no reason why users should not be able -- if they so desire -- to
139
+ override speed-up requests, and poll a feed *less* frequently than the
140
+ indicated update schedule, if the FWP user wants to space update checkins
141
+ over a longer interval of time. Before, they could not do this: FWP always
142
+ sped up to meet the indicated update schedule. Now, they can do this, by
143
+ using the new "Minimum Interval" setting in Syndication --> Feeds &
144
+ Updates..
145
+
146
  = 2011.0706 =
147
 
148
  * WP 3.2 COMPATIBILITY: ELIMINATES FATAL ERROR "Call to undefined method
syndicatedlink.class.php CHANGED
@@ -168,17 +168,20 @@ class SyndicatedLink {
168
  global $feedwordpress;
169
 
170
  $stale = true;
171
- if (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='ping')) :
172
  $stale = false; // don't update on any timed updates; pings only
173
- elseif (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='next')) :
174
  $stale = true; // update on the next timed update
175
- elseif (!isset($this->settings['update/ttl']) or !isset($this->settings['update/last'])) :
176
  $stale = true; // initial update
177
  elseif ($feedwordpress->force_update_all()) :
178
  $stale = true; // forced general updating
179
  else :
180
- $after = ((int) $this->settings['update/last'])
181
- +((int) $this->settings['update/ttl'] * 60);
 
 
 
182
  $stale = (time() >= $after);
183
  endif;
184
  return $stale;
@@ -282,17 +285,23 @@ class SyndicatedLink {
282
 
283
  $this->settings = array_merge($this->settings, $this->flatten_array($channel));
284
 
285
- $this->settings['update/last'] = time(); $ttl = $this->ttl();
 
 
286
  if (!is_null($ttl)) :
287
  $this->settings['update/ttl'] = $ttl;
 
288
  $this->settings['update/timed'] = 'feed';
289
  else :
290
- $this->settings['update/ttl'] = $this->automatic_ttl();
 
 
291
  $this->settings['update/timed'] = 'automatically';
292
  endif;
293
- $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->settings['update/ttl'], $this);
 
294
 
295
- if (!isset($this->settings['update/hold']) or $this->settings['update/hold']!='ping') :
296
  $this->settings['update/hold'] = 'scheduled';
297
  endif;
298
 
@@ -670,7 +679,7 @@ class SyndicatedLink {
670
  return $ret;
671
  }
672
 
673
- function ttl () {
674
  if (is_object($this->magpie)) :
675
  $channel = $this->magpie->channel;
676
  else :
@@ -682,6 +691,7 @@ class SyndicatedLink {
682
  // minutes that indicates how long a channel can be
683
  // cached before refreshing from the source."
684
  // <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
 
685
  $ret = $channel['ttl'];
686
  elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
687
  $period_minutes = array (
@@ -709,11 +719,21 @@ class SyndicatedLink {
709
  else : $freq = 1;
710
  endif;
711
 
 
712
  $ret = (int) ($period_minutes[$period] / $freq);
713
  else :
 
714
  $ret = NULL;
715
  endif;
716
- return $ret;
 
 
 
 
 
 
 
 
717
  } /* SyndicatedLink::ttl() */
718
 
719
  function automatic_ttl () {
@@ -723,7 +743,9 @@ class SyndicatedLink {
723
  $updateWindow = DEFAULT_UPDATE_PERIOD;
724
  endif;
725
 
726
- $fudgedInterval = $updateWindow+rand(0, 2*($updateWindow/3));
 
 
727
  return apply_filters('syndicated_feed_automatic_ttl', $fudgedInterval, $this);
728
  } /* SyndicatedLink::automatic_ttl () */
729
 
168
  global $feedwordpress;
169
 
170
  $stale = true;
171
+ if ($this->setting('update/hold')=='ping') :
172
  $stale = false; // don't update on any timed updates; pings only
173
+ elseif ($this->setting('update/hold')=='next') :
174
  $stale = true; // update on the next timed update
175
+ elseif ( !$this->setting('update/last') ) :
176
  $stale = true; // initial update
177
  elseif ($feedwordpress->force_update_all()) :
178
  $stale = true; // forced general updating
179
  else :
180
+ $after = (
181
+ (int) $this->setting('update/last')
182
+ + (int) $this->setting('update/fudge')
183
+ + ((int) $this->setting('update/ttl') * 60)
184
+ );
185
  $stale = (time() >= $after);
186
  endif;
187
  return $stale;
285
 
286
  $this->settings = array_merge($this->settings, $this->flatten_array($channel));
287
 
288
+ $this->settings['update/last'] = time();
289
+ list($ttl, $xml) = $this->ttl(/*return element=*/ true);
290
+
291
  if (!is_null($ttl)) :
292
  $this->settings['update/ttl'] = $ttl;
293
+ $this->settings['update/xml'] = $xml;
294
  $this->settings['update/timed'] = 'feed';
295
  else :
296
+ $ttl = $this->automatic_ttl();
297
+ $this->settings['update/ttl'] = $ttl;
298
+ $this->settings['update/xml'] = NULL;
299
  $this->settings['update/timed'] = 'automatically';
300
  endif;
301
+ $this->settings['update/fudge'] = rand(0, ($ttl/3))*60;
302
+ $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->setting('update/ttl'), $this);
303
 
304
+ if (!$this->setting('update/hold') != 'ping') :
305
  $this->settings['update/hold'] = 'scheduled';
306
  endif;
307
 
679
  return $ret;
680
  }
681
 
682
+ function ttl ($return_element = false) {
683
  if (is_object($this->magpie)) :
684
  $channel = $this->magpie->channel;
685
  else :
691
  // minutes that indicates how long a channel can be
692
  // cached before refreshing from the source."
693
  // <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
694
+ $xml = 'rss:ttl';
695
  $ret = $channel['ttl'];
696
  elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
697
  $period_minutes = array (
719
  else : $freq = 1;
720
  endif;
721
 
722
+ $xml = 'sy:updateFrequency';
723
  $ret = (int) ($period_minutes[$period] / $freq);
724
  else :
725
+ $xml = NULL;
726
  $ret = NULL;
727
  endif;
728
+
729
+ if ('yes'==$this->setting('update/minimum', 'update_minimum', 'no')) :
730
+ $min = (int) $this->setting('update/window', 'update_window', DEFAULT_UPDATE_PERIOD);
731
+
732
+ if ($min > $ret) :
733
+ $ret = NULL;
734
+ endif;
735
+ endif;
736
+ return ($return_element ? array($ret, $xml) : $ret);
737
  } /* SyndicatedLink::ttl() */
738
 
739
  function automatic_ttl () {
743
  $updateWindow = DEFAULT_UPDATE_PERIOD;
744
  endif;
745
 
746
+ // We get a fudge of 1/3 of window from elsewhere. We'll do some more
747
+ // fudging here.
748
+ $fudgedInterval = $updateWindow+rand(-($updateWindow/6), 5*($updateWindow/12));
749
  return apply_filters('syndicated_feed_automatic_ttl', $fudgedInterval, $this);
750
  } /* SyndicatedLink::automatic_ttl () */
751
 
syndicationdataqueries.class.php CHANGED
@@ -59,7 +59,7 @@ class SyndicationDataQueries {
59
 
60
  // Assemble
61
  $guidMatch = "(guid = '".implode("') OR (guid = '", $seek)."')";
62
- $search .= $wpdb->prepare(" AND ($guidMatch)");
63
  endif;
64
  endif;
65
 
59
 
60
  // Assemble
61
  $guidMatch = "(guid = '".implode("') OR (guid = '", $seek)."')";
62
+ $search .= " AND ($guidMatch)";
63
  endif;
64
  endif;
65