FeedWordPress - Version 2010.0623

Version Description

  • WORDPRESS 3.0 COMPATIBILITY / AUTHOR MAPPING INTERFACE ISSUES: I resolved a couple of outstanding issues with the author mapping interface (Syndication --> Authors), which were preventing new users from being created correctly and author mapping rules from being set up correctly. These partly had to do with new restrictions on user account creation introduced in WordPress 3.0; anyway, they should now be fixed.

  • MORE EFFICIENT SYNDICATED URL LOOKUPS: Several users noticed that the bug fix introduced in 2010.0528 for compatibility with post-listing plugins caused a lot more queries to the database in order to look up numerical post IDs from the URL provided to the filter. This shouldn't cause any major problems, but it is not as efficient as it could be; the code now takes advantage of a more efficient way of doing things, which usually will not require any additional database queries.

  • SIMPLEPIE FEED UPDATE ISSUES: If you have been having significant problems with getting feeds to update correctly, this may be the result of some bugs in the implementation of SimplePie caching that ships with WordPress (as of version 3.0). (You would most commonly experience this error if you continually saw errors such as "No feed found at <...>" in your updates.) Fortunately, SimplePie allows for a great deal of extensibility and this allows me to work around the problem; these error conditions should now be mostly eliminated when the underlying feed is valid.

  • UI: SHOW INACTIVE SOURCES: When you use the default unsubscribe option -- which turns off the subscription to a feed while preserving the posts from it and the syndication-related meta-data for the feed -- the unsubscribed feed can now easily be viewed in a special "Inactive" section of the Syndicated Sources page. (As a side benefit, if you've accidentally, or only temporarily, turned off the subscription to a feed, it is now much easier to restore the feed to being active, or to delete it permanently, if you prefer.

  • UI: FEED FINDER / SWITCH FEED INTERFACE IMPROVEMENTS: changes to styling and options for the feed finder / switch feed, which should now make it easier, in some cases, to find alternative feeds, and make interface options more clearly visible.

  • FILTERS: syndicated_item_published and syndicated_item_updated NOW PROPERLY AFFECT THE DATING OF POSTS. These filters used to affect some date-related settings, but not others -- and, most importantly, not the final date that is set for a post's publication or last-modified date in the WordPress database. Now, they do affect that, as they should. (Filters should receive, and return, a long integer, representing a Unix epoch relative timestamp.)

  • MAGIC URL TO CLEAR THE CACHE: Suppose that you need to clear the feed cache, for whatever reason; suppose, even, that you need to clear it on a regular basis. One way you might do this is by logging into the FeedWordPress administrative interface and going to Syndication --> Performance. Another way you might do it, now, is to simply send an HTTP request to a magic URL provided by FeedWordPress: if your blog is at example.com, the URL would be http://example.com/?clear_cache=1

Download this release

Release Info

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

Code changes from version 2010.0602 to 2010.0623

admin-ui.php CHANGED
@@ -499,6 +499,32 @@ function fwp_author_list () {
499
  }
500
 
501
  class FeedWordPressSettingsUI {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
  function instead_of_posts_box ($link_id = null) {
503
  if (!is_null($link_id)) :
504
  $from_this_feed = 'from this feed';
@@ -622,21 +648,16 @@ function fwp_insert_new_user ($newuser_name) {
622
  if (strlen($newuser_name) > 0) :
623
  $userdata = array();
624
  $userdata['ID'] = NULL;
 
 
 
 
625
 
626
- $userdata['user_login'] = sanitize_user($newuser_name);
627
- $userdata['user_login'] = apply_filters('pre_user_login', $userdata['user_login']);
628
-
629
- $userdata['user_nicename'] = sanitize_title($newuser_name);
630
- $userdata['user_nicename'] = apply_filters('pre_user_nicename', $userdata['user_nicename']);
631
 
632
- $userdata['display_name'] = $wpdb->escape($newuser_name);
633
-
634
  $newuser_id = wp_insert_user($userdata);
635
- if (is_numeric($newuser_id)) :
636
- $ret = $newuser_id;
637
- else :
638
- // TODO: Add some error detection and reporting
639
- endif;
640
  else :
641
  // TODO: Add some error reporting
642
  endif;
499
  }
500
 
501
  class FeedWordPressSettingsUI {
502
+ function is_admin () {
503
+ global $fwp_path;
504
+
505
+ $admin_page = false; // Innocent until proven guilty
506
+ if (isset($_REQUEST['page'])) :
507
+ $admin_page = (
508
+ is_admin()
509
+ and preg_match("|^{$fwp_path}/|", $_REQUEST['page'])
510
+ );
511
+ endif;
512
+ return $admin_page;
513
+ }
514
+
515
+ function admin_scripts () {
516
+ global $fwp_path;
517
+
518
+ wp_enqueue_script('post'); // for magic tag and category boxes
519
+ if (!FeedWordPressCompatibility::test_version(FWP_SCHEMA_29)) : // < 2.9
520
+ wp_enqueue_script('thickbox'); // for fold-up boxes
521
+ endif;
522
+ wp_enqueue_script('admin-forms'); // for checkbox selection
523
+
524
+ wp_register_script('feedwordpress-elements', WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-elements.js');
525
+ wp_enqueue_script('feedwordpress-elements');
526
+ }
527
+
528
  function instead_of_posts_box ($link_id = null) {
529
  if (!is_null($link_id)) :
530
  $from_this_feed = 'from this feed';
648
  if (strlen($newuser_name) > 0) :
649
  $userdata = array();
650
  $userdata['ID'] = NULL;
651
+ $userdata['user_login'] = apply_filters('pre_user_login', sanitize_user($newuser_name));
652
+ $userdata['user_nicename'] = apply_filters('pre_user_nicename', sanitize_title($newuser_name));
653
+ $userdata['display_name'] = $newuser_name;
654
+ $userdata['user_pass'] = substr(md5(uniqid(microtime())), 0, 6); // just something random to lock it up
655
 
656
+ $blahUrl = get_bloginfo('url'); $url = parse_url($blahUrl);
657
+ $userdata['user_email'] = substr(md5(uniqid(microtime())), 0, 6).'@'.$url['host'];
 
 
 
658
 
 
 
659
  $newuser_id = wp_insert_user($userdata);
660
+ $ret = $newuser_id; // Either a numeric ID or a WP_Error object
 
 
 
 
661
  else :
662
  // TODO: Add some error reporting
663
  endif;
authors-page.php CHANGED
@@ -7,11 +7,15 @@ class FeedWordPressAuthorsPage extends FeedWordPressAdminPage {
7
 
8
  function FeedWordPressAuthorsPage ($link) {
9
  FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpressauthors', $link);
10
- $this->authorlist = fwp_author_list();
11
  $this->dispatch = 'feedwordpress_author_settings';
12
  $this->filename = __FILE__;
13
  }
14
 
 
 
 
 
15
  /*static*/ function syndicated_authors_box ($page, $box = NULL) {
16
  $link = $page->link;
17
  $unfamiliar = array ('create' => '','default' => '','filter' => '');
@@ -171,27 +175,7 @@ function fwp_authors_page () {
171
  if (isset($GLOBALS['fwp_post']['fix_mismatch'])) :
172
  if ('newuser'==$GLOBALS['fwp_post']['fix_mismatch_to']) :
173
  $newuser_name = trim($GLOBALS['fwp_post']['fix_mismatch_to_newuser']);
174
- if (strlen($newuser_name) > 0) :
175
- $userdata = array();
176
- $userdata['ID'] = NULL;
177
-
178
- $userdata['user_login'] = sanitize_user($newuser_name);
179
- $userdata['user_login'] = apply_filters('pre_user_login', $userdata['user_login']);
180
-
181
- $userdata['user_nicename'] = sanitize_title($newuser_name);
182
- $userdata['user_nicename'] = apply_filters('pre_user_nicename', $userdata['user_nicename']);
183
-
184
- $userdata['display_name'] = $wpdb->escape($newuser_name);
185
-
186
- $newuser_id = wp_insert_user($userdata);
187
- if (is_numeric($newuser_id)) :
188
- $fix_mismatch_to_id = $newuser_id;
189
- else :
190
- // TODO: Add some error detection and reporting
191
- endif;
192
- else :
193
- // TODO: Add some error reporting
194
- endif;
195
  else :
196
  $fix_mismatch_to_id = $GLOBALS['fwp_post']['fix_mismatch_to'];
197
  endif;
@@ -238,6 +222,7 @@ function fwp_authors_page () {
238
  $mesg = "Couldn't find any posts that matched your criteria.";
239
  endif;
240
  endif;
 
241
  elseif (isset($GLOBALS['fwp_post']['save'])) :
242
  if (is_object($link) and $link->found()) :
243
  $alter = array ();
@@ -297,27 +282,12 @@ function fwp_authors_page () {
297
  else :
298
  if ('newuser'==$GLOBALS['fwp_post']['unfamiliar_author']) :
299
  $newuser_name = trim($GLOBALS['fwp_post']['unfamiliar_author_newuser']);
300
- if (strlen($newuser_name) > 0) :
301
- $userdata = array();
302
- $userdata['ID'] = NULL;
303
-
304
- $userdata['user_login'] = sanitize_user($newuser_name);
305
- $userdata['user_login'] = apply_filters('pre_user_login', $userdata['user_login']);
306
-
307
- $userdata['user_nicename'] = sanitize_title($newuser_name);
308
- $userdata['user_nicename'] = apply_filters('pre_user_nicename', $userdata['user_nicename']);
309
-
310
- $userdata['display_name'] = $wpdb->escape($newuser_name);
311
-
312
- $newuser_id = wp_insert_user($userdata);
313
- if (is_numeric($newuser_id)) :
314
- update_option('feedwordpress_unfamiliar_author', $newuser_id);
315
- else :
316
- // TODO: Add some error detection and reporting
317
- endif;
318
  else :
319
- // TODO: Add some error reporting
320
- endif;
321
  else :
322
  update_option('feedwordpress_unfamiliar_author', $GLOBALS['fwp_post']['unfamiliar_author']);
323
  endif;
@@ -336,6 +306,7 @@ function fwp_authors_page () {
336
  endif;
337
 
338
  do_action('feedwordpress_admin_page_authors_save', $GLOBALS['fwp_post'], $authorsPage);
 
339
  else :
340
  $updated_link = false;
341
  endif;
7
 
8
  function FeedWordPressAuthorsPage ($link) {
9
  FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpressauthors', $link);
10
+ $this->refresh_author_list();
11
  $this->dispatch = 'feedwordpress_author_settings';
12
  $this->filename = __FILE__;
13
  }
14
 
15
+ function refresh_author_list () {
16
+ $this->authorlist = fwp_author_list();
17
+ }
18
+
19
  /*static*/ function syndicated_authors_box ($page, $box = NULL) {
20
  $link = $page->link;
21
  $unfamiliar = array ('create' => '','default' => '','filter' => '');
175
  if (isset($GLOBALS['fwp_post']['fix_mismatch'])) :
176
  if ('newuser'==$GLOBALS['fwp_post']['fix_mismatch_to']) :
177
  $newuser_name = trim($GLOBALS['fwp_post']['fix_mismatch_to_newuser']);
178
+ $fix_mismatch_to_id = fwp_insert_new_user($newuser_name);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  else :
180
  $fix_mismatch_to_id = $GLOBALS['fwp_post']['fix_mismatch_to'];
181
  endif;
222
  $mesg = "Couldn't find any posts that matched your criteria.";
223
  endif;
224
  endif;
225
+ $updated_link = false;
226
  elseif (isset($GLOBALS['fwp_post']['save'])) :
227
  if (is_object($link) and $link->found()) :
228
  $alter = array ();
282
  else :
283
  if ('newuser'==$GLOBALS['fwp_post']['unfamiliar_author']) :
284
  $newuser_name = trim($GLOBALS['fwp_post']['unfamiliar_author_newuser']);
285
+ $newuser_id = fwp_insert_new_user($newuser_name);
286
+ if (is_numeric($newuser_id)) :
287
+ update_option('feedwordpress_unfamiliar_author', $newuser_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  else :
289
+ // TODO: Add some error detection and reporting
290
+ endif;
291
  else :
292
  update_option('feedwordpress_unfamiliar_author', $GLOBALS['fwp_post']['unfamiliar_author']);
293
  endif;
306
  endif;
307
 
308
  do_action('feedwordpress_admin_page_authors_save', $GLOBALS['fwp_post'], $authorsPage);
309
+ $authorsPage->refresh_author_list();
310
  else :
311
  $updated_link = false;
312
  endif;
compatability.php CHANGED
@@ -60,32 +60,15 @@ class FeedWordPressCompatibility {
60
 
61
  $cat_id = NULL;
62
 
63
- // WordPress 2.3 introduces a new taxonomy/term API
64
- if (function_exists('is_term')) :
65
- $the_term = is_term($value, 'link_category');
66
 
67
- // Sometimes, in some versions, we get a row
68
- if (is_array($the_term)) :
69
- $cat_id = $the_term['term_id'];
70
 
71
- // other times we get an integer result
72
- else :
73
- $cat_id = $the_term;
74
- endif;
75
-
76
- // WordPress 2.1 and 2.2 use a common table for both link and post categories
77
- elseif (fwp_test_wp_version(FWP_SCHEMA_21, FWP_SCHEMA_23)) :
78
- $value = $wpdb->escape($value);
79
- $cat_id = $wpdb->get_var("SELECT cat_id FROM {$wpdb->categories} WHERE {$key}='$value'");
80
-
81
- // WordPress 1.5 and 2.0.x have a separate table for link categories
82
- elseif (fwp_test_wp_version(0, FWP_SCHEMA_21)):
83
- $value = $wpdb->escape($value);
84
- $cat_id = $wpdb->get_var("SELECT cat_id FROM {$wpdb->linkcategories} WHERE {$key}='$value'");
85
-
86
- // This should never happen.
87
  else :
88
- FeedWordPress::critical_bug(__CLASS__.'::'.__METHOD__.'::wp_db_version', $wp_db_version, __LINE__);
89
  endif;
90
 
91
  return $cat_id;
@@ -255,6 +238,12 @@ if (!function_exists('disabled')) {
255
  }
256
  } /* if */
257
 
 
 
 
 
 
 
258
  require_once(dirname(__FILE__).'/feedwordpress-walker-category-checklist.class.php');
259
 
260
  function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selected_cats = false, $prefix = '') {
60
 
61
  $cat_id = NULL;
62
 
63
+ $the_term = term_exists($value, 'link_category');
 
 
64
 
65
+ // Sometimes, in some versions, we get a row
66
+ if (is_array($the_term)) :
67
+ $cat_id = $the_term['term_id'];
68
 
69
+ // other times we get an integer result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  else :
71
+ $cat_id = $the_term;
72
  endif;
73
 
74
  return $cat_id;
238
  }
239
  } /* if */
240
 
241
+ if (!function_exists('term_exists')) {
242
+ // Fucking WordPress 3.0 wordsmithing.
243
+ function term_exists ( $term, $taxonomy = '', $parent = 0 ) {
244
+ return is_term($term, $taxonomy, $parent);
245
+ }
246
+ } /* if */
247
  require_once(dirname(__FILE__).'/feedwordpress-walker-category-checklist.class.php');
248
 
249
  function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selected_cats = false, $prefix = '') {
diagnostics-page.php CHANGED
@@ -131,7 +131,8 @@ caution: this setting is absolutely inappropriate for a production server.</p>
131
  $checked = array(
132
  'updated_feeds' => '',
133
  "syndicated_posts" => '', 'syndicated_posts:meta_data' => '',
134
- 'feed_items' => ''
 
135
  );
136
 
137
  $diagnostics_show = get_option('feedwordpress_diagnostics_show', array());
@@ -150,6 +151,7 @@ caution: this setting is absolutely inappropriate for a production server.</p>
150
  <li><label><input type="checkbox" name="diagnostics_show[]" value="updated_feeds" <?php print $checked['updated_feeds']; ?> /> as each feed checked for updates</label></li>
151
  <li><label><input type="checkbox" name="diagnostics_show[]" value="syndicated_posts" <?php print $checked['syndicated_posts']; ?> /> as each syndicated post is added to the database</label></li>
152
  <li><label><input type="checkbox" name="diagnostics_show[]" value="feed_items" <?php print $checked['feed_items']; ?> /> as each syndicated item is considered on the feed</label></li>
 
153
  </ul></td>
154
  </tr>
155
  <tr style="vertical-align: top">
131
  $checked = array(
132
  'updated_feeds' => '',
133
  "syndicated_posts" => '', 'syndicated_posts:meta_data' => '',
134
+ 'feed_items' => '',
135
+ 'memory_usage' => '',
136
  );
137
 
138
  $diagnostics_show = get_option('feedwordpress_diagnostics_show', array());
151
  <li><label><input type="checkbox" name="diagnostics_show[]" value="updated_feeds" <?php print $checked['updated_feeds']; ?> /> as each feed checked for updates</label></li>
152
  <li><label><input type="checkbox" name="diagnostics_show[]" value="syndicated_posts" <?php print $checked['syndicated_posts']; ?> /> as each syndicated post is added to the database</label></li>
153
  <li><label><input type="checkbox" name="diagnostics_show[]" value="feed_items" <?php print $checked['feed_items']; ?> /> as each syndicated item is considered on the feed</label></li>
154
+ <li><label><input type="checkbox" name="diagnostics_show[]" value="memory_usage" <?php print $checked['memory_usage']; ?> /> indicating how much memory was used</label></li>
155
  </ul></td>
156
  </tr>
157
  <tr style="vertical-align: top">
feedfinder.class.php CHANGED
@@ -1,7 +1,11 @@
1
  <?php
2
- ################################################################################
3
- ## class FeedFinder: find likely feeds using autodetection and/or guesswork ####
4
- ################################################################################
 
 
 
 
5
 
6
  class FeedFinder {
7
  var $uri = NULL;
@@ -35,7 +39,7 @@ class FeedFinder {
35
  $ret = array ();
36
  if (!is_null($this->data($uri))) {
37
  if ($this->is_feed($uri)) {
38
- $ret = array($this->uri);
39
  } else {
40
  // Assume that we have HTML or XHTML (even if we don't, who's it gonna hurt?)
41
  // Autodiscovery is the preferred method
@@ -50,21 +54,26 @@ class FeedFinder {
50
  // Our search may turn up duplicate URIs. We only need to do any given URI once.
51
  // Props to Camilo <http://projects.radgeek.com/2008/12/14/feedwordpress-20081214/#comment-20090122160414>
52
  $href = array_unique($href);
53
-
54
- // Verify feeds and resolve relative URIs
55
- foreach ($href as $u) {
56
- $the_uri = Relative_URI::resolve($u, $this->uri);
57
- if ($this->verify) {
58
- $feed = new FeedFinder($the_uri);
59
- if ($feed->is_feed()) $ret[] = $the_uri;
60
- unset($feed);
61
- } else {
62
- $ret[] = $the_uri;
63
- }
64
- } /* foreach */
65
  } /* if */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  } /* if */
67
- return array_unique($ret);
 
68
  } /* FeedFinder::find () */
69
 
70
  function data ($uri = NULL) {
@@ -171,6 +180,61 @@ class FeedFinder {
171
  return $href;
172
  }
173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  function _tags ($tag) {
175
  $html = $this->data();
176
 
1
  <?php
2
+ /**
3
+ * class FeedFinder: find likely feeds using autodetection and/or guesswork
4
+ * @version 2010.0622
5
+ * @uses SimplePie_Misc
6
+ */
7
+
8
+ require_once(ABSPATH . WPINC . '/class-simplepie.php');
9
 
10
  class FeedFinder {
11
  var $uri = NULL;
39
  $ret = array ();
40
  if (!is_null($this->data($uri))) {
41
  if ($this->is_feed($uri)) {
42
+ $href = array($this->uri);
43
  } else {
44
  // Assume that we have HTML or XHTML (even if we don't, who's it gonna hurt?)
45
  // Autodiscovery is the preferred method
54
  // Our search may turn up duplicate URIs. We only need to do any given URI once.
55
  // Props to Camilo <http://projects.radgeek.com/2008/12/14/feedwordpress-20081214/#comment-20090122160414>
56
  $href = array_unique($href);
 
 
 
 
 
 
 
 
 
 
 
 
57
  } /* if */
58
+
59
+ // Try some clever URL little tricks before we go
60
+ $href = array_merge($href, $this->_url_manipulation_feeds());
61
+ $href = array_unique($href);
62
+
63
+ // Verify feeds and resolve relative URIs
64
+ foreach ($href as $u) {
65
+ $the_uri = SimplePie_Misc::absolutize_url($u, $this->uri);
66
+ if ($this->verify and ($u != $this->uri and $the_uri != $this->uri)) {
67
+ $feed = new FeedFinder($the_uri);
68
+ if ($feed->is_feed()) : $ret[] = $the_uri; endif;
69
+ unset($feed);
70
+ } else {
71
+ $ret[] = $the_uri;
72
+ }
73
+ } /* foreach */
74
  } /* if */
75
+
76
+ return array_values($ret);
77
  } /* FeedFinder::find () */
78
 
79
  function data ($uri = NULL) {
180
  return $href;
181
  }
182
 
183
+ function _url_manipulation_feeds () {
184
+ $href = array();
185
+
186
+ // check for HTTP GET parameters that look feed-like.
187
+ $bits = parse_url($this->uri);
188
+ foreach (array('rss', 'rss2', 'atom', 'rdf') as $format) :
189
+ if (isset($bits['query']) and (strlen($bits['query']) > 0)) :
190
+ $newQuery = preg_replace('/([?&=])(rss2?|atom|rdf)/i', '$1'.$format, $bits['query']);
191
+ else :
192
+ $newQuery = NULL;
193
+ endif;
194
+
195
+ if (isset($bits['path']) and (strlen($bits['path']) > 0)) :
196
+ $newPath = preg_replace('!([/.])(rss2?|atom|rdf)!i', '$1'.$format, $bits['path']);
197
+ else :
198
+ $newPath = NULL;
199
+ endif;
200
+
201
+ // Reassemble, check and return
202
+ $credentials = '';
203
+ if (isset($bits['user'])) :
204
+ $credentials = $bits['user'];
205
+ if (isset($bits['pass'])) :
206
+ $credentials .= ':'.$bits['pass'];
207
+ endif;
208
+ $credentials .= '@';
209
+ endif;
210
+
211
+ // Variations on a theme
212
+ $newUrl[0] = (''
213
+ .(isset($bits['scheme']) ? $bits['scheme'].':' : '')
214
+ .(isset($bits['host']) ? '//'.$credentials.$bits['host'] : '')
215
+ .(!is_null($newPath) ? $newPath : '')
216
+ .(!is_null($newQuery) ? '?'.$newQuery : '')
217
+ .(isset($bits['fragment']) ? '#'.$bits['fragment'] : '')
218
+ );
219
+ $newUrl[1] = (''
220
+ .(isset($bits['scheme']) ? $bits['scheme'].':' : '')
221
+ .(isset($bits['host']) ? '//'.$credentials.$bits['host'] : '')
222
+ .(!is_null($newPath) ? $newPath : '')
223
+ .(isset($bits['query']) ? '?'.$bits['query'] : '')
224
+ .(isset($bits['fragment']) ? '#'.$bits['fragment'] : '')
225
+ );
226
+ $newUrl[2] = (''
227
+ .(isset($bits['scheme']) ? $bits['scheme'].':' : '')
228
+ .(isset($bits['host']) ? '//'.$credentials.$bits['host'] : '')
229
+ .(isset($bits['path']) ? $bits['path'] : '')
230
+ .(!is_null($newQuery) ? '?'.$newQuery : '')
231
+ .(isset($bits['fragment']) ? '#'.$bits['fragment'] : '')
232
+ );
233
+ $href = array_merge($href, $newUrl);
234
+ endforeach;
235
+ return array_unique($href);
236
+ }
237
+
238
  function _tags ($tag) {
239
  $html = $this->data();
240
 
feeds-page.php CHANGED
@@ -536,20 +536,69 @@ contextual_appearance('time-limit', 'time-limit-box', null, 'yes');
536
 
537
  $lookup = (isset($_REQUEST['lookup']) ? $_REQUEST['lookup'] : NULL);
538
 
 
539
  if ($this->for_feed_settings()) : // Existing feed?
540
- if (is_null($lookup)) : $lookup = $this->link->link->link_url; endif;
 
 
 
 
 
 
 
 
 
 
 
541
  $name = esc_html($this->link->link->link_name);
542
  else: // Or a new subscription to add?
543
  $name = "Subscribe to <code>".esc_html(feedwordpress_display_url($lookup))."</code>";
544
  endif;
545
  ?>
546
- <div class="wrap">
547
  <h2>Feed Finder: <?php echo $name; ?></h2>
548
 
549
  <?php
550
- $f = new FeedFinder($lookup);
551
- $feeds = $f->find();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
  if (count($feeds) > 0):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
553
  foreach ($feeds as $key => $f):
554
  $pie = FeedWordPress::fetch($f);
555
  $rss = (is_wp_error($pie) ? $pie : new MagpieFromSimplePie($pie));
@@ -558,19 +607,32 @@ contextual_appearance('time-limit', 'time-limit-box', null, 'yes');
558
  $feed_title = isset($rss->channel['title'])?$rss->channel['title']:$rss->channel['link'];
559
  $feed_link = isset($rss->channel['link'])?$rss->channel['link']:'';
560
  $feed_type = ($rss->feed_type ? $rss->feed_type : 'Unknown');
 
561
  $feed_version = $rss->feed_version;
562
  else :
563
  // Give us some sucky defaults
564
  $feed_title = feedwordpress_display_url($lookup);
565
  $feed_link = $lookup;
566
  $feed_type = 'Unknown';
 
567
  $feed_version = '';
568
  endif;
569
  ?>
570
- <form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/syndication.php" method="post">
571
- <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_switchfeed'); ?></div>
572
- <fieldset>
573
- <legend><?php echo $feed_type; ?> <?php echo $feed_version; ?> feed</legend>
 
 
 
 
 
 
 
 
 
 
 
574
 
575
  <?php
576
  $this->stamp_link_id();
@@ -631,70 +693,98 @@ contextual_appearance('time-limit', 'time-limit-box', null, 'yes');
631
  <h3>Feed Information</h3>
632
  <ul>
633
  <li><strong>Homepage:</strong> <a href="<?php echo $feed_link; ?>"><?php echo is_null($feed_title)?'<em>Unknown</em>':$feed_title; ?></a></li>
634
- <li><strong>Feed URL:</strong> <a href="<?php echo esc_html($f); ?>"><?php echo esc_html($f); ?></a> (<a title="Check feed &lt;<?php echo esc_html($f); ?>&gt; for validity" href="http://feedvalidator.org/check.cgi?url=<?php echo urlencode($f); ?>">validate</a>)</li>
635
  <li><strong>Encoding:</strong> <?php echo isset($rss->encoding)?esc_html($rss->encoding):"<em>Unknown</em>"; ?></li>
636
  <li><strong>Description:</strong> <?php echo isset($rss->channel['description'])?esc_html($rss->channel['description']):"<em>Unknown</em>"; ?></li>
637
  </ul>
638
  <?php do_action('feedwordpress_feedfinder_form', $f, $post, $link, $this->for_feed_settings()); ?>
639
- <div class="submit"><input type="submit" name="Use" value="&laquo; Use this feed" /></div>
640
- <div class="submit"><input type="submit" name="Cancel" value="&laquo; Cancel" /></div>
641
  </div>
642
  </div>
643
  </fieldset>
 
644
  </form>
645
  <?php
646
  unset($link);
647
  unset($post);
648
  endforeach;
649
  else:
650
- print "<p><strong>".__('Error').":</strong> ".__("FeedWordPress couldn't find any feeds at").' <code><a href="'.htmlspecialchars($lookup).'">'.htmlspecialchars($lookup).'</a></code>';
651
- print ". ".__('Try another URL').".</p>";
 
 
 
652
 
653
- // Diagnostics
654
- print "<div class=\"updated\" style=\"margin-left: 3.0em; margin-right: 3.0em;\">\n";
655
- print "<h3>".__('Diagnostic information')."</h3>\n";
656
- if (!is_null($f->error()) and strlen($f->error()) > 0) :
657
- print "<h4>".__('HTTP request failure')."</h4>\n";
658
- print "<p>".$f->error()."</p>\n";
659
- else :
660
- print "<h4>".__('HTTP request completed')."</h4>\n";
661
- print "<p><strong>Status ".$f->status().":</strong> ".$this->HTTPStatusMessages[(int) $f->status()]."</p>\n";
662
- endif;
663
-
664
- // Do some more diagnostics if the API for it is available.
665
- if (function_exists('_wp_http_get_object')) :
666
- $httpObject = _wp_http_get_object();
667
- $transports = $httpObject->_getTransport();
668
-
669
- print "<h4>".__('HTTP Transports available').":</h4>\n";
670
- print "<ol>\n";
671
- print "<li>".implode("</li>\n<li>", array_map('get_class', $transports))."</li>\n";
672
- print "</ol>\n";
673
- print "</div>\n";
674
- endif;
675
 
676
- endif;
677
- ?>
678
- </div>
 
679
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
680
  <form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>" method="post">
681
- <div><?php
682
  FeedWordPressCompatibility::stamp_nonce(get_class($this));
683
- ?></div>
684
- <div class="wrap">
685
- <h2>Use another feed</h2>
686
- <div><label>Feed:</label>
687
- <input type="text" name="lookup" id="use-another-feed" value="URI" />
 
 
 
 
 
 
 
 
 
 
688
  <?php FeedWordPressSettingsUI::magic_input_tip_js('use-another-feed'); ?>
 
689
  <?php $this->stamp_link_id('link_id'); ?>
690
- <input type="hidden" name="action" value="feedfinder" /></div>
691
- <div class="submit"><input type="submit" value="Use this feed &raquo;" /></div>
692
- </div>
693
- </form>
 
 
 
 
694
  <?php
695
- return false; // Don't continue
696
- } /* WordPressFeedsPage::display_feedfinder() */
697
-
698
  function accept_POST ($post) {
699
  global $wpdb;
700
 
536
 
537
  $lookup = (isset($_REQUEST['lookup']) ? $_REQUEST['lookup'] : NULL);
538
 
539
+ $feeds = array(); $feedSwitch = false; $current = null;
540
  if ($this->for_feed_settings()) : // Existing feed?
541
+ $feedSwitch = true;
542
+ if (is_null($lookup)) :
543
+ // Switch Feed without a specific feed yet suggested
544
+ // Go to the human-readable homepage to look for
545
+ // auto-detection links
546
+ $lookup = $this->link->link->link_url;
547
+
548
+ // Guarantee that you at least have the option to
549
+ // stick with what works.
550
+ $current = $this->link->link->link_rss;
551
+ $feeds[] = $current;
552
+ endif;
553
  $name = esc_html($this->link->link->link_name);
554
  else: // Or a new subscription to add?
555
  $name = "Subscribe to <code>".esc_html(feedwordpress_display_url($lookup))."</code>";
556
  endif;
557
  ?>
558
+ <div class="wrap" id="feed-finder">
559
  <h2>Feed Finder: <?php echo $name; ?></h2>
560
 
561
  <?php
562
+ if ($feedSwitch) :
563
+ $this->display_alt_feed_box($lookup);
564
+ endif;
565
+
566
+ $finder = array();
567
+ if (!is_null($current)) :
568
+ $finder[$current] = new FeedFinder($current);
569
+ endif;
570
+ $finder[$lookup] = new FeedFinder($lookup);
571
+
572
+ foreach ($finder as $url => $ff) :
573
+ $feeds = array_merge($feeds, $ff->find());
574
+ endforeach;
575
+
576
+ $feeds = array_values( // Renumber from 0..(N-1)
577
+ array_unique( // Eliminate duplicates
578
+ $feeds
579
+ )
580
+ );
581
+
582
  if (count($feeds) > 0):
583
+ if ($feedSwitch) :
584
+ ?>
585
+ <h3>Feeds Found</h3>
586
+ <?php
587
+ endif;
588
+
589
+ if (count($feeds) > 1) :
590
+ $option_template = 'Option %d: ';
591
+ $form_class = ' class="multi"';
592
+ ?>
593
+ <p><strong>This web page provides at least <?php print count($feeds); ?> different feeds.</strong> These feeds may provide the same information
594
+ in different formats, or may track different items. (You can check the Feed Information and the
595
+ Sample Item for each feed to get an idea of what the feed provides.) Please select the feed that you'd like to subscribe to.</p>
596
+ <?php
597
+ else :
598
+ $option_template = '';
599
+ $form_class = '';
600
+ endif;
601
+
602
  foreach ($feeds as $key => $f):
603
  $pie = FeedWordPress::fetch($f);
604
  $rss = (is_wp_error($pie) ? $pie : new MagpieFromSimplePie($pie));
607
  $feed_title = isset($rss->channel['title'])?$rss->channel['title']:$rss->channel['link'];
608
  $feed_link = isset($rss->channel['link'])?$rss->channel['link']:'';
609
  $feed_type = ($rss->feed_type ? $rss->feed_type : 'Unknown');
610
+ $feed_version_template = '%.1f';
611
  $feed_version = $rss->feed_version;
612
  else :
613
  // Give us some sucky defaults
614
  $feed_title = feedwordpress_display_url($lookup);
615
  $feed_link = $lookup;
616
  $feed_type = 'Unknown';
617
+ $feed_version_template = '';
618
  $feed_version = '';
619
  endif;
620
  ?>
621
+ <form<?php print $form_class; ?> action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/syndication.php" method="post">
622
+ <div class="inside"><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_switchfeed'); ?>
623
+
624
+ <?php
625
+ $classes = array('feed-found'); $currentFeed = '';
626
+ if (!is_null($current) and $current==$f) :
627
+ $classes[] = 'current';
628
+ $currentFeed = ' (currently subscribed)';
629
+ endif;
630
+ if ($key%2) :
631
+ $classes[] = 'alt';
632
+ endif;
633
+ ?>
634
+ <fieldset class="<?php print implode(" ", $classes); ?>">
635
+ <legend><?php printf($option_template, ($key+1)); print $feed_type." "; printf($feed_version_template, $feed_version); ?> feed<?php print $currentFeed; ?></legend>
636
 
637
  <?php
638
  $this->stamp_link_id();
693
  <h3>Feed Information</h3>
694
  <ul>
695
  <li><strong>Homepage:</strong> <a href="<?php echo $feed_link; ?>"><?php echo is_null($feed_title)?'<em>Unknown</em>':$feed_title; ?></a></li>
696
+ <li><strong>Feed URL:</strong> <a title="<?php echo esc_html($f); ?>" href="<?php echo esc_html($f); ?>"><?php echo esc_html(feedwordpress_display_url($f, 40, 10)); ?></a> (<a title="Check feed &lt;<?php echo esc_html($f); ?>&gt; for validity" href="http://feedvalidator.org/check.cgi?url=<?php echo urlencode($f); ?>">validate</a>)</li>
697
  <li><strong>Encoding:</strong> <?php echo isset($rss->encoding)?esc_html($rss->encoding):"<em>Unknown</em>"; ?></li>
698
  <li><strong>Description:</strong> <?php echo isset($rss->channel['description'])?esc_html($rss->channel['description']):"<em>Unknown</em>"; ?></li>
699
  </ul>
700
  <?php do_action('feedwordpress_feedfinder_form', $f, $post, $link, $this->for_feed_settings()); ?>
701
+ <div class="submit"><input type="submit" class="button-primary" name="Use" value="&laquo; Use this feed" />
702
+ <input type="submit" class="button" name="Cancel" value="× Cancel" /></div>
703
  </div>
704
  </div>
705
  </fieldset>
706
+ </div> <!-- class="inside" -->
707
  </form>
708
  <?php
709
  unset($link);
710
  unset($post);
711
  endforeach;
712
  else:
713
+ foreach ($finder as $url => $ff) :
714
+ $url = esc_html($url);
715
+ print "<h3>Searched for feeds at ${url}</h3>\n";
716
+ print "<p><strong>".__('Error').":</strong> ".__("FeedWordPress couldn't find any feeds at").' <code><a href="'.htmlspecialchars($lookup).'">'.htmlspecialchars($lookup).'</a></code>';
717
+ print ". ".__('Try another URL').".</p>";
718
 
719
+ // Diagnostics
720
+ print "<div class=\"updated\" style=\"margin-left: 3.0em; margin-right: 3.0em;\">\n";
721
+ print "<h3>".__('Diagnostic information')."</h3>\n";
722
+ if (!is_null($ff->error()) and strlen($ff->error()) > 0) :
723
+ print "<h4>".__('HTTP request failure')."</h4>\n";
724
+ print "<p>".$ff->error()."</p>\n";
725
+ else :
726
+ print "<h4>".__('HTTP request completed')."</h4>\n";
727
+ print "<p><strong>Status ".$ff->status().":</strong> ".$this->HTTPStatusMessages[(int) $ff->status()]."</p>\n";
728
+ endif;
 
 
 
 
 
 
 
 
 
 
 
 
729
 
730
+ // Do some more diagnostics if the API for it is available.
731
+ if (function_exists('_wp_http_get_object')) :
732
+ $httpObject = _wp_http_get_object();
733
+ $transports = $httpObject->_getTransport();
734
 
735
+ print "<h4>".__('HTTP Transports available').":</h4>\n";
736
+ print "<ol>\n";
737
+ print "<li>".implode("</li>\n<li>", array_map('get_class', $transports))."</li>\n";
738
+ print "</ol>\n";
739
+ print "</div>\n";
740
+ endif;
741
+ endforeach;
742
+ endif;
743
+
744
+ if (!$feedSwitch) :
745
+ $this->display_alt_feed_box($lookup, /*alt=*/ true);
746
+ endif;
747
+ ?>
748
+ </div> <!-- class="wrap" -->
749
+ <?php
750
+ return false; // Don't continue
751
+ } /* WordPressFeedsPage::display_feedfinder() */
752
+
753
+ function display_alt_feed_box ($lookup, $alt = false) {
754
+ global $fwp_post;
755
+ ?>
756
  <form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>" method="post">
757
+ <div class="inside"><?php
758
  FeedWordPressCompatibility::stamp_nonce(get_class($this));
759
+ ?>
760
+ <fieldset class="alt"
761
+ <?php if (!$alt): ?>style="margin: 1.0em 3.0em; font-size: smaller;"<?php endif; ?>>
762
+ <legend><?php if ($alt) : ?>Alternative feeds<?php else: ?>Find feeds<?php endif; ?></legend>
763
+ <?php if ($alt) : ?><h3>Use a different feed</h3><?php endif; ?>
764
+ <div><label>Address:
765
+ <input type="text" name="lookup" id="use-another-feed"
766
+ placeholder="URL"
767
+ <?php if (is_null($lookup)) : ?>
768
+ value="URL"
769
+ <?php else : ?>
770
+ value="<?php print esc_html($lookup); ?>"
771
+ <?php endif; ?>
772
+ size="64" style="max-width: 80%" /></label>
773
+ <?php if (is_null($lookup)) : ?>
774
  <?php FeedWordPressSettingsUI::magic_input_tip_js('use-another-feed'); ?>
775
+ <?php endif; ?>
776
  <?php $this->stamp_link_id('link_id'); ?>
777
+ <input type="hidden" name="action" value="feedfinder" />
778
+ <input type="submit" class="button<?php if ($alt): ?>-primary<?php endif; ?>" value="Check &raquo;" /></div>
779
+ <p>This can be the address of a feed, or of a website. FeedWordPress
780
+ will try to automatically detect any feeds associated with a
781
+ website.</p>
782
+ </div> <!-- class="inside" -->
783
+ </fieldset></form>
784
+
785
  <?php
786
+ } /* WordPressFeedsPage::display_alt_feed_box() */
787
+
 
788
  function accept_POST ($post) {
789
  global $wpdb;
790
 
feedwordpress-content-type-sniffer.class.php CHANGED
@@ -1,4 +1,6 @@
1
  <?php
 
 
2
  class FeedWordPress_Content_Type_Sniffer extends SimplePie_Content_Type_Sniffer {
3
  /**
4
  * Get the Content-Type of the specified file
@@ -34,13 +36,21 @@ class FeedWordPress_Content_Type_Sniffer extends SimplePie_Content_Type_Sniffer
34
  if (!is_null($contentType)) :
35
  $outHeader[] = $contentType;
36
  else :
37
- $outHeader[] = 'application/xml'; // Generic
38
  endif;
39
  if (!is_null($charset)) :
40
  $outHeader[] = $charset;
41
  endif;
42
 
43
  $this->file->headers['content-type'] = implode("; ", $outHeader);
 
 
 
 
 
 
 
 
44
  endif;
45
  return parent::get_type();
46
  } /* FeedWordPress_Content_Type_Sniffer::get_type() */
1
  <?php
2
+ require_once(ABSPATH . WPINC . '/class-feed.php');
3
+
4
  class FeedWordPress_Content_Type_Sniffer extends SimplePie_Content_Type_Sniffer {
5
  /**
6
  * Get the Content-Type of the specified file
36
  if (!is_null($contentType)) :
37
  $outHeader[] = $contentType;
38
  else :
39
+ $outHeader[] = 'text/xml'; // Generic
40
  endif;
41
  if (!is_null($charset)) :
42
  $outHeader[] = $charset;
43
  endif;
44
 
45
  $this->file->headers['content-type'] = implode("; ", $outHeader);
46
+ else :
47
+ // The default SimplePie behavior seems to be to return
48
+ // text/plain if it can't find a Content-Type header.
49
+ // The default SimplePie behavior sucks. Particularly
50
+ // since SimplePie gets so draconian about Content-Type.
51
+ // And since the WP SimplePie seems to drop Content-Type
52
+ // from cached copies for some unfortunate reason.
53
+ $this->file->headers['content-type'] = 'text/xml'; // Generic
54
  endif;
55
  return parent::get_type();
56
  } /* FeedWordPress_Content_Type_Sniffer::get_type() */
feedwordpress-elements.css CHANGED
@@ -67,10 +67,61 @@
67
 
68
  /* Switchfeed interface elements */
69
 
70
- form.fieldset {
 
 
 
 
 
 
 
 
 
 
 
71
  clear: both;
 
 
 
 
 
 
 
72
  }
73
- .feed-sample {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  float: right;
75
  background-color: #D0D0D0;
76
  color: black;
@@ -82,11 +133,11 @@ form.fieldset {
82
  max-height: 200px;
83
  overflow: auto;
84
  }
85
- .feed-sample p, .feed-sample h3 {
86
  padding-left: 0.5em;
87
  padding-right: 0.5em;
88
  }
89
- .feed-sample .feed-problem {
90
  background-color: #ffd0d0;
91
  border-bottom: 1px dotted black;
92
  padding-bottom: 0.5em;
67
 
68
  /* Switchfeed interface elements */
69
 
70
+ #feed-finder form {
71
+ padding-bottom: 2.0em;
72
+ border-bottom: 1px dashed #333;
73
+ margin-bottom: 2.0em;
74
+ }
75
+ #feed-finder form.multi .inside {
76
+ margin-left: 1.0em;
77
+ border-left: 3px solid #333;
78
+ padding-left: 2.0em;
79
+ }
80
+
81
+ #feed-finder form fieldset {
82
  clear: both;
83
+ border: 1px solid #777;
84
+ padding: 5px 25px;
85
+ background-color: #fff;
86
+ border-radius: 5px;
87
+ -moz-border-radius: 5px;
88
+ -khtml-border-radius: 5px;
89
+ -webkit-border-radius: 5px;
90
  }
91
+ #feed-finder form fieldset.alt {
92
+ background-color: #eee;
93
+ }
94
+ #feed-finder form fieldset.current {
95
+ background-color: #efe;
96
+ }
97
+ #feed-finder form fieldset.current legend {
98
+ background-color: #7f7;
99
+ }
100
+ #feed-finder form fieldset legend {
101
+ border-left: 1px solid #777;
102
+ border-right: 1px solid #777;
103
+ border-top: 1px solid #777;
104
+ border-bottom: 1px solid #777;
105
+ border-radius: 5px;
106
+ -moz-border-radius: 5px;
107
+ -khtml-border-radius: 5px;
108
+ -webkit-border-radius: 5px;
109
+ background-color: #7FF;
110
+ padding: 3px 10px;
111
+ font-weight: bold;
112
+ }
113
+ #feed-finder form fieldset label {
114
+ font-weight: bold;
115
+ }
116
+ #feed-finder form fieldset div.submit {
117
+ clear: both;
118
+ text-align: left;
119
+ }
120
+ #feed-finder form fieldset div.submit input {
121
+ margin-right: 3.0em;
122
+ }
123
+
124
+ #feed-finder .feed-sample {
125
  float: right;
126
  background-color: #D0D0D0;
127
  color: black;
133
  max-height: 200px;
134
  overflow: auto;
135
  }
136
+ #feed-finder .feed-sample p, .feed-sample h3 {
137
  padding-left: 0.5em;
138
  padding-right: 0.5em;
139
  }
140
+ #feed-finder .feed-sample .feed-problem {
141
  background-color: #ffd0d0;
142
  border-bottom: 1px dotted black;
143
  padding-bottom: 0.5em;
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: 2010.0602
7
  Author: Charles Johnson
8
  Author URI: http://radgeek.com/
9
  License: GPL
@@ -11,13 +11,14 @@ License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
- * @version 2010.0602
15
  */
16
 
17
  # This uses code derived from:
18
  # - wp-rss-aggregate.php by Kellan Elliot-McCrea <kellan@protest.net>
19
- # - HTTP Navigator 2 by Keyvan Minoukadeh <keyvan@k1m.com>
20
  # - Ultra-Liberal Feed Finder by Mark Pilgrim <mark@diveintomark.org>
 
21
  # according to the terms of the GNU General Public License.
22
  #
23
  # INSTALLATION: see readme.txt or <http://projects.radgeek.com/install>
@@ -33,7 +34,7 @@ License: GPL
33
 
34
  # -- Don't change these unless you know what you're doing...
35
 
36
- define ('FEEDWORDPRESS_VERSION', '2010.0602');
37
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
38
 
39
  // Defaults
@@ -96,20 +97,12 @@ add_filter('wp_feed_cache_transient_lifetime', array('FeedWordPress', 'cache_lif
96
  // Ensure that we have SimplePie loaded up and ready to go.
97
  // We no longer need a MagpieRSS upgrade module. Hallelujah!
98
  require_once(ABSPATH . WPINC . '/feed.php');
 
 
99
 
100
- if (isset($wp_db_version)) :
101
- if ($wp_db_version >= FWP_SCHEMA_23) :
102
- require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
103
- elseif ($wp_db_version >= FWP_SCHEMA_21) : // WordPress 2.1 and 2.2, but not 2.3
104
- require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
105
- require_once (ABSPATH . 'wp-admin/admin-db.php'); // for wp_insert_category
106
- elseif ($wp_db_version >= FWP_SCHEMA_20) : // WordPress 2.0
107
- require_once (ABSPATH . WPINC . '/registration-functions.php'); // for wp_insert_user
108
- require_once (ABSPATH . 'wp-admin/admin-db.php'); // for wp_insert_category
109
- endif;
110
- endif;
111
 
112
- require_once (ABSPATH . WPINC . '/class-feed.php');
113
  require_once(dirname(__FILE__) . '/compatability.php'); // LEGACY API: Replicate or mock up functions for legacy support purposes
114
  require_once(dirname(__FILE__) . '/feedwordpresshtml.class.php');
115
  require_once(dirname(__FILE__) . '/feedwordpress-content-type-sniffer.class.php');
@@ -132,23 +125,10 @@ else : // Something went wrong. Let's just guess.
132
  $fwp_path = 'feedwordpress';
133
  endif;
134
 
135
- function feedwordpress_admin_scripts () {
136
- global $fwp_path;
137
-
138
- wp_enqueue_script('post'); // for magic tag and category boxes
139
- if (!FeedWordPressCompatibility::test_version(FWP_SCHEMA_29)) : // < 2.9
140
- wp_enqueue_script('thickbox'); // for fold-up boxes
141
- endif;
142
- wp_enqueue_script('admin-forms'); // for checkbox selection
143
-
144
- wp_register_script('feedwordpress-elements', WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-elements.js');
145
- wp_enqueue_script('feedwordpress-elements');
146
- }
147
-
148
  // If this is a FeedWordPress admin page, queue up scripts for AJAX functions that FWP uses
149
  // If it is a display page or a non-FeedWordPress admin page, don't.
150
- if (is_admin() and isset($_REQUEST['page']) and preg_match("|^{$fwp_path}/|", $_REQUEST['page'])) :
151
- add_action('admin_print_scripts', 'feedwordpress_admin_scripts');
152
 
153
  wp_register_style('feedwordpress-elements', WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-elements.css');
154
 
@@ -183,7 +163,7 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
183
  add_action('atom_entry', 'feedwordpress_item_feed_data');
184
 
185
  # Filter in original permalinks if the user wants that
186
- add_filter('post_link', 'syndication_permalink', 1);
187
 
188
  # When foreign URLs are used for permalinks in feeds or display
189
  # contexts, they need to be escaped properly.
@@ -243,6 +223,11 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
243
  add_action('feedwordpress_check_feed_complete', 'debug_out_feedwordpress_feed_error', 100, 3);
244
  endif;
245
 
 
 
 
 
 
246
  # Cron-less auto-update. Hooray!
247
  $autoUpdateHook = get_option('feedwordpress_automatic_updates');
248
  if ($autoUpdateHook != 'init') :
@@ -268,6 +253,12 @@ function feedwordpress_auto_update () {
268
  endif;
269
  } /* feedwordpress_auto_update () */
270
 
 
 
 
 
 
 
271
  function feedwordpress_update_magic_url () {
272
  global $wpdb;
273
 
@@ -295,6 +286,7 @@ function feedwordpress_update_magic_url () {
295
  echo "[feedwordpress] $wpdb->num_queries queries. $mysqlTime seconds in MySQL. Total of "; timer_stop(1); print " seconds.";
296
  endif;
297
 
 
298
 
299
  // Magic URL should return nothing but a 200 OK header packet
300
  // when successful.
@@ -381,6 +373,28 @@ function debug_out_feedwordpress_feed_error ($feed, $added, $dt) {
381
  endif;
382
  }
383
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  ################################################################################
385
  ## TEMPLATE API: functions to make your templates syndication-aware ############
386
  ################################################################################
@@ -653,28 +667,41 @@ function feedwordpress_item_feed_data () {
653
  * syndicated, or if FWP is set to use internal permalinks, or if the post
654
  * was syndicated, but didn't have a proper permalink recorded.
655
  *
656
- * @uses FeedWordPress::munge_permalinks()
657
  * @uses get_syndication_permalink()
 
 
 
658
  * @global $feedwordpress_the_original_permalink
659
- */
660
- function syndication_permalink ($permalink = '') {
 
661
  global $feedwordpress_the_original_permalink;
662
 
663
  // Save the local permalink in case we need to retrieve it later.
664
  $feedwordpress_the_original_permalink = $permalink;
665
 
666
- // Map this permalink to a post ID so we can get the correct permalink
667
- // even outside of the Post Loop. Props Björn.
668
- $id = url_to_postid($permalink);
 
 
 
 
 
 
 
 
 
669
 
670
  $munge = false;
671
- $link = get_syndication_feed_object($id);
672
  if (is_object($link)) :
673
  $munge = ($link->setting('munge permalink', 'munge_permalink', 'yes') != 'no');
674
  endif;
675
 
676
  if ($munge):
677
- $uri = get_syndication_permalink($id);
678
  $permalink = ((strlen($uri) > 0) ? $uri : $permalink);
679
  endif;
680
  return $permalink;
@@ -692,6 +719,7 @@ function syndication_permalink ($permalink = '') {
692
  *
693
  */
694
  function syndication_permalink_escaped ($permalink) {
 
695
  if (is_syndicated() and FeedWordPress::munge_permalinks()) :
696
  // This is a foreign link; WordPress can't vouch for its not
697
  // having any entities that need to be &-escaped. So we'll do
@@ -1120,6 +1148,13 @@ class FeedWordPress {
1120
  return $ret;
1121
  } // FeedWordPress::stale()
1122
 
 
 
 
 
 
 
 
1123
  function update_requested () {
1124
  return (
1125
  isset($_REQUEST['update_feedwordpress'])
@@ -1247,13 +1282,12 @@ class FeedWordPress {
1247
  return (get_option('feedwordpress_munge_permalink', /*default=*/ 'yes') != 'no');
1248
  } /* FeedWordPress::munge_permalinks() */
1249
 
1250
- function syndicated_links () {
1251
  $contributors = FeedWordPress::link_category_id();
1252
- if (function_exists('get_bookmarks')) :
1253
- $links = get_bookmarks(array("category" => $contributors));
1254
- else:
1255
- $links = get_linkobjects($contributors); // deprecated as of WP 2.1
1256
- endif;
1257
  return $links;
1258
  } // function FeedWordPress::syndicated_links()
1259
 
@@ -1379,12 +1413,14 @@ class FeedWordPress {
1379
  ");
1380
  }
1381
 
1382
- /*static*/ function fetch ($url) {
1383
  $feed = new SimplePie();
1384
  $feed->set_feed_url($url);
1385
  $feed->set_cache_class('WP_Feed_Cache');
1386
  $feed->set_file_class('WP_SimplePie_File');
1387
  $feed->set_content_type_sniffer_class('FeedWordPress_Content_Type_Sniffer');
 
 
1388
  $feed->set_cache_duration(FeedWordPress::cache_duration());
1389
  $feed->init();
1390
  $feed->handle_content_type();
@@ -1400,6 +1436,12 @@ class FeedWordPress {
1400
  function clear_cache () {
1401
  global $wpdb;
1402
 
 
 
 
 
 
 
1403
  // The WordPress SimplePie module stores its cached feeds as
1404
  // transient records in the options table. The data itself is
1405
  // stored in `_transient_feed_{md5 of url}` and the last-modified
@@ -1407,11 +1449,13 @@ class FeedWordPress {
1407
  // these records are stored in `_transient_timeout_feed_{md5}`.
1408
  // Since the md5 is always 32 characters in length, the
1409
  // option_name is always over 32 characters.
1410
- $ret = $wpdb->query("
1411
  DELETE FROM {$wpdb->options}
1412
  WHERE option_name LIKE '_transient%_feed_%' AND LENGTH(option_name) > 32
1413
  ");
1414
- return (int) ($ret / 4); // Each transient has 4 rows: the data, the modified timestamp; and the timeouts for each
 
 
1415
  } /* FeedWordPress::clear_cache () */
1416
 
1417
  function cache_duration () {
@@ -1446,7 +1490,6 @@ class FeedWordPress {
1446
  return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $affirmo));
1447
  }
1448
 
1449
-
1450
  # Internal debugging functions
1451
  function critical_bug ($varname, $var, $line) {
1452
  global $wp_version;
@@ -1477,17 +1520,21 @@ class FeedWordPress {
1477
  $out = preg_replace('/\s+/', " ", $out);
1478
  endif;
1479
  return $out;
1480
- } /* FeedWordPress:val () */
 
 
 
 
 
1481
 
1482
  function diagnostic ($level, $out) {
1483
  global $feedwordpress_admin_footer;
1484
 
1485
  $output = get_option('feedwordpress_diagnostics_output', array());
1486
- $show = get_option('feedwordpress_diagnostics_show', array());
1487
 
1488
  $diagnostic_nesting = count(explode(":", $level));
1489
 
1490
- if (in_array($level, $show)) :
1491
  foreach ($output as $method) :
1492
  switch ($method) :
1493
  case 'echo' :
@@ -1512,6 +1559,18 @@ class FeedWordPress {
1512
  } /* FeedWordPress::admin_footer () */
1513
  } // class FeedWordPress
1514
 
 
 
 
 
 
 
 
 
 
 
 
 
1515
  $feedwordpress_admin_footer = array();
1516
 
1517
  require_once(dirname(__FILE__) . '/syndicatedpost.class.php');
@@ -1540,8 +1599,6 @@ function feedwordpress_pong ($args) {
1540
  endif;
1541
  }
1542
 
1543
- require_once(dirname(__FILE__) . '/relative_uri.class.php');
1544
-
1545
  // take your best guess at the realname and e-mail, given a string
1546
  define('FWP_REGEX_EMAIL_ADDY', '([^@"(<\s]+@[^"@(<\s]+\.[^"@(<\s]+)');
1547
  define('FWP_REGEX_EMAIL_NAME', '("([^"]*)"|([^"<(]+\S))');
3
  Plugin Name: FeedWordPress
4
  Plugin URI: http://feedwordpress.radgeek.com/
5
  Description: simple and flexible Atom/RSS syndication for WordPress
6
+ Version: 2010.0623
7
  Author: Charles Johnson
8
  Author URI: http://radgeek.com/
9
  License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
+ * @version 2010.0623
15
  */
16
 
17
  # This uses code derived from:
18
  # - wp-rss-aggregate.php by Kellan Elliot-McCrea <kellan@protest.net>
19
+ # - MagpieRSS by Kellan Elliot-McCrea <kellan@protest.net>
20
  # - Ultra-Liberal Feed Finder by Mark Pilgrim <mark@diveintomark.org>
21
+ # - WordPress Blog Tool and Publishing Platform <http://wordpress.org/>
22
  # according to the terms of the GNU General Public License.
23
  #
24
  # INSTALLATION: see readme.txt or <http://projects.radgeek.com/install>
34
 
35
  # -- Don't change these unless you know what you're doing...
36
 
37
+ define ('FEEDWORDPRESS_VERSION', '2010.0623');
38
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
39
 
40
  // Defaults
97
  // Ensure that we have SimplePie loaded up and ready to go.
98
  // We no longer need a MagpieRSS upgrade module. Hallelujah!
99
  require_once(ABSPATH . WPINC . '/feed.php');
100
+ require_once(ABSPATH . WPINC . '/class-feed.php');
101
+ require_once(ABSPATH . WPINC . '/class-simplepie.php');
102
 
103
+ require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
 
 
 
 
 
 
 
 
 
 
104
 
105
+ require_once(dirname(__FILE__) . '/admin-ui.php');
106
  require_once(dirname(__FILE__) . '/compatability.php'); // LEGACY API: Replicate or mock up functions for legacy support purposes
107
  require_once(dirname(__FILE__) . '/feedwordpresshtml.class.php');
108
  require_once(dirname(__FILE__) . '/feedwordpress-content-type-sniffer.class.php');
125
  $fwp_path = 'feedwordpress';
126
  endif;
127
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  // If this is a FeedWordPress admin page, queue up scripts for AJAX functions that FWP uses
129
  // If it is a display page or a non-FeedWordPress admin page, don't.
130
+ if (FeedWordPressSettingsUI::is_admin()) :
131
+ add_action('admin_print_scripts', array('FeedWordPressSettingsUI', 'admin_scripts'));
132
 
133
  wp_register_style('feedwordpress-elements', WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-elements.css');
134
 
163
  add_action('atom_entry', 'feedwordpress_item_feed_data');
164
 
165
  # Filter in original permalinks if the user wants that
166
+ add_filter('post_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 3);
167
 
168
  # When foreign URLs are used for permalinks in feeds or display
169
  # contexts, they need to be escaped properly.
223
  add_action('feedwordpress_check_feed_complete', 'debug_out_feedwordpress_feed_error', 100, 3);
224
  endif;
225
 
226
+ add_action('wp_footer', 'debug_out_feedwordpress_footer', -100);
227
+ add_action('admin_footer', 'debug_out_feedwordpress_footer', -100);
228
+
229
+ add_action('init', 'feedwordpress_clear_cache_magic_url');
230
+
231
  # Cron-less auto-update. Hooray!
232
  $autoUpdateHook = get_option('feedwordpress_automatic_updates');
233
  if ($autoUpdateHook != 'init') :
253
  endif;
254
  } /* feedwordpress_auto_update () */
255
 
256
+ function feedwordpress_clear_cache_magic_url () {
257
+ if (FeedWordPress::clear_cache_requested()) :
258
+ FeedWordPress::clear_cache();
259
+ endif;
260
+ }
261
+
262
  function feedwordpress_update_magic_url () {
263
  global $wpdb;
264
 
286
  echo "[feedwordpress] $wpdb->num_queries queries. $mysqlTime seconds in MySQL. Total of "; timer_stop(1); print " seconds.";
287
  endif;
288
 
289
+ debug_out_feedwordpress_footer();
290
 
291
  // Magic URL should return nothing but a 200 OK header packet
292
  // when successful.
373
  endif;
374
  }
375
 
376
+ function debug_out_human_readable_bytes ($quantity) {
377
+ $quantity = (int) $quantity;
378
+ $magnitude = 'B';
379
+ $orders = array('KB', 'MB', 'GB', 'TB');
380
+ while (($quantity > 1024) and (count($orders) > 0)) :
381
+ $quantity = floor($quantity / 1024);
382
+ $magnitude = array_shift($orders);
383
+ endwhile;
384
+ return "${quantity} ${magnitude}";
385
+ }
386
+
387
+ function debug_out_feedwordpress_footer () {
388
+ if (FeedWordPress::diagnostic_on('memory_usage')) :
389
+ if (function_exists('memory_get_usage')) :
390
+ FeedWordPress::diagnostic ('memory_usage', "Memory: Current usage: ".debug_out_human_readable_bytes(memory_get_usage()));
391
+ endif;
392
+ if (function_exists('memory_get_peak_usage')) :
393
+ FeedWordPress::diagnostic ('memory_usage', "Memory: Peak usage: ".debug_out_human_readable_bytes(memory_get_peak_usage()));
394
+ endif;
395
+ endif;
396
+ } /* debug_out_feedwordpress_footer() */
397
+
398
  ################################################################################
399
  ## TEMPLATE API: functions to make your templates syndication-aware ############
400
  ################################################################################
667
  * syndicated, or if FWP is set to use internal permalinks, or if the post
668
  * was syndicated, but didn't have a proper permalink recorded.
669
  *
670
+ * @uses SyndicatedLink::setting()
671
  * @uses get_syndication_permalink()
672
+ * @uses get_syndication_feed_object()
673
+ * @uses url_to_postid()
674
+ * @global $id
675
  * @global $feedwordpress_the_original_permalink
676
+ */
677
+ function syndication_permalink ($permalink = '', $post = null, $leavename = false) {
678
+ global $id;
679
  global $feedwordpress_the_original_permalink;
680
 
681
  // Save the local permalink in case we need to retrieve it later.
682
  $feedwordpress_the_original_permalink = $permalink;
683
 
684
+ if (is_object($post) and isset($post->ID) and !empty($post->ID)) :
685
+ // Use the post ID we've been provided with.
686
+ $postId = $post->ID;
687
+ elseif (is_string($permalink) and strlen($permalink) > 0) :
688
+ // Map this permalink to a post ID so we can get the correct
689
+ // permalink even outside of the Post Loop. Props Björn.
690
+ $postId = url_to_postid($permalink);
691
+ else :
692
+ // If the permalink string is empty but Post Loop context
693
+ // provides an id.
694
+ $postId = $id;
695
+ endif;
696
 
697
  $munge = false;
698
+ $link = get_syndication_feed_object($postId);
699
  if (is_object($link)) :
700
  $munge = ($link->setting('munge permalink', 'munge_permalink', 'yes') != 'no');
701
  endif;
702
 
703
  if ($munge):
704
+ $uri = get_syndication_permalink($postId);
705
  $permalink = ((strlen($uri) > 0) ? $uri : $permalink);
706
  endif;
707
  return $permalink;
719
  *
720
  */
721
  function syndication_permalink_escaped ($permalink) {
722
+ /* FIXME: This should review link settings not just global settings */
723
  if (is_syndicated() and FeedWordPress::munge_permalinks()) :
724
  // This is a foreign link; WordPress can't vouch for its not
725
  // having any entities that need to be &-escaped. So we'll do
1148
  return $ret;
1149
  } // FeedWordPress::stale()
1150
 
1151
+ function clear_cache_requested () {
1152
+ return (
1153
+ isset($_GET['clear_cache'])
1154
+ and $_GET['clear_cache']
1155
+ );
1156
+ } /* FeedWordPress::clear_cache_requested() */
1157
+
1158
  function update_requested () {
1159
  return (
1160
  isset($_REQUEST['update_feedwordpress'])
1282
  return (get_option('feedwordpress_munge_permalink', /*default=*/ 'yes') != 'no');
1283
  } /* FeedWordPress::munge_permalinks() */
1284
 
1285
+ function syndicated_links ($args = array()) {
1286
  $contributors = FeedWordPress::link_category_id();
1287
+ $links = get_bookmarks(array_merge(
1288
+ array("category" => $contributors),
1289
+ $args
1290
+ ));
 
1291
  return $links;
1292
  } // function FeedWordPress::syndicated_links()
1293
 
1413
  ");
1414
  }
1415
 
1416
+ /*static*/ function fetch ($url, $force_feed = true) {
1417
  $feed = new SimplePie();
1418
  $feed->set_feed_url($url);
1419
  $feed->set_cache_class('WP_Feed_Cache');
1420
  $feed->set_file_class('WP_SimplePie_File');
1421
  $feed->set_content_type_sniffer_class('FeedWordPress_Content_Type_Sniffer');
1422
+ $feed->set_file_class('FeedWordPress_File');
1423
+ $feed->force_feed($force_feed);
1424
  $feed->set_cache_duration(FeedWordPress::cache_duration());
1425
  $feed->init();
1426
  $feed->handle_content_type();
1436
  function clear_cache () {
1437
  global $wpdb;
1438
 
1439
+ // Just in case, clear out any old MagpieRSS cache records.
1440
+ $magpies = $wpdb->query("
1441
+ DELETE FROM {$wpdb->options}
1442
+ WHERE option_name LIKE 'rss_%' AND LENGTH(option_name) > 32
1443
+ ");
1444
+
1445
  // The WordPress SimplePie module stores its cached feeds as
1446
  // transient records in the options table. The data itself is
1447
  // stored in `_transient_feed_{md5 of url}` and the last-modified
1449
  // these records are stored in `_transient_timeout_feed_{md5}`.
1450
  // Since the md5 is always 32 characters in length, the
1451
  // option_name is always over 32 characters.
1452
+ $simplepies = $wpdb->query("
1453
  DELETE FROM {$wpdb->options}
1454
  WHERE option_name LIKE '_transient%_feed_%' AND LENGTH(option_name) > 32
1455
  ");
1456
+ $simplepies = (int) ($simplepies / 4); // Each transient has 4 rows: the data, the modified timestamp; and the timeouts for each
1457
+
1458
+ return ($magpies + $simplepies);
1459
  } /* FeedWordPress::clear_cache () */
1460
 
1461
  function cache_duration () {
1490
  return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $affirmo));
1491
  }
1492
 
 
1493
  # Internal debugging functions
1494
  function critical_bug ($varname, $var, $line) {
1495
  global $wp_version;
1520
  $out = preg_replace('/\s+/', " ", $out);
1521
  endif;
1522
  return $out;
1523
+ } /* FeedWordPress::val () */
1524
+
1525
+ function diagnostic_on ($level) {
1526
+ $show = get_option('feedwordpress_diagnostics_show', array());
1527
+ return (in_array($level, $show));
1528
+ } /* FeedWordPress::diagnostic_on () */
1529
 
1530
  function diagnostic ($level, $out) {
1531
  global $feedwordpress_admin_footer;
1532
 
1533
  $output = get_option('feedwordpress_diagnostics_output', array());
 
1534
 
1535
  $diagnostic_nesting = count(explode(":", $level));
1536
 
1537
+ if (FeedWordPress::diagnostic_on($level)) :
1538
  foreach ($output as $method) :
1539
  switch ($method) :
1540
  case 'echo' :
1559
  } /* FeedWordPress::admin_footer () */
1560
  } // class FeedWordPress
1561
 
1562
+ class FeedWordPress_File extends WP_SimplePie_File {
1563
+ function FeedWordPress_File ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
1564
+ WP_SimplePie_File::WP_SimplePie_File($url, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
1565
+
1566
+ // SimplePie makes a strongly typed check against integers with
1567
+ // this, but WordPress puts a string in. Which causes caching
1568
+ // to break and fall on its ass when SimplePie is getting a 304,
1569
+ // but doesn't realize it because this member is "304" instead.
1570
+ $this->status_code = (int) $this->status_code;
1571
+ }
1572
+ } /* class FeedWordPress_File () */
1573
+
1574
  $feedwordpress_admin_footer = array();
1575
 
1576
  require_once(dirname(__FILE__) . '/syndicatedpost.class.php');
1599
  endif;
1600
  }
1601
 
 
 
1602
  // take your best guess at the realname and e-mail, given a string
1603
  define('FWP_REGEX_EMAIL_ADDY', '([^@"(<\s]+@[^"@(<\s]+\.[^"@(<\s]+)');
1604
  define('FWP_REGEX_EMAIL_NAME', '("([^"]*)"|([^"<(]+\S))');
magpiefromsimplepie.class.php CHANGED
@@ -6,7 +6,7 @@ require_once(dirname(__FILE__).'/feedtime.class.php');
6
  * from breaking.
7
  *
8
  * @since 2010.0203
9
- *
10
  */
11
 
12
  class MagpieFromSimplePie {
@@ -76,6 +76,7 @@ class MagpieFromSimplePie {
76
  // In case anyone goes poking around our private members (uh...)
77
  $this->feed_type = ($this->is_atom() ? 'Atom' : 'RSS');
78
  $this->feed_version = $this->feed_version();
 
79
  } /* MagpieFromSimplePie constructor */
80
 
81
  /**
6
  * from breaking.
7
  *
8
  * @since 2010.0203
9
+ * @version 2010.0612
10
  */
11
 
12
  class MagpieFromSimplePie {
76
  // In case anyone goes poking around our private members (uh...)
77
  $this->feed_type = ($this->is_atom() ? 'Atom' : 'RSS');
78
  $this->feed_version = $this->feed_version();
79
+ $this->encoding = $pie->get_encoding();
80
  } /* MagpieFromSimplePie constructor */
81
 
82
  /**
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://feedwordpress.radgeek.com/
4
  Tags: syndication, aggregation, feed, atom, rss
5
  Requires at least: 2.8
6
  Tested up to: 3.0
7
- Stable tag: 2010.0602
8
 
9
  FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
10
 
@@ -93,6 +93,63 @@ outs, see the documentation at the [FeedWordPress project homepage][].
93
 
94
  == Changelog ==
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  = 2010.0602 =
97
 
98
  * CATEGORY BOX INTERFACE ELEMENT FIXED FOR WP 3.0: Stylesheet changes
@@ -256,7 +313,7 @@ outs, see the documentation at the [FeedWordPress project homepage][].
256
  original source, or the local comment feed, when providing the comment
257
  feed URL for a syndicated post.
258
 
259
- #### PARSING ####
260
 
261
  * BETTER DATE HANDLING -- FEWER FLASHBACKS TO 1969 and 1970: FeedWordPress
262
  has made some bugfixes and some improvements in the logic for parsing
@@ -1357,9 +1414,9 @@ The FeedWordPress plugin is copyright © 2005-2010 by Charles Johnson. It uses
1357
  code derived or translated from:
1358
 
1359
  - [wp-rss-aggregate.php][] by [Kellan Elliot-McCrea](kellan@protest.net)
1360
- - [MagpieRSS][] by [Kellan Elliot-McCrea](kellan@protest.net)
1361
- - [HTTP Navigator 2][] by [Keyvan Minoukadeh](keyvan@k1m.com)
1362
  - [Ultra-Liberal Feed Finder][] by [Mark Pilgrim](mark@diveintomark.org)
 
1363
 
1364
  according to the terms of the [GNU General Public License][].
1365
 
4
  Tags: syndication, aggregation, feed, atom, rss
5
  Requires at least: 2.8
6
  Tested up to: 3.0
7
+ Stable tag: 2010.0623
8
 
9
  FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
10
 
93
 
94
  == Changelog ==
95
 
96
+ = 2010.0623 =
97
+
98
+ * WORDPRESS 3.0 COMPATIBILITY / AUTHOR MAPPING INTERFACE ISSUES: I
99
+ resolved a couple of outstanding issues with the author mapping
100
+ interface (Syndication --> Authors), which were preventing new users
101
+ from being created correctly and author mapping rules from being set up
102
+ correctly. These partly had to do with new restrictions on user account
103
+ creation introduced in WordPress 3.0; anyway, they should now be fixed.
104
+
105
+ * MORE EFFICIENT SYNDICATED URL LOOKUPS: Several users noticed that the
106
+ bug fix introduced in 2010.0528 for compatibility with post-listing
107
+ plugins caused a lot more queries to the database in order to look up
108
+ numerical post IDs from the URL provided to the filter. This shouldn't
109
+ cause any major problems, but it is not as efficient as it could be; the
110
+ code now takes advantage of a more efficient way of doing things,
111
+ which usually will not require any additional database queries.
112
+
113
+ * SIMPLEPIE FEED UPDATE ISSUES: If you have been having significant
114
+ problems with getting feeds to update correctly, this may be the result
115
+ of some bugs in the implementation of SimplePie caching that ships with
116
+ WordPress (as of version 3.0). (You would most commonly experience this
117
+ error if you continually saw errors such as "No feed found at <...>" in
118
+ your updates.) Fortunately, SimplePie allows for a great deal of
119
+ extensibility and this allows me to work around the problem; these
120
+ error conditions should now be mostly eliminated when the underlying
121
+ feed is valid.
122
+
123
+ * UI: SHOW INACTIVE SOURCES: When you use the default unsubscribe option
124
+ -- which turns off the subscription to a feed while preserving the posts
125
+ from it and the syndication-related meta-data for the feed -- the
126
+ unsubscribed feed can now easily be viewed in a special "Inactive"
127
+ section of the Syndicated Sources page. (As a side benefit, if you've
128
+ accidentally, or only temporarily, turned off the subscription to a
129
+ feed, it is now much easier to restore the feed to being active, or to
130
+ delete it permanently, if you prefer.
131
+
132
+ * UI: FEED FINDER / SWITCH FEED INTERFACE IMPROVEMENTS: changes to styling
133
+ and options for the feed finder / switch feed, which should now make it
134
+ easier, in some cases, to find alternative feeds, and make interface
135
+ options more clearly visible.
136
+
137
+ * FILTERS: `syndicated_item_published` and `syndicated_item_updated` NOW
138
+ PROPERLY AFFECT THE DATING OF POSTS. These filters used to affect some
139
+ date-related settings, but not others -- and, most importantly, not the
140
+ final date that is set for a post's publication or last-modified date
141
+ in the WordPress database. Now, they do affect that, as they should.
142
+ (Filters should receive, and return, a long integer, representing a Unix
143
+ epoch relative timestamp.)
144
+
145
+ * MAGIC URL TO CLEAR THE CACHE: Suppose that you need to clear the feed
146
+ cache, for whatever reason; suppose, even, that you need to clear it on
147
+ a regular basis. One way you might do this is by logging into the
148
+ FeedWordPress administrative interface and going to Syndication -->
149
+ Performance. Another way you might do it, now, is to simply send an
150
+ HTTP request to a magic URL provided by FeedWordPress: if your blog is
151
+ at example.com, the URL would be <http://example.com/?clear_cache=1>
152
+
153
  = 2010.0602 =
154
 
155
  * CATEGORY BOX INTERFACE ELEMENT FIXED FOR WP 3.0: Stylesheet changes
313
  original source, or the local comment feed, when providing the comment
314
  feed URL for a syndicated post.
315
 
316
+ #### Parsing ####
317
 
318
  * BETTER DATE HANDLING -- FEWER FLASHBACKS TO 1969 and 1970: FeedWordPress
319
  has made some bugfixes and some improvements in the logic for parsing
1414
  code derived or translated from:
1415
 
1416
  - [wp-rss-aggregate.php][] by [Kellan Elliot-McCrea](kellan@protest.net)
1417
+ - [MagpieRSS][] by [Kellan Elliot-McCrea](kellan@protest.net)
 
1418
  - [Ultra-Liberal Feed Finder][] by [Mark Pilgrim](mark@diveintomark.org)
1419
+ - [WordPress Blog Tool and Publishing Platform](http://wordpress.org/)
1420
 
1421
  according to the terms of the [GNU General Public License][].
1422
 
relative_uri.class.php DELETED
@@ -1,174 +0,0 @@
1
- <?php
2
- # Relative URI static class: PHP class for resolving relative URLs
3
- #
4
- # This class is derived (under the terms of the GPL) from URL Class 0.3 by
5
- # Keyvan Minoukadeh <keyvan@k1m.com>, which is great but more than we need
6
- # for FeedWordPress's purposes. The class has been stripped down to a single
7
- # public method: Relative_URI::resolve($url, $base), which resolves the URI in
8
- # $url relative to the URI in $base
9
-
10
- class Relative_URI
11
- {
12
- // Resolve relative URI in $url against the base URI in $base. If $base
13
- // is not supplied, then we use the REQUEST_URI of this script.
14
- //
15
- // I'm hoping this method reflects RFC 2396 Section 5.2
16
- function resolve ($url, $base = NULL)
17
- {
18
- if (is_null($base)):
19
- $base = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
20
- endif;
21
-
22
- $base = Relative_URI::_encode(trim($base));
23
- $uri_parts = Relative_URI::_parse_url($base);
24
-
25
- $url = Relative_URI::_encode(trim($url));
26
- $parts = Relative_URI::_parse_url($url);
27
-
28
- $uri_parts['fragment'] = (isset($parts['fragment']) ? $parts['fragment'] : null);
29
- $uri_parts['query'] = (isset($parts['query']) ? $parts['query'] : null);
30
-
31
- // if path is empty, and scheme, host, and query are undefined,
32
- // the URL is referring the base URL
33
-
34
- if (($parts['path'] == '') && !isset($parts['scheme']) && !isset($parts['host']) && !isset($parts['query'])) {
35
- // If the URI is empty or only a fragment, return the base URI
36
- return $base . (isset($parts['fragment']) ? '#'.$parts['fragment'] : '');
37
- } elseif (isset($parts['scheme'])) {
38
- // If the scheme is set, then the URI is absolute.
39
- return $url;
40
- } elseif (isset($parts['host'])) {
41
- $uri_parts['host'] = $parts['host'];
42
- $uri_parts['path'] = $parts['path'];
43
- } else {
44
- // We have a relative path but not a host.
45
-
46
- // start ugly fix:
47
- // prepend slash to path if base host is set, base path is not set, and url path is not absolute
48
- if ($uri_parts['host'] && ($uri_parts['path'] == '')
49
- && (strlen($parts['path']) > 0)
50
- && (substr($parts['path'], 0, 1) != '/')) {
51
- $parts['path'] = '/'.$parts['path'];
52
- } // end ugly fix
53
-
54
- if (substr($parts['path'], 0, 1) == '/') {
55
- $uri_parts['path'] = $parts['path'];
56
- } else {
57
- // copy base path excluding any characters after the last (right-most) slash character
58
- $buffer = substr($uri_parts['path'], 0, (int)strrpos($uri_parts['path'], '/')+1);
59
- // append relative path
60
- $buffer .= $parts['path'];
61
- // remove "./" where "." is a complete path segment.
62
- $buffer = str_replace('/./', '/', $buffer);
63
- if (substr($buffer, 0, 2) == './') {
64
- $buffer = substr($buffer, 2);
65
- }
66
- // if buffer ends with "." as a complete path segment, remove it
67
- if (substr($buffer, -2) == '/.') {
68
- $buffer = substr($buffer, 0, -1);
69
- }
70
- // remove "<segment>/../" where <segment> is a complete path segment not equal to ".."
71
- $search_finished = false;
72
- $segment = explode('/', $buffer);
73
- while (!$search_finished) {
74
- for ($x=0; $x+1 < count($segment);) {
75
- if (($segment[$x] != '') && ($segment[$x] != '..') && ($segment[$x+1] == '..')) {
76
- if ($x+2 == count($segment)) $segment[] = '';
77
- unset($segment[$x], $segment[$x+1]);
78
- $segment = array_values($segment);
79
- continue 2;
80
- } else {
81
- $x++;
82
- }
83
- }
84
- $search_finished = true;
85
- }
86
- $buffer = (count($segment) == 1) ? '/' : implode('/', $segment);
87
- $uri_parts['path'] = $buffer;
88
-
89
- }
90
- }
91
-
92
- // If we've gotten to this point, we can try to put the pieces
93
- // back together.
94
- $ret = '';
95
- if (isset($uri_parts['scheme'])) $ret .= $uri_parts['scheme'].':';
96
- if (isset($uri_parts['user'])) {
97
- $ret .= $uri_parts['user'];
98
- if (isset($uri_parts['pass'])) $ret .= ':'.$uri_parts['parts'];
99
- $ret .= '@';
100
- }
101
- if (isset($uri_parts['host'])) {
102
- $ret .= '//'.$uri_parts['host'];
103
- if (isset($uri_parts['port'])) $ret .= ':'.$uri_parts['port'];
104
- }
105
- $ret .= $uri_parts['path'];
106
- if (isset($uri_parts['query'])) $ret .= '?'.$uri_parts['query'];
107
- if (isset($uri_parts['fragment'])) $ret .= '#'.$uri_parts['fragment'];
108
-
109
- return $ret;
110
- }
111
-
112
- /**
113
- * Parse URL
114
- *
115
- * Regular expression grabbed from RFC 2396 Appendix B.
116
- * This is a replacement for PHPs builtin parse_url().
117
- * @param string $url
118
- * @access private
119
- * @return array
120
- */
121
- function _parse_url($url)
122
- {
123
- // I'm using this pattern instead of parse_url() as there's a few strings where parse_url()
124
- // generates a warning.
125
- if (preg_match('!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!', $url, $match)) {
126
- $parts = array();
127
- if ($match[1] != '') $parts['scheme'] = $match[2];
128
- if ($match[3] != '') $parts['auth'] = $match[4];
129
- // parse auth
130
- if (isset($parts['auth'])) {
131
- // store user info
132
- if (($at_pos = strpos($parts['auth'], '@')) !== false) {
133
- $userinfo = explode(':', substr($parts['auth'], 0, $at_pos), 2);
134
- $parts['user'] = $userinfo[0];
135
- if (isset($userinfo[1])) $parts['pass'] = $userinfo[1];
136
- $parts['auth'] = substr($parts['auth'], $at_pos+1);
137
- }
138
- // get port number
139
- if ($port_pos = strrpos($parts['auth'], ':')) {
140
- $parts['host'] = substr($parts['auth'], 0, $port_pos);
141
- $parts['port'] = (int)substr($parts['auth'], $port_pos+1);
142
- if ($parts['port'] < 1) $parts['port'] = null;
143
- } else {
144
- $parts['host'] = $parts['auth'];
145
- }
146
- }
147
- unset($parts['auth']);
148
- $parts['path'] = $match[5];
149
- if (isset($match[6]) && ($match[6] != '')) $parts['query'] = $match[7];
150
- if (isset($match[8]) && ($match[8] != '')) $parts['fragment'] = $match[9];
151
- return $parts;
152
- }
153
- // shouldn't reach here
154
- return array('path'=>'');
155
- }
156
-
157
- function _encode($string)
158
- {
159
- static $replace = array();
160
- if (!count($replace)) {
161
- $find = array(32, 34, 60, 62, 123, 124, 125, 91, 92, 93, 94, 96, 127);
162
- $find = array_merge(range(0, 31), $find);
163
- $find = array_map('chr', $find);
164
- foreach ($find as $char) {
165
- $replace[$char] = '%'.bin2hex($char);
166
- }
167
- }
168
- // escape control characters and a few other characters
169
- $encoded = strtr($string, $replace);
170
- // remove any character outside the hex range: 21 - 7E (see www.asciitable.com)
171
- return preg_replace('/[^\x21-\x7e]/', '', $encoded);
172
- }
173
- } // class Relative_URI
174
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
syndicatedlink.class.php CHANGED
@@ -177,7 +177,40 @@ class SyndicatedLink {
177
 
178
  if (is_wp_error($this->simplepie)) :
179
  $new_count = $this->simplepie;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  elseif (is_object($this->simplepie)) :
 
 
 
 
 
181
  $new_count = array('new' => 0, 'updated' => 0);
182
 
183
  # -- Update Link metadata live from feed
@@ -211,18 +244,7 @@ class SyndicatedLink {
211
  $this->settings['update/ttl'] = $ttl;
212
  $this->settings['update/timed'] = 'feed';
213
  else :
214
- // spread out over a time interval for staggered updates
215
- $updateWindow = $this->setting(
216
- 'update/window',
217
- 'update_window',
218
- DEFAULT_UPDATE_PERIOD
219
- );
220
- if (!is_numeric($updateWindow) or ($updateWindow < 1)) :
221
- $updateWindow = DEFAULT_UPDATE_PERIOD;
222
- endif;
223
-
224
- $fudgedInterval = $updateWindow+rand(0, 2*($updateWindow/3));
225
- $this->settings['update/ttl'] = apply_filters('syndicated_feed_automatic_ttl', $fudgedInterval, $this);
226
  $this->settings['update/timed'] = 'automatically';
227
  endif;
228
  $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->settings['update/ttl'], $this);
@@ -332,18 +354,7 @@ class SyndicatedLink {
332
  global $wpdb;
333
 
334
  if (strlen($newuser_name) > 0) :
335
- $userdata = array();
336
- $userdata['ID'] = NULL;
337
-
338
- $userdata['user_login'] = sanitize_user($newuser_name);
339
- $userdata['user_login'] = apply_filters('pre_user_login', $userdata['user_login']);
340
-
341
- $userdata['user_nicename'] = sanitize_title($newuser_name);
342
- $userdata['user_nicename'] = apply_filters('pre_user_nicename', $userdata['user_nicename']);
343
-
344
- $userdata['display_name'] = $wpdb->escape($newuser_name);
345
-
346
- $newuser_id = wp_insert_user($userdata);
347
  if (is_numeric($newuser_id)) :
348
  if (is_null($name)) : // Unfamiliar author
349
  $this->settings['unfamiliar author'] = $newuser_id;
@@ -464,22 +475,27 @@ class SyndicatedLink {
464
  return (is_object($this->link) ? $this->link->link_rss : NULL);
465
  } /* SyndicatedLink::uri () */
466
 
467
- function homepage ($fromFeed = true) {
 
468
  if ($fromFeed) :
469
- $url = (isset($this->settings['feed/link']) ? $this->settings['feed/link'] : NULL);
 
 
 
 
 
470
  else :
471
- $url = $this->link->link_url;
472
  endif;
473
- return $url;
 
 
 
 
474
  } /* SyndicatedLink::homepage () */
475
 
476
  function name ($fromFeed = true) {
477
- if ($fromFeed) :
478
- $name = (isset($this->settings['feed/title']) ? $this->settings['feed/title'] : NULL);
479
- else :
480
- $name = $this->link->link_name;
481
- endif;
482
- return $name;
483
  } /* SyndicatedLink::name () */
484
 
485
  function ttl () {
@@ -528,6 +544,17 @@ class SyndicatedLink {
528
  return $ret;
529
  } /* SyndicatedLink::ttl() */
530
 
 
 
 
 
 
 
 
 
 
 
 
531
  // SyndicatedLink::flatten_array (): flatten an array. Useful for
532
  // hierarchical and namespaced elements.
533
  //
177
 
178
  if (is_wp_error($this->simplepie)) :
179
  $new_count = $this->simplepie;
180
+ // Error; establish an error setting.
181
+ $theError = array();
182
+ $theError['ts'] = time();
183
+ $theError['since'] = time();
184
+ $theError['object'] = $this->simplepie;
185
+
186
+ $oldError = $this->setting('update/error', NULL, NULL);
187
+ if (is_string($oldError)) :
188
+ $oldError = unserialize($oldError);
189
+ endif;
190
+
191
+ if (!is_null($oldError)) :
192
+ // Copy over the in-error-since timestamp
193
+ $theError['since'] = $oldError['since'];
194
+
195
+ // If this is a repeat error, then we should take
196
+ // a step back before we try to fetch it again.
197
+ $this->settings['update/last'] = time();
198
+ $this->settings['update/ttl'] = $this->automatic_ttl();
199
+ $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->settings['update/ttl'], $this);
200
+ $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl_from_error', $this->settings['update/ttl'], $this);
201
+
202
+ $this->settings['update/timed'] = 'automatically';
203
+ endif;
204
+
205
+ $this->settings['update/error'] = serialize($theError);
206
+ $this->save_settings(/*reload=*/ true);
207
+
208
  elseif (is_object($this->simplepie)) :
209
+ // Success; clear out error setting, if any.
210
+ if (isset($this->settings['update/error'])) :
211
+ unset($this->settings['update/error']);
212
+ endif;
213
+
214
  $new_count = array('new' => 0, 'updated' => 0);
215
 
216
  # -- Update Link metadata live from feed
244
  $this->settings['update/ttl'] = $ttl;
245
  $this->settings['update/timed'] = 'feed';
246
  else :
247
+ $this->settings['update/ttl'] = $this->automatic_ttl();
 
 
 
 
 
 
 
 
 
 
 
248
  $this->settings['update/timed'] = 'automatically';
249
  endif;
250
  $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->settings['update/ttl'], $this);
354
  global $wpdb;
355
 
356
  if (strlen($newuser_name) > 0) :
357
+ $newuser_id = fwp_insert_new_user($newuser_name);
 
 
 
 
 
 
 
 
 
 
 
358
  if (is_numeric($newuser_id)) :
359
  if (is_null($name)) : // Unfamiliar author
360
  $this->settings['unfamiliar author'] = $newuser_id;
475
  return (is_object($this->link) ? $this->link->link_rss : NULL);
476
  } /* SyndicatedLink::uri () */
477
 
478
+ function property_cascade ($fromFeed, $link_field, $setting, $simplepie_method) {
479
+ $value = NULL;
480
  if ($fromFeed) :
481
+ if (isset($this->settings[$setting])) :
482
+ $value = $this->settings[$setting];
483
+ elseif (is_object($this->simplepie)
484
+ and method_exists($this->simplepie, $simplepie_method)) :
485
+ $value = $this->simplepie->{$simplepie_method}();
486
+ endif;
487
  else :
488
+ $value = $this->link->{$link_field};
489
  endif;
490
+ return $value;
491
+ } /* SyndicatedLink::property_cascade () */
492
+
493
+ function homepage ($fromFeed = true) {
494
+ return $this->property_cascade($fromFeed, 'link_url', 'feed/link', 'get_link');
495
  } /* SyndicatedLink::homepage () */
496
 
497
  function name ($fromFeed = true) {
498
+ return $this->property_cascade($fromFeed, 'link_name', 'feed/title', 'get_title');
 
 
 
 
 
499
  } /* SyndicatedLink::name () */
500
 
501
  function ttl () {
544
  return $ret;
545
  } /* SyndicatedLink::ttl() */
546
 
547
+ function automatic_ttl () {
548
+ // spread out over a time interval for staggered updates
549
+ $updateWindow = $this->setting('update/window', 'update_window', DEFAULT_UPDATE_PERIOD);
550
+ if (!is_numeric($updateWindow) or ($updateWindow < 1)) :
551
+ $updateWindow = DEFAULT_UPDATE_PERIOD;
552
+ endif;
553
+
554
+ $fudgedInterval = $updateWindow+rand(0, 2*($updateWindow/3));
555
+ return apply_filters('syndicated_feed_automatic_ttl', $fudgedInterval, $this);
556
+ } /* SyndicatedLink::automatic_ttl () */
557
+
558
  // SyndicatedLink::flatten_array (): flatten an array. Useful for
559
  // hierarchical and namespaced elements.
560
  //
syndicatedpost.class.php CHANGED
@@ -893,7 +893,7 @@ class SyndicatedPost {
893
 
894
  function resolve_single_relative_uri ($refs) {
895
  $tag = FeedWordPressHTML::attributeMatch($refs);
896
- $url = Relative_URI::resolve($tag['value'], $this->_base);
897
  return $tag['prefix'] . $url . $tag['suffix'];
898
  } /* function SyndicatedPost::resolve_single_relative_uri() */
899
 
@@ -1481,7 +1481,7 @@ class SyndicatedPost {
1481
  $a = $this->author();
1482
  $author = $a['name'];
1483
  $email = (isset($a['email']) ? $a['email'] : NULL);
1484
- $url = (isset($a['uri']) ? $a['uri'] : NULL);
1485
 
1486
  $match_author_by_email = !('yes' == get_option("feedwordpress_do_not_match_author_by_email"));
1487
  if ($match_author_by_email and !FeedWordPress::is_null_email($email)) :
@@ -1501,7 +1501,7 @@ class SyndicatedPost {
1501
  $author = $wpdb->escape($author);
1502
  $email = $wpdb->escape($email);
1503
  $test_email = $wpdb->escape($test_email);
1504
- $url = $wpdb->escape($url);
1505
 
1506
  // Check for an existing author rule....
1507
  if (isset($this->link->settings['map authors']['name'][strtolower(trim($author))])) :
@@ -1574,7 +1574,7 @@ class SyndicatedPost {
1574
  $userdata['user_nicename'] = $nice_author;
1575
  $userdata['user_pass'] = substr(md5(uniqid(microtime())), 0, 6); // just something random to lock it up
1576
  $userdata['user_email'] = $email;
1577
- $userdata['user_url'] = $url;
1578
  $userdata['display_name'] = $author;
1579
 
1580
  $id = wp_insert_user($userdata);
@@ -1610,7 +1610,7 @@ class SyndicatedPost {
1610
  foreach ($cats as $cat_name) :
1611
  if (preg_match('/^{#([0-9]+)}$/', $cat_name, $backref)) :
1612
  $cat_id = (int) $backref[1];
1613
- if (function_exists('is_term') and is_term($cat_id, 'category')) :
1614
  $cat_ids[] = $cat_id;
1615
  elseif (get_category($cat_id)) :
1616
  $cat_ids[] = $cat_id;
@@ -1619,63 +1619,28 @@ class SyndicatedPost {
1619
  $esc = $wpdb->escape($cat_name);
1620
  $resc = $wpdb->escape(preg_quote($cat_name));
1621
 
1622
- // WordPress 2.3+
1623
- if (function_exists('is_term')) :
1624
- $cat_id = is_term($cat_name, 'category');
1625
- if ($cat_id) :
1626
- $cat_ids[] = $cat_id['term_id'];
1627
- // There must be a better way to do this...
1628
- elseif ($results = $wpdb->get_results(
1629
- "SELECT term_id
1630
- FROM $wpdb->term_taxonomy
1631
- WHERE
1632
- LOWER(description) RLIKE
1633
- CONCAT('(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*', LOWER('{$resc}'), '( |\\t|\\r)*(\\n|\$)')"
1634
- )) :
1635
- foreach ($results AS $term) :
1636
- $cat_ids[] = (int) $term->term_id;
1637
- endforeach;
1638
- elseif ('tag'==$unfamiliar_category) :
1639
- $tags[] = $cat_name;
1640
- elseif ('create'===$unfamiliar_category) :
1641
- $term = wp_insert_term($cat_name, 'category');
1642
- if (is_wp_error($term)) :
1643
- FeedWordPress::noncritical_bug('term insertion problem', array('cat_name' => $cat_name, 'term' => $term, 'this' => $this), __LINE__);
1644
- else :
1645
- $cat_ids[] = $term['term_id'];
1646
- endif;
1647
- endif;
1648
-
1649
- // WordPress 1.5.x - 2.2.x
1650
- else :
1651
- $results = $wpdb->get_results(
1652
- "SELECT cat_ID
1653
- FROM $wpdb->categories
1654
  WHERE
1655
- (LOWER(cat_name) = LOWER('$esc'))
1656
- OR (LOWER(category_description)
1657
- RLIKE CONCAT('(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*', LOWER('{$resc}'), '( |\\t|\\r)*(\\n|\$)'))
1658
- ");
1659
- if ($results) :
1660
- foreach ($results as $term) :
1661
- $cat_ids[] = (int) $term->cat_ID;
1662
- endforeach;
1663
- elseif ('create'===$unfamiliar_category) :
1664
- if (function_exists('wp_insert_category')) :
1665
- $cat_id = wp_insert_category(array('cat_name' => $esc));
1666
- // And into the database we go.
1667
- else :
1668
- $nice_kitty = sanitize_title($cat_name);
1669
- $wpdb->query(sprintf("
1670
- INSERT INTO $wpdb->categories
1671
- SET
1672
- cat_name='%s',
1673
- category_nicename='%s'
1674
- ", $esc, $nice_kitty
1675
- ));
1676
- $cat_id = $wpdb->insert_id;
1677
- endif;
1678
- $cat_ids[] = $cat_id;
1679
  endif;
1680
  endif;
1681
  endif;
893
 
894
  function resolve_single_relative_uri ($refs) {
895
  $tag = FeedWordPressHTML::attributeMatch($refs);
896
+ $url = SimplePie_Misc::absolutize_url($tag['value'], $this->_base);
897
  return $tag['prefix'] . $url . $tag['suffix'];
898
  } /* function SyndicatedPost::resolve_single_relative_uri() */
899
 
1481
  $a = $this->author();
1482
  $author = $a['name'];
1483
  $email = (isset($a['email']) ? $a['email'] : NULL);
1484
+ $authorUrl = (isset($a['uri']) ? $a['uri'] : NULL);
1485
 
1486
  $match_author_by_email = !('yes' == get_option("feedwordpress_do_not_match_author_by_email"));
1487
  if ($match_author_by_email and !FeedWordPress::is_null_email($email)) :
1501
  $author = $wpdb->escape($author);
1502
  $email = $wpdb->escape($email);
1503
  $test_email = $wpdb->escape($test_email);
1504
+ $authorUrl = $wpdb->escape($authorUrl);
1505
 
1506
  // Check for an existing author rule....
1507
  if (isset($this->link->settings['map authors']['name'][strtolower(trim($author))])) :
1574
  $userdata['user_nicename'] = $nice_author;
1575
  $userdata['user_pass'] = substr(md5(uniqid(microtime())), 0, 6); // just something random to lock it up
1576
  $userdata['user_email'] = $email;
1577
+ $userdata['user_url'] = $authorUrl;
1578
  $userdata['display_name'] = $author;
1579
 
1580
  $id = wp_insert_user($userdata);
1610
  foreach ($cats as $cat_name) :
1611
  if (preg_match('/^{#([0-9]+)}$/', $cat_name, $backref)) :
1612
  $cat_id = (int) $backref[1];
1613
+ if (term_exists($cat_id, 'category')) :
1614
  $cat_ids[] = $cat_id;
1615
  elseif (get_category($cat_id)) :
1616
  $cat_ids[] = $cat_id;
1619
  $esc = $wpdb->escape($cat_name);
1620
  $resc = $wpdb->escape(preg_quote($cat_name));
1621
 
1622
+ $cat_id = term_exists($cat_name, 'category');
1623
+ if ($cat_id) :
1624
+ $cat_ids[] = $cat_id['term_id'];
1625
+ // There must be a better way to do this...
1626
+ elseif ($results = $wpdb->get_results(
1627
+ "SELECT term_id
1628
+ FROM $wpdb->term_taxonomy
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1629
  WHERE
1630
+ LOWER(description) RLIKE
1631
+ CONCAT('(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*', LOWER('{$resc}'), '( |\\t|\\r)*(\\n|\$)')"
1632
+ )) :
1633
+ foreach ($results as $term) :
1634
+ $cat_ids[] = (int) $term->term_id;
1635
+ endforeach;
1636
+ elseif ('tag'==$unfamiliar_category) :
1637
+ $tags[] = $cat_name;
1638
+ elseif ('create'===$unfamiliar_category) :
1639
+ $term = wp_insert_term($cat_name, 'category');
1640
+ if (is_wp_error($term)) :
1641
+ FeedWordPress::noncritical_bug('term insertion problem', array('cat_name' => $cat_name, 'term' => $term, 'this' => $this), __LINE__);
1642
+ else :
1643
+ $cat_ids[] = $term['term_id'];
 
 
 
 
 
 
 
 
 
 
1644
  endif;
1645
  endif;
1646
  endif;
syndication.php CHANGED
@@ -7,7 +7,9 @@ require_once(dirname(__FILE__) . '/admin-ui.php');
7
 
8
  define('FWP_UPDATE_CHECKED', 'Update Checked');
9
  define('FWP_UNSUB_CHECKED', 'Unsubscribe');
10
- define('FWP_SYNDICATE_NEW', 'Syndicate ...');
 
 
11
 
12
  class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
13
  function FeedWordPressSyndicationPage () {
@@ -20,6 +22,81 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
20
 
21
  function has_link () { return false; }
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  function display () {
24
  global $wpdb;
25
 
@@ -29,12 +106,20 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
29
  endif;
30
 
31
  ?>
32
- <?php $cont = true;
33
- if (isset($_REQUEST['action'])):
34
- if ($_REQUEST['action'] == 'feedfinder' or $_REQUEST['action']==FWP_SYNDICATE_NEW) : $cont = fwp_feedfinder_page();
35
- elseif ($_REQUEST['action'] == 'switchfeed') : $cont = fwp_switchfeed_page();
36
- elseif ($_REQUEST['action'] == FWP_UNSUB_CHECKED or $_REQUEST['action'] == 'Unsubscribe') : $cont = fwp_multidelete_page();
37
- endif;
 
 
 
 
 
 
 
 
38
  endif;
39
 
40
  if ($cont):
@@ -81,14 +166,29 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
81
  margin-top: 0.5em;
82
  border-top: thin solid #777777;
83
  }
 
 
 
 
 
 
 
 
 
 
 
 
84
  </style>
85
  <?php
86
- $links = FeedWordPress::syndicated_links();
 
 
87
  $this->open_sheet('Syndicated Sites');
88
  ?>
89
  <div id="post-body">
90
  <?php
91
- if ($links) :
 
92
  fwp_add_meta_box(
93
  /*id=*/ 'feedwordpress_update_box',
94
  /*title=*/ __('Update feeds now'),
@@ -156,7 +256,7 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
156
  <p><a href="http://feedwordpress.radgeek.com/">FeedWordPress</a> makes syndication
157
  simple and empowers you to stream content from all over the web into your
158
  WordPress hub. That's got to be worth a few lattes. If you're finding FWP useful,
159
- <a href="http://feedwordpress.radgeek.com/donation/">a modest gift</a>
160
  is the best way to support steady progress on development, enhancements,
161
  support, and documentation.</p>
162
  <div class="donate">
@@ -195,34 +295,14 @@ regular donation</a>) using an existing PayPal account or any major credit card.
195
  } /* FeedWordPressSyndicationPage::interstitial() */
196
  } /* class FeedWordPressSyndicationPage */
197
 
198
- function fwp_dashboard_update_if_requested () {
199
  global $wpdb;
200
 
201
- if (isset($_POST['update']) or isset($_POST['action']) or isset($_POST['update_uri'])) :
202
- $fwp_update_invoke = 'post';
203
- else :
204
- $fwp_update_invoke = 'get';
205
- endif;
206
 
207
- $update_set = array();
208
- if (isset($_POST['link_ids']) and is_array($_POST['link_ids']) and ($_POST['action']==FWP_UPDATE_CHECKED)) :
209
- $targets = $wpdb->get_results("
210
- SELECT * FROM $wpdb->links
211
- WHERE link_id IN (".implode(",",$_POST['link_ids']).")
212
- ");
213
- if (is_array($targets)) :
214
- foreach ($targets as $target) :
215
- $update_set[] = $target->link_rss;
216
- endforeach;
217
- else : // This should never happen
218
- FeedWordPress::critical_bug('fwp_syndication_manage_page::targets', $targets, __LINE__);
219
- endif;
220
- elseif (isset($_POST['update_uri'])) :
221
- $update_set[] = $_POST['update_uri'];
222
- endif;
223
 
224
- shuffle($update_set); // randomize order for load balancing purposes...
225
- if ($fwp_update_invoke != 'get' and count($update_set) > 0) : // Only do things with side-effects for HTTP POST or command line
226
  $feedwordpress = new FeedWordPress;
227
  add_action('feedwordpress_check_feed', 'update_feeds_mention');
228
  add_action('feedwordpress_check_feed_complete', 'update_feeds_finish', 10, 3);
@@ -234,11 +314,7 @@ function fwp_dashboard_update_if_requested () {
234
  $crash_ts = NULL;
235
  endif;
236
 
237
- if (fwp_test_wp_version(FWP_SCHEMA_25)) :
238
- echo "<div class=\"youare\">\n";
239
- else :
240
- echo "<div class=\"updated\">\n";
241
- endif;
242
  echo "<ul>\n";
243
  $tdelta = NULL;
244
  foreach ($update_set as $uri) :
@@ -323,7 +399,7 @@ function fwp_syndication_manage_page_update_box ($object = NULL, $box = NULL) {
323
  <p>Check currently scheduled feeds for new and updated posts.</p>
324
 
325
  <?php
326
- fwp_dashboard_update_if_requested();
327
 
328
  if (!get_option('feedwordpress_automatic_updates')) :
329
  ?>
@@ -335,131 +411,220 @@ function fwp_syndication_manage_page_update_box ($object = NULL, $box = NULL) {
335
  endif;
336
  ?>
337
 
338
- <div class="submit"><input type="hidden" name="update_uri" value="*" /><input class="button-primary" type="submit" name="update" value="Update" /></div>
 
 
 
 
 
 
 
339
 
340
  <br style="clear: both" />
341
  </form>
342
  <?php
343
  } /* function fwp_syndication_manage_page_update_box () */
344
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  function fwp_syndication_manage_page_links_box ($object = NULL, $box = NULL) {
346
- $links = FeedWordPress::syndicated_links();
 
 
 
 
 
 
 
 
347
  ?>
348
- <form id="syndicated-links" action="admin.php?page=<?php print $GLOBALS['fwp_path']; ?>/<?php echo basename(__FILE__); ?>" method="post">
349
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
 
 
 
 
350
 
351
- <?php $alt_row = true; ?>
352
-
353
- <?php if (fwp_test_wp_version(FWP_SCHEMA_25)) : ?>
 
 
 
 
354
  <div class="tablenav">
355
  <div class="alignright">
356
- <label for="add-uri">Add new source:</label>
357
  <input type="text" name="lookup" id="add-uri" value="Website or feed URI" />
358
  <?php FeedWordPressSettingsUI::magic_input_tip_js('add-uri'); ?>
359
 
360
  <input type="hidden" name="action" value="feedfinder" />
361
  <input type="submit" class="button-secondary" name="action" value="<?php print FWP_SYNDICATE_NEW; ?>" /></div>
362
 
363
- <?php if (count($links) > 0) : ?>
364
  <div class="alignleft">
 
 
 
 
365
  <input class="button-secondary" type="submit" name="action" value="<?php print FWP_UPDATE_CHECKED; ?>" />
366
- <input class="button-secondary delete" type="submit" class="delete" name="action" value="<?php print FWP_UNSUB_CHECKED; ?>" />
 
367
  </div>
 
 
 
368
  <?php endif; ?>
369
 
370
  <br class="clear" />
371
  </div>
372
  <br class="clear" />
373
-
374
- <table class="widefat">
375
- <?php else : ?>
376
- <table width="100%" cellpadding="3" cellspacing="3">
377
- <?php endif; ?>
378
- <thead>
379
- <tr>
380
- <th class="check-column" scope="col"><?php if (fwp_test_wp_version(FWP_SCHEMA_25)) : ?>
381
- <input type="checkbox" <?php if (fwp_test_wp_version(FWP_SCHEMA_25, FWP_SCHEMA_26)) : ?>onclick="checkAll(document.getElementById('syndicated-links'));"<?php endif; ?> />
382
- <?php endif; ?></th>
383
- <th scope="col"><?php _e('Name'); ?></th>
384
- <th scope="col"><?php _e('Feed'); ?></th>
385
- <th scope="col"><?php _e('Updated'); ?></th>
386
- </tr>
387
- </thead>
388
-
389
- <tbody>
390
- <?php if (count($links) > 0): foreach ($links as $link):
391
- $alt_row = !$alt_row; ?>
392
- <tr<?php echo ($alt_row?' class="alternate"':''); ?>>
393
- <th class="check-column" scope="row"><input type="checkbox" name="link_ids[]" value="<?php echo $link->link_id; ?>" /></th>
394
- <?php
395
- if (strlen($link->link_rss) > 0):
396
- $caption=__('Switch Feed');
397
- else :
398
- $caption=__('Find Feed');
399
- endif;
400
- ?>
401
- <td>
402
- <strong><a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/feeds-page.php&amp;link_id=<?php echo $link->link_id; ?>"><?php echo esc_html($link->link_name); ?></a></strong>
403
- <div class="row-actions"><div><strong>Settings &gt;</strong>
404
- <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/feeds-page.php&amp;link_id=<?php echo $link->link_id; ?>"><?php _e('Feed'); ?></a>
405
- | <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/posts-page.php&amp;link_id=<?php echo $link->link_id; ?>"><?php _e('Posts'); ?></a>
406
- | <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/authors-page.php&amp;link_id=<?php echo $link->link_id; ?>"><?php _e('Authors'); ?></a>
407
- | <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/categories-page.php&amp;link_id=<?php echo $link->link_id; ?>"><?php print htmlspecialchars(__('Categories'.FEEDWORDPRESS_AND_TAGS)); ?></a></div>
408
- <div><strong>Actions &gt;</strong>
409
- <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>&amp;link_id=<?php echo $link->link_id; ?>&amp;action=feedfinder"><?php echo $caption; ?></a>
410
- | <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>&amp;link_id=<?php echo $link->link_id; ?>&amp;action=Unsubscribe"><?php _e('Unsubscribe'); ?></a>
411
- | <a href="<?php echo esc_html($link->link_url); ?>"><?php _e('View')?></a></div>
412
- </div>
413
- </td>
414
- <?php if (strlen($link->link_rss) > 0): ?>
415
- <td><a href="<?php echo esc_html($link->link_rss); ?>"><?php echo esc_html(feedwordpress_display_url($link->link_rss, 32)); ?></a></td>
416
- <?php else: ?>
417
- <td style="background-color:#FFFFD0"><p><strong>no
418
- feed assigned</strong></p></td>
419
- <?php endif; ?>
420
-
421
- <td><?php
422
- $sLink = new SyndicatedLink($link->link_id);
423
- if (isset($sLink->settings['update/last'])) :
424
- print fwp_time_elapsed($sLink->settings['update/last']);
425
- else :
426
- _e('None yet');
427
- endif;
428
-
429
- print "<div style='font-style:italic;size:0.9em'>Ready for next update ";
430
- if (isset($sLink->settings['update/ttl']) and is_numeric($sLink->settings['update/ttl'])) :
431
- if (isset($sLink->settings['update/timed']) and $sLink->settings['update/timed']=='automatically') :
432
- $next = $sLink->settings['update/last'] + ((int) $sLink->settings['update/ttl'] * 60);
433
- print fwp_time_elapsed($next);
434
- if (FEEDWORDPRESS_DEBUG) : print " [".(($next-time())/60)." minutes]"; endif;
435
- else :
436
- echo "every ".$sLink->settings['update/ttl']." minute".(($sLink->settings['update/ttl']!=1)?"s":"");
437
- endif;
438
- else:
439
- echo "as soon as possible";
440
- endif;
441
- unset($sLink);
442
- print "</div>";
443
- ?>
444
- </td>
445
- </tr>
446
- <?php
447
- endforeach;
448
- else :
449
- ?>
450
- <tr><td colspan="<?php print $span+2; ?>"><p>There are no websites currently listed for syndication.</p></td></tr>
451
- <?php
452
- endif;
453
- ?>
454
- </tbody>
455
- </table>
456
-
457
- <?php if (count($links) > 0 and fwp_test_wp_version(0, FWP_SCHEMA_25)) : ?>
458
- <br/><hr/>
459
- <div class="submit"><input type="submit" class="delete" name="action" value="<?php print FWP_UNSUB_CHECKED; ?>" />
460
- <input type="submit" name="action" value="<?php print FWP_UPDATE_CHECKED; ?>" /></div>
461
- <?php endif; ?>
462
 
 
 
 
463
  </form>
464
  <?php
465
  } /* function fwp_syndication_manage_page_links_box() */
@@ -523,6 +688,119 @@ updated to &lt;<a href="<?php echo esc_html($fwp_post['feed']); ?>"><?php echo e
523
  return true; // Continue
524
  }
525
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
526
  function fwp_multidelete_page () {
527
  global $wpdb;
528
 
@@ -539,6 +817,12 @@ function fwp_multidelete_page () {
539
  $actions = array();
540
  endif;
541
 
 
 
 
 
 
 
542
  foreach ($actions as $link_id => $what) :
543
  $do_it[$what][] = $link_id;
544
  endforeach;
@@ -566,7 +850,16 @@ function fwp_multidelete_page () {
566
  // ... and kill them all
567
  if (count($post_ids) > 0) :
568
  foreach ($post_ids as $post_id) :
569
- wp_delete_post($post_id);
 
 
 
 
 
 
 
 
 
570
  endforeach;
571
  endif;
572
 
@@ -627,6 +920,7 @@ function fwp_multidelete_page () {
627
 
628
  <h2>Unsubscribe from Syndicated Links:</h2>
629
  <?php foreach ($targets as $link) :
 
630
  $link_url = esc_html($link->link_url);
631
  $link_name = esc_html($link->link_name);
632
  $link_description = esc_html($link->link_description);
@@ -643,13 +937,15 @@ function fwp_multidelete_page () {
643
  <td width="80%"><a href="<?php echo $link_url; ?>"><?php echo $link_url; ?></a></td></tr>
644
  <tr style="vertical-align:top"><th width="20%" scope="row">Subscription <?php _e('Options') ?>:</th>
645
  <td width="80%"><ul style="margin:0; padding: 0; list-style: none">
 
646
  <li><input type="radio" id="hide-<?php echo $link->link_id; ?>"
647
- name="link_action[<?php echo $link->link_id; ?>]" value="hide" />
648
  <label for="hide-<?php echo $link->link_id; ?>">Turn off the subscription for this
649
  syndicated link<br/><span style="font-size:smaller">(Keep the feed information
650
  and all the posts from this feed in the database, but don't syndicate any
651
  new posts from the feed.)</span></label></li>
652
- <li><input type="radio" id="nuke-<?php echo $link->link_id; ?>"
 
653
  name="link_action[<?php echo $link->link_id; ?>]" value="nuke" />
654
  <label for="nuke-<?php echo $link->link_id; ?>">Delete this syndicated link and all the
655
  posts that were syndicated from it</label></li>
7
 
8
  define('FWP_UPDATE_CHECKED', 'Update Checked');
9
  define('FWP_UNSUB_CHECKED', 'Unsubscribe');
10
+ define('FWP_DELETE_CHECKED', 'Delete');
11
+ define('FWP_RESUB_CHECKED', 'Re-subscribe');
12
+ define('FWP_SYNDICATE_NEW', 'Add →');
13
 
14
  class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
15
  function FeedWordPressSyndicationPage () {
22
 
23
  function has_link () { return false; }
24
 
25
+ var $_sources = NULL;
26
+
27
+ function sources ($visibility = 'Y') {
28
+ if (is_null($this->_sources)) :
29
+ $links = FeedWordPress::syndicated_links(array("hide_invisible" => false));
30
+ $this->_sources = array("Y" => array(), "N" => array());
31
+ foreach ($links as $link) :
32
+ $this->_sources[$link->link_visible][] = $link;
33
+ endforeach;
34
+ endif;
35
+ $ret = (
36
+ array_key_exists($visibility, $this->_sources)
37
+ ? $this->_sources[$visibility]
38
+ : $this->_sources
39
+ );
40
+ return $ret;
41
+ } /* FeedWordPressSyndicationPage::sources() */
42
+
43
+ function visibility_toggle () {
44
+ $sources = $this->sources('*');
45
+
46
+ $defaultVisibility = 'Y';
47
+ if ((count($this->sources('N')) > 0)
48
+ and (count($this->sources('Y'))==0)) :
49
+ $defaultVisibility = 'N';
50
+ endif;
51
+
52
+ $visibility = (
53
+ isset($_REQUEST['visibility'])
54
+ ? $_REQUEST['visibility']
55
+ : $defaultVisibility
56
+ );
57
+
58
+ return $visibility;
59
+ } /* FeedWordPressSyndicationPage::visibility_toggle() */
60
+
61
+ function show_inactive () {
62
+ return ($this->visibility_toggle() == 'N');
63
+ }
64
+
65
+ function updates_requested () {
66
+ global $wpdb;
67
+
68
+ if (isset($_POST['update']) or isset($_POST['action']) or isset($_POST['update_uri'])) :
69
+ // Only do things with side-effects for HTTP POST or command line
70
+ $fwp_update_invoke = 'post';
71
+ else :
72
+ $fwp_update_invoke = 'get';
73
+ endif;
74
+
75
+ $update_set = array();
76
+ if ($fwp_update_invoke != 'get') :
77
+ if (isset($_POST['link_ids']) and is_array($_POST['link_ids']) and ($_POST['action']==FWP_UPDATE_CHECKED)) :
78
+ $targets = $wpdb->get_results("
79
+ SELECT * FROM $wpdb->links
80
+ WHERE link_id IN (".implode(",",$_POST['link_ids']).")
81
+ ");
82
+ if (is_array($targets)) :
83
+ foreach ($targets as $target) :
84
+ $update_set[] = $target->link_rss;
85
+ endforeach;
86
+ else : // This should never happen
87
+ FeedWordPress::critical_bug('fwp_syndication_manage_page::targets', $targets, __LINE__);
88
+ endif;
89
+ elseif (isset($_POST['update_uri'])) :
90
+ $targets = $_POST['update_uri'];
91
+ if (!is_array($targets)) :
92
+ $targets = array($targets);
93
+ endif;
94
+ $update_set = $targets;
95
+ endif;
96
+ endif;
97
+ return $update_set;
98
+ }
99
+
100
  function display () {
101
  global $wpdb;
102
 
106
  endif;
107
 
108
  ?>
109
+ <?php
110
+ $cont = true;
111
+ $dispatcher = array(
112
+ "feedfinder" => 'fwp_feedfinder_page',
113
+ FWP_SYNDICATE_NEW => 'fwp_feedfinder_page',
114
+ "switchfeed" => 'fwp_switchfeed_page',
115
+ FWP_UNSUB_CHECKED => 'fwp_multidelete_page',
116
+ FWP_DELETE_CHECKED => 'fwp_multidelete_page',
117
+ 'Unsubscribe' => 'fwp_multidelete_page',
118
+ FWP_RESUB_CHECKED => 'fwp_multiundelete_page',
119
+ );
120
+ if (isset($_REQUEST['action']) and isset($dispatcher[$_REQUEST['action']])) :
121
+ $method = $dispatcher[$_REQUEST['action']];
122
+ $cont = call_user_func($method);
123
  endif;
124
 
125
  if ($cont):
166
  margin-top: 0.5em;
167
  border-top: thin solid #777777;
168
  }
169
+ .feed-missing {
170
+ background-color:#FFFFD0;
171
+ }
172
+ .unsubscribed tr {
173
+ background-color: #FFE0E0;
174
+ }
175
+ .unsubscribed tr.alternate {
176
+ background-color: #FFF0F0;
177
+ }
178
+ tr.feed-error {
179
+ background-color: #FFFFD0;
180
+ }
181
  </style>
182
  <?php
183
+ $links = $this->sources('Y');
184
+ $potential_updates = (!$this->show_inactive() and (count($this->sources('Y')) > 0));
185
+
186
  $this->open_sheet('Syndicated Sites');
187
  ?>
188
  <div id="post-body">
189
  <?php
190
+ if ($potential_updates
191
+ or (count($this->updates_requested()) > 0)) :
192
  fwp_add_meta_box(
193
  /*id=*/ 'feedwordpress_update_box',
194
  /*title=*/ __('Update feeds now'),
256
  <p><a href="http://feedwordpress.radgeek.com/">FeedWordPress</a> makes syndication
257
  simple and empowers you to stream content from all over the web into your
258
  WordPress hub. That's got to be worth a few lattes. If you're finding FWP useful,
259
+ <a href="http://feedwordpress.radgeek.com/donate/">a modest gift</a>
260
  is the best way to support steady progress on development, enhancements,
261
  support, and documentation.</p>
262
  <div class="donate">
295
  } /* FeedWordPressSyndicationPage::interstitial() */
296
  } /* class FeedWordPressSyndicationPage */
297
 
298
+ function fwp_dashboard_update_if_requested ($object) {
299
  global $wpdb;
300
 
301
+ $update_set = $object->updates_requested();
 
 
 
 
302
 
303
+ if (count($update_set) > 0) :
304
+ shuffle($update_set); // randomize order for load balancing purposes...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
 
 
 
306
  $feedwordpress = new FeedWordPress;
307
  add_action('feedwordpress_check_feed', 'update_feeds_mention');
308
  add_action('feedwordpress_check_feed_complete', 'update_feeds_finish', 10, 3);
314
  $crash_ts = NULL;
315
  endif;
316
 
317
+ echo "<div class=\"update-results\">\n";
 
 
 
 
318
  echo "<ul>\n";
319
  $tdelta = NULL;
320
  foreach ($update_set as $uri) :
399
  <p>Check currently scheduled feeds for new and updated posts.</p>
400
 
401
  <?php
402
+ fwp_dashboard_update_if_requested($object);
403
 
404
  if (!get_option('feedwordpress_automatic_updates')) :
405
  ?>
411
  endif;
412
  ?>
413
 
414
+ <div class="submit"><?php if ($object->show_inactive()) : ?>
415
+ <?php foreach ($object->updates_requested() as $req) : ?>
416
+ <input type="hidden" name="update_uri[]" value="<?php print esc_html($req); ?>" />
417
+ <?php endforeach; ?>
418
+ <?php else : ?>
419
+ <input type="hidden" name="update_uri" value="*" />
420
+ <?php endif; ?>
421
+ <input class="button-primary" type="submit" name="update" value="Update" /></div>
422
 
423
  <br style="clear: both" />
424
  </form>
425
  <?php
426
  } /* function fwp_syndication_manage_page_update_box () */
427
 
428
+ function fwp_syndication_manage_page_links_table_rows ($links, $visible = 'Y') {
429
+ global $fwp_path;
430
+
431
+ $subscribed = ('Y' == strtoupper($visible));
432
+ if ($subscribed or (count($links) > 0)) :
433
+ ?>
434
+ <table class="widefat<?php if (!$subscribed) : ?> unsubscribed<?php endif; ?>">
435
+ <thead>
436
+ <tr>
437
+ <th class="check-column" scope="col"><input type="checkbox" /></th>
438
+ <th scope="col"><?php _e('Name'); ?></th>
439
+ <th scope="col"><?php _e('Feed'); ?></th>
440
+ <th scope="col"><?php _e('Updated'); ?></th>
441
+ </tr>
442
+ </thead>
443
+
444
+ <tbody>
445
+ <?php
446
+ $alt_row = true;
447
+ if (count($links) > 0):
448
+ foreach ($links as $link):
449
+ $trClass = array();
450
+
451
+ // Prep: Get last updated timestamp
452
+ $sLink = new SyndicatedLink($link->link_id);
453
+ if (!is_null($sLink->setting('update/last'))) :
454
+ $lastUpdated = fwp_time_elapsed($sLink->setting('update/last'));
455
+ else :
456
+ $lastUpdated = __('None yet');
457
+ endif;
458
+
459
+ // Prep: get last error timestamp, if any
460
+ if (is_null($sLink->setting('update/error'))) :
461
+ $errorsSince = '';
462
+ else :
463
+ $trClass[] = 'feed-error';
464
+
465
+ $theError = unserialize($sLink->setting('update/error'));
466
+
467
+ $errorsSince = "<div class=\"returning-errors\">"
468
+ ."<p><strong>Returning errors</strong> since "
469
+ .fwp_time_elapsed($theError['since'])
470
+ ."</p>"
471
+ ."<p>Most recent ("
472
+ .fwp_time_elapsed($theError['ts'])
473
+ ."):<br/><code>"
474
+ .implode("</code><br/><code>", $theError['object']->get_error_messages())
475
+ ."</code></p>"
476
+ ."</div>\n";
477
+ endif;
478
+
479
+ $nextUpdate = "<div style='font-style:italic;size:0.9em'>Ready for next update ";
480
+ if (isset($sLink->settings['update/ttl']) and is_numeric($sLink->settings['update/ttl'])) :
481
+ if (isset($sLink->settings['update/timed']) and $sLink->settings['update/timed']=='automatically') :
482
+ $next = $sLink->settings['update/last'] + ((int) $sLink->settings['update/ttl'] * 60);
483
+ $nextUpdate .= fwp_time_elapsed($next);
484
+ if (FEEDWORDPRESS_DEBUG) : $nextUpdate .= " [".(($next-time())/60)." minutes]"; endif;
485
+ else :
486
+ $nextUpdate .= "every ".$sLink->settings['update/ttl']." minute".(($sLink->settings['update/ttl']!=1)?"s":"");
487
+ endif;
488
+ else:
489
+ $nextUpdate .= "as soon as possible";
490
+ endif;
491
+ $nextUpdate .= "</div>";
492
+
493
+ unset($sLink);
494
+
495
+ $alt_row = !$alt_row;
496
+
497
+ if ($alt_row) :
498
+ $trClass[] = 'alternate';
499
+ endif;
500
+ ?>
501
+ <tr<?php echo ((count($trClass) > 0) ? ' class="'.implode(" ", $trClass).'"':''); ?>>
502
+ <th class="check-column" scope="row"><input type="checkbox" name="link_ids[]" value="<?php echo $link->link_id; ?>" /></th>
503
+ <?php
504
+ $hrefPrefix = "admin.php?link_id={$link->link_id}&amp;page=${fwp_path}/";
505
+ $caption = (
506
+ (strlen($link->link_rss) > 0)
507
+ ? __('Switch Feed')
508
+ : $caption=__('Find Feed')
509
+ );
510
+ ?>
511
+ <td>
512
+ <strong><a href="<?php print $hrefPrefix; ?>feeds-page.php"><?php print esc_html($link->link_name); ?></a></strong>
513
+ <div class="row-actions"><?php if ($subscribed) : ?>
514
+ <div><strong>Settings &gt;</strong>
515
+ <a href="<?php print $hrefPrefix; ?>feeds-page.php"><?php _e('Feed'); ?></a>
516
+ | <a href="<?php print $hrefPrefix; ?>posts-page.php"><?php _e('Posts'); ?></a>
517
+ | <a href="<?php print $hrefPrefix; ?>authors-page.php"><?php _e('Authors'); ?></a>
518
+ | <a href="<?php print $hrefPrefix; ?>categories-page.php"><?php print htmlspecialchars(__('Categories'.FEEDWORDPRESS_AND_TAGS)); ?></a></div>
519
+ <?php endif; ?>
520
+
521
+ <div><strong>Actions &gt;</strong>
522
+ <?php if ($subscribed) : ?>
523
+ <a href="<?php print $hrefPrefix; ?><?php echo basename(__FILE__); ?>&amp;action=feedfinder"><?php echo $caption; ?></a>
524
+ <?php else : ?>
525
+ <a href="<?php print $hrefPrefix; ?><?php echo basename(__FILE__); ?>&amp;action=<?php print FWP_RESUB_CHECKED; ?>"><?php _e('Re-subscribe'); ?></a>
526
+ <?php endif; ?>
527
+ | <a href="<?php print $hrefPrefix; ?><?php echo basename(__FILE__); ?>&amp;action=Unsubscribe"><?php _e(($subscribed ? 'Unsubscribe' : 'Delete permanently')); ?></a>
528
+ | <a href="<?php print esc_html($link->link_url); ?>"><?php _e('View')?></a></div>
529
+ </div>
530
+ </td>
531
+ <?php if (strlen($link->link_rss) > 0): ?>
532
+ <td><a href="<?php echo esc_html($link->link_rss); ?>"><?php echo esc_html(feedwordpress_display_url($link->link_rss, 32)); ?></a></td>
533
+ <?php else: ?>
534
+ <td class="feed-missing"><p><strong>no feed assigned</strong></p></td>
535
+ <?php endif; ?>
536
+
537
+ <td><?php print $lastUpdated; ?>
538
+ <?php print $errorsSince; ?>
539
+ <?php print $nextUpdate; ?>
540
+ </td>
541
+ </tr>
542
+ <?php
543
+ endforeach;
544
+ else :
545
+ ?>
546
+ <tr><td colspan="4"><p>There are no websites currently listed for syndication.</p></td></tr>
547
+ <?php
548
+ endif;
549
+ ?>
550
+ </tbody>
551
+ </table>
552
+ <?php
553
+ endif;
554
+ } /* function fwp_syndication_manage_page_links_table_rows () */
555
+
556
+ function fwp_syndication_manage_page_links_subsubsub ($sources, $showInactive) {
557
+ global $fwp_path;
558
+ $hrefPrefix = "admin.php?page=${fwp_path}/".basename(__FILE__);
559
+ ?>
560
+ <ul class="subsubsub">
561
+ <li><a <?php if (!$showInactive) : ?>class="current" <?php endif; ?>href="<?php print $hrefPrefix; ?>&amp;visibility=Y">Subscribed
562
+ <span class="count">(<?php print count($sources['Y']); ?>)</span></a></li>
563
+ <?php if ($showInactive or (count($sources['N']) > 0)) : ?>
564
+ <li><a <?php if ($showInactive) : ?>class="current" <?php endif; ?>href="<?php print $hrefPrefix; ?>&amp;visibility=N">Inactive</a>
565
+ <span class="count">(<?php print count($sources['N']); ?>)</span></a></li>
566
+ <?php endif; ?>
567
+
568
+ </ul> <!-- class="subsubsub" -->
569
+ <?php
570
+ }
571
+
572
  function fwp_syndication_manage_page_links_box ($object = NULL, $box = NULL) {
573
+ global $fwp_path;
574
+
575
+ $links = FeedWordPress::syndicated_links(array("hide_invisible" => false));
576
+ $sources = $object->sources('*');
577
+
578
+ $visibility = $object->visibility_toggle();
579
+ $showInactive = $object->show_inactive();
580
+
581
+ $hrefPrefix = "admin.php?page=${fwp_path}/".basename(__FILE__);
582
  ?>
583
+ <form id="syndicated-links" action="<?php print $hrefPrefix; ?>&amp;visibility=<?php print $visibility; ?>" method="post">
584
  <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
585
+ <?php
586
+ if (count($sources[$visibility]) > 0) :
587
+ fwp_syndication_manage_page_links_subsubsub($sources, $showInactive);
588
+ endif;
589
 
590
+ if ($showInactive) : ?>
591
+ <p style="clear: both; font-size: smaller; font-style: italic">FeedWordPress used to syndicate
592
+ posts from these sources, but you have unsubscribed from them.</p>
593
+ <?php
594
+ endif;
595
+ ?>
596
+
597
  <div class="tablenav">
598
  <div class="alignright">
599
+ <label for="add-uri">New source:</label>
600
  <input type="text" name="lookup" id="add-uri" value="Website or feed URI" />
601
  <?php FeedWordPressSettingsUI::magic_input_tip_js('add-uri'); ?>
602
 
603
  <input type="hidden" name="action" value="feedfinder" />
604
  <input type="submit" class="button-secondary" name="action" value="<?php print FWP_SYNDICATE_NEW; ?>" /></div>
605
 
606
+ <?php if (count($sources[$visibility]) > 0) : ?>
607
  <div class="alignleft">
608
+ <?php if ($showInactive) : ?>
609
+ <input class="button-secondary" type="submit" name="action" value="<?php print FWP_RESUB_CHECKED; ?>" />
610
+ <input class="button-secondary" type="submit" name="action" value="<?php print FWP_DELETE_CHECKED; ?>" />
611
+ <?php else : ?>
612
  <input class="button-secondary" type="submit" name="action" value="<?php print FWP_UPDATE_CHECKED; ?>" />
613
+ <input class="button-secondary delete" type="submit" name="action" value="<?php print FWP_UNSUB_CHECKED; ?>" />
614
+ <?php endif ; ?>
615
  </div>
616
+
617
+ <?php else : ?>
618
+ <?php fwp_syndication_manage_page_links_subsubsub($sources, $showInactive); ?>
619
  <?php endif; ?>
620
 
621
  <br class="clear" />
622
  </div>
623
  <br class="clear" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
624
 
625
+ <?php
626
+ fwp_syndication_manage_page_links_table_rows($sources[$visibility], $visibility);
627
+ ?>
628
  </form>
629
  <?php
630
  } /* function fwp_syndication_manage_page_links_box() */
688
  return true; // Continue
689
  }
690
 
691
+ function fwp_multiundelete_page () {
692
+ global $wpdb;
693
+
694
+ // If this is a POST, validate source and user credentials
695
+ FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_feeds', /*capability=*/ 'manage_links');
696
+
697
+ $link_ids = (isset($_REQUEST['link_ids']) ? $_REQUEST['link_ids'] : array());
698
+ if (isset($_REQUEST['link_id'])) : array_push($link_ids, $_REQUEST['link_id']); endif;
699
+
700
+ if (isset($GLOBALS['fwp_post']['confirm']) and $GLOBALS['fwp_post']['confirm']=='Undelete'):
701
+ if (isset($GLOBALS['fwp_post']['link_action']) and is_array($GLOBALS['fwp_post']['link_action'])) :
702
+ $actions = $GLOBALS['fwp_post']['link_action'];
703
+ else :
704
+ $actions = array();
705
+ endif;
706
+
707
+ $do_it = array(
708
+ 'unhide' => array(),
709
+ );
710
+
711
+ foreach ($actions as $link_id => $what) :
712
+ $do_it[$what][] = $link_id;
713
+ endforeach;
714
+
715
+ $alter = array();
716
+ if (count($do_it['unhide']) > 0) :
717
+ $unhiddem = "(".implode(', ', $do_it['unhide']).")";
718
+ $alter[] = "
719
+ UPDATE $wpdb->links
720
+ SET link_visible = 'Y'
721
+ WHERE link_id IN {$unhiddem}
722
+ ";
723
+ endif;
724
+
725
+ $errs = array(); $success = array ();
726
+ foreach ($alter as $sql) :
727
+ $result = $wpdb->query($sql);
728
+ if (!$result):
729
+ $errs[] = mysql_error();
730
+ endif;
731
+ endforeach;
732
+
733
+ if (count($alter) > 0) :
734
+ echo "<div class=\"updated\">\n";
735
+ if (count($errs) > 0) :
736
+ echo "There were some problems processing your ";
737
+ echo "re-subscribe request. [SQL: ".implode('; ', $errs)."]";
738
+ else :
739
+ echo "Your re-subscribe request(s) have been processed.";
740
+ endif;
741
+ echo "</div>\n";
742
+ endif;
743
+
744
+ return true; // Continue on to Syndicated Sites listing
745
+ else :
746
+ $targets = $wpdb->get_results("
747
+ SELECT * FROM $wpdb->links
748
+ WHERE link_id IN (".implode(",",$link_ids).")
749
+ ");
750
+ ?>
751
+ <form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>" method="post">
752
+ <div class="wrap">
753
+ <?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?>
754
+ <input type="hidden" name="action" value="<?php print FWP_RESUB_CHECKED; ?>" />
755
+ <input type="hidden" name="confirm" value="Undelete" />
756
+
757
+ <h2>Re-subscribe to Syndicated Links:</h2>
758
+ <?php
759
+ foreach ($targets as $link) :
760
+ $subscribed = ('Y' == strtoupper($link->link_visible));
761
+ $link_url = esc_html($link->link_url);
762
+ $link_name = esc_html($link->link_name);
763
+ $link_description = esc_html($link->link_description);
764
+ $link_rss = esc_html($link->link_rss);
765
+
766
+ if (!$subscribed) :
767
+ ?>
768
+ <fieldset>
769
+ <legend><?php echo $link_name; ?></legend>
770
+ <table class="editform" width="100%" cellspacing="2" cellpadding="5">
771
+ <tr><th scope="row" width="20%"><?php _e('Feed URI:') ?></th>
772
+ <td width="80%"><a href="<?php echo $link_rss; ?>"><?php echo $link_rss; ?></a></td></tr>
773
+ <tr><th scope="row" width="20%"><?php _e('Short description:') ?></th>
774
+ <td width="80%"><?php echo $link_description; ?></span></td></tr>
775
+ <tr><th width="20%" scope="row"><?php _e('Homepage:') ?></th>
776
+ <td width="80%"><a href="<?php echo $link_url; ?>"><?php echo $link_url; ?></a></td></tr>
777
+ <tr style="vertical-align:top"><th width="20%" scope="row">Subscription <?php _e('Options') ?>:</th>
778
+ <td width="80%"><ul style="margin:0; padding: 0; list-style: none">
779
+ <li><input type="radio" id="unhide-<?php echo $link->link_id; ?>"
780
+ name="link_action[<?php echo $link->link_id; ?>]" value="unhide" checked="checked" />
781
+ <label for="unhide-<?php echo $link->link_id; ?>">Turn back on the subscription
782
+ for this syndication source.</label></li>
783
+ <li><input type="radio" id="nothing-<?php echo $link->link_id; ?>"
784
+ name="link_action[<?php echo $link->link_id; ?>]" value="nothing" />
785
+ <label for="nothing-<?php echo $link->link_id; ?>">Leave this feed as it is.
786
+ I changed my mind.</label></li>
787
+ </ul>
788
+ </table>
789
+ </fieldset>
790
+ <?php
791
+ endif;
792
+ endforeach;
793
+ ?>
794
+
795
+ <div class="submit">
796
+ <input class="button-primary delete" type="submit" name="submit" value="<?php _e('Re-subscribe to selected feeds &raquo;') ?>" />
797
+ </div>
798
+ </div>
799
+ <?php
800
+ return false; // Don't continue on to Syndicated Sites listing
801
+ endif;
802
+ }
803
+
804
  function fwp_multidelete_page () {
805
  global $wpdb;
806
 
817
  $actions = array();
818
  endif;
819
 
820
+ $do_it = array(
821
+ 'hide' => array(),
822
+ 'nuke' => array(),
823
+ 'delete' => array(),
824
+ );
825
+
826
  foreach ($actions as $link_id => $what) :
827
  $do_it[$what][] = $link_id;
828
  endforeach;
850
  // ... and kill them all
851
  if (count($post_ids) > 0) :
852
  foreach ($post_ids as $post_id) :
853
+ if (FeedWordPressCompatibility::test_version(FWP_SCHEMA_29)) :
854
+ // Force scrubbing of deleted post
855
+ // rather than sending to Trashcan
856
+ wp_delete_post(
857
+ /*postid=*/ $post_id,
858
+ /*force_delete=*/ true
859
+ );
860
+ else :
861
+ wp_delete_post($post_id);
862
+ endif;
863
  endforeach;
864
  endif;
865
 
920
 
921
  <h2>Unsubscribe from Syndicated Links:</h2>
922
  <?php foreach ($targets as $link) :
923
+ $subscribed = ('Y' == strtoupper($link->link_visible));
924
  $link_url = esc_html($link->link_url);
925
  $link_name = esc_html($link->link_name);
926
  $link_description = esc_html($link->link_description);
937
  <td width="80%"><a href="<?php echo $link_url; ?>"><?php echo $link_url; ?></a></td></tr>
938
  <tr style="vertical-align:top"><th width="20%" scope="row">Subscription <?php _e('Options') ?>:</th>
939
  <td width="80%"><ul style="margin:0; padding: 0; list-style: none">
940
+ <?php if ($subscribed) : ?>
941
  <li><input type="radio" id="hide-<?php echo $link->link_id; ?>"
942
+ name="link_action[<?php echo $link->link_id; ?>]" value="hide" checked="checked" />
943
  <label for="hide-<?php echo $link->link_id; ?>">Turn off the subscription for this
944
  syndicated link<br/><span style="font-size:smaller">(Keep the feed information
945
  and all the posts from this feed in the database, but don't syndicate any
946
  new posts from the feed.)</span></label></li>
947
+ <?php endif; ?>
948
+ <li><input type="radio" id="nuke-<?php echo $link->link_id; ?>"<?php if (!$subscribed) : ?> checked="checked"<?php endif; ?>
949
  name="link_action[<?php echo $link->link_id; ?>]" value="nuke" />
950
  <label for="nuke-<?php echo $link->link_id; ?>">Delete this syndicated link and all the
951
  posts that were syndicated from it</label></li>