FeedWordPress - Version 2011.0211

Version Description

Download this release

Release Info

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

Code changes from version 2010.0905 to 2011.0211

admin-ui.php CHANGED
@@ -2,6 +2,8 @@
2
  class FeedWordPressAdminPage {
3
  var $context;
4
  var $updated = false;
 
 
5
  var $link = NULL;
6
  var $dispatch = NULL;
7
  var $filename = NULL;
@@ -43,13 +45,44 @@ class FeedWordPressAdminPage {
43
  } /* FeedWordPressAdminPage::pagename () */
44
 
45
  function accept_POST ($post) {
46
- if ($this->save_requested_in($post)) : // User mashed Save Changes
 
 
47
  $this->save_settings($post);
48
  endif;
49
- do_action($this->dispatch.'_post', $post, $this);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
 
52
  function save_settings ($post) {
 
 
53
  if ($this->for_feed_settings()) :
54
  // Save settings
55
  $this->link->save_settings(/*reload=*/ true);
@@ -62,12 +95,37 @@ class FeedWordPressAdminPage {
62
  else :
63
  $this->updated = true;
64
  endif;
65
- do_action($this->dispatch.'_save', $post, $this);
66
  } /* FeedWordPressAdminPage::save_settings () */
67
 
68
  function for_feed_settings () { return (is_object($this->link) and method_exists($this->link, 'found') and $this->link->found()); }
69
  function for_default_settings () { return !$this->for_feed_settings(); }
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  function update_setting ($names, $value, $default = 'default') {
72
  if (is_string($names)) :
73
  $feed_name = $names;
@@ -87,7 +145,10 @@ class FeedWordPressAdminPage {
87
  function save_requested_in ($post) {
88
  return (isset($post['save']) or isset($post['submit']));
89
  }
90
-
 
 
 
91
  /*static*/ function submitted_link_id () {
92
  global $fwp_post;
93
 
@@ -262,7 +323,7 @@ class FeedWordPressAdminPage {
262
  <option value="<?php print (int) $ddlink->link_id; ?>"<?php if (!is_null($this->link) and ($this->link->id==$ddlink->link_id)) : ?> selected="selected"<?php endif; ?>><?php print esc_html($ddlink->link_name); ?></option>
263
  <?php endforeach; endif; ?>
264
  </select>
265
- <input class="button" type="submit" name="go" value="<?php _e('Go') ?> &raquo;" /></li>
266
 
267
  <?php
268
  $this->display_feed_settings_page_links(array(
@@ -271,8 +332,14 @@ class FeedWordPressAdminPage {
271
  'after' => '</li>',
272
  'subscription' => $this->link,
273
  ));
 
 
274
  ?>
275
- </ul>
 
 
 
 
276
  </div>
277
  <?php
278
  } /* FeedWordPressAdminPage::display_feed_select_dropdown() */
@@ -285,18 +352,22 @@ class FeedWordPressAdminPage {
285
  }
286
 
287
  function display_update_notice_if_updated ($pagename = 'Syndication', $mesg = NULL) {
 
 
 
 
288
  if ($this->updated) :
289
  if ($this->updated === true) :
290
- $mesg = $pagename . ' settings updated.';
291
  else :
292
- $mesg = $this->updated;
293
  endif;
294
  endif;
295
 
296
- if (!is_null($mesg)) :
297
  ?>
298
  <div class="updated">
299
- <p><?php print esc_html($mesg); ?></p>
300
  </div>
301
  <?php
302
  endif;
@@ -328,7 +399,7 @@ class FeedWordPressAdminPage {
328
  } /* FeedWordPressAdminPage::form_action () */
329
 
330
  function update_message () {
331
- return NULL;
332
  }
333
 
334
  function display () {
@@ -493,6 +564,7 @@ class FeedWordPressAdminPage {
493
  // This allows us to provide an alternative set of human-readable
494
  // labels for each potential value. For use in Currently: line.
495
  if (isset($params['labels'])) : $labels = $params['labels'];
 
496
  else : $labels = $options;
497
  endif;
498
 
@@ -572,6 +644,8 @@ class FeedWordPressAdminPage {
572
  <span class="current-setting">Currently:
573
  <strong><?php if (is_callable($labels)) :
574
  print call_user_func($labels, $globalSetting, $defaulted, $params);
 
 
575
  else :
576
  print $labels[$globalSetting];
577
  endif; ?></strong> (<a href="<?php print $href; ?>">change</a>)</span></li>
@@ -676,6 +750,11 @@ function fwp_tags_box ($tags, $object, $params = array()) {
676
  $tax_name = (isset($params['taxonomy']) ? $params['taxonomy'] : 'post_tag');
677
  $desc = "<p style=\"font-size:smaller;font-style:bold;margin:0\">Tag $object as...</p>";
678
 
 
 
 
 
 
679
  print $desc;
680
  $helps = __('Separate tags with commas.');
681
  $box['title'] = __('Tags');
@@ -684,7 +763,7 @@ function fwp_tags_box ($tags, $object, $params = array()) {
684
  <div class="jaxtag">
685
  <div class="nojs-tags hide-if-js">
686
  <p><?php _e('Add or remove tags'); ?></p>
687
- <textarea name="<?php echo "tax_input[$tax_name]"; ?>" class="the-tags" id="tax-input[<?php echo $tax_name; ?>]"><?php echo esc_attr(implode(",", $tags)); ?></textarea></div>
688
 
689
  <div class="ajaxtag hide-if-no-js">
690
  <label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $box['title']; ?></label>
@@ -805,7 +884,7 @@ function fwp_author_list () {
805
  global $wpdb;
806
  $ret = array();
807
 
808
- $users = $wpdb->get_results("SELECT * FROM $wpdb->users ORDER BY display_name");
809
  if (is_array($users)) :
810
  foreach ($users as $user) :
811
  $id = (int) $user->ID;
@@ -848,6 +927,14 @@ class FeedWordPressSettingsUI {
848
  function admin_styles () {
849
  ?>
850
  <style type="text/css">
 
 
 
 
 
 
 
 
851
  .fwpfs {
852
  background-image: url(<?php print admin_url('images/fav.png'); ?>);
853
  background-repeat: repeat-x;
@@ -890,10 +977,13 @@ class FeedWordPressSettingsUI {
890
  } /* FeedWordPressSettingsUI::fix_toggles_js () */
891
 
892
  function magic_input_tip_js ($id) {
 
 
 
893
  ?>
894
  <script type="text/javascript">
895
  jQuery(document).ready( function () {
896
- var inputBox = jQuery("#<?php print $id; ?>");
897
  var boxEl = inputBox.get(0);
898
  if (boxEl.value==boxEl.defaultValue) { inputBox.addClass('form-input-tip'); }
899
  inputBox.focus(function() {
@@ -1069,7 +1159,10 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
1069
  <td class="feed-missing"><p><strong>no feed assigned</strong></p></td>
1070
  <?php endif; ?>
1071
 
1072
- <td><?php print $lastUpdated; ?>
 
 
 
1073
  <?php print $errorsSince; ?>
1074
  <?php print $nextUpdate; ?>
1075
  </td>
2
  class FeedWordPressAdminPage {
3
  var $context;
4
  var $updated = false;
5
+ var $mesg = NULL;
6
+
7
  var $link = NULL;
8
  var $dispatch = NULL;
9
  var $filename = NULL;
45
  } /* FeedWordPressAdminPage::pagename () */
46
 
47
  function accept_POST ($post) {
48
+ if ($this->for_feed_settings() and $this->update_requested_in($post)) :
49
+ $this->update_feed();
50
+ elseif ($this->save_requested_in($post)) : // User mashed Save Changes
51
  $this->save_settings($post);
52
  endif;
53
+ do_action($this->dispatch.'_post', &$post, &$this);
54
+ }
55
+
56
+ function update_feed () {
57
+ global $feedwordpress;
58
+
59
+ add_action('feedwordpress_check_feed', 'update_feeds_mention');
60
+ add_action('feedwordpress_check_feed_complete', 'update_feeds_finish', 10, 3);
61
+
62
+ print '<div class="updated">';
63
+ print "<ul>";
64
+ $uri = $this->link->uri();
65
+ $delta = $feedwordpress->update($uri);
66
+ print "</ul>";
67
+
68
+ if (!is_null($delta)) :
69
+ $mesg = array();
70
+ if (isset($delta['new'])) : $mesg[] = ' '.$delta['new'].' new posts were syndicated'; endif;
71
+ if (isset($delta['updated'])) : $mesg[] = ' '.$delta['updated'].' existing posts were updated'; endif;
72
+ echo "<p><strong>Update complete.</strong>".implode(' and', $mesg)."</p>";
73
+ echo "\n"; flush();
74
+ else :
75
+ $uri = esc_html($uri);
76
+ echo "<p><strong>Error:</strong> There was a problem updating <a href=\"$uri\">$uri</a></p>\n";
77
+ endif;
78
+ print "</div>\n";
79
+ remove_action('feedwordpress_check_feed', 'update_feeds_mention');
80
+ remove_action('feedwordpress_check_feed_complete', 'update_feeds_finish', 10, 3);
81
  }
82
 
83
  function save_settings ($post) {
84
+ do_action($this->dispatch.'_save', &$post, &$this);
85
+
86
  if ($this->for_feed_settings()) :
87
  // Save settings
88
  $this->link->save_settings(/*reload=*/ true);
95
  else :
96
  $this->updated = true;
97
  endif;
 
98
  } /* FeedWordPressAdminPage::save_settings () */
99
 
100
  function for_feed_settings () { return (is_object($this->link) and method_exists($this->link, 'found') and $this->link->found()); }
101
  function for_default_settings () { return !$this->for_feed_settings(); }
102
 
103
+ function setting ($names, $fallback_value = NULL, $params = array()) {
104
+ if (!is_array($params)) :
105
+ $params = array('default' => $params);
106
+ endif;
107
+ $params = shortcode_atts(array(
108
+ 'default' => 'default',
109
+ 'fallback' => true,
110
+ ), $params);
111
+
112
+ if (is_string($names)) :
113
+ $feed_name = $names;
114
+ $global_name = 'feedwordpress_'.preg_replace('![\s/]+!', '_', $names);
115
+ else :
116
+ $feed_name = $names['feed'];
117
+ $global_name = 'feedwordpress_'.$names['global'];
118
+ endif;
119
+
120
+ if ($this->for_feed_settings()) : // Check feed-specific setting first; fall back to global
121
+ if (!$params['fallback']) : $global_name = NULL; endif;
122
+ $ret = $this->link->setting($feed_name, $global_name, $fallback_value, $params['default']);
123
+ else : // Check global setting
124
+ $ret = get_option($global_name, $fallback_value);
125
+ endif;
126
+ return $ret;
127
+ }
128
+
129
  function update_setting ($names, $value, $default = 'default') {
130
  if (is_string($names)) :
131
  $feed_name = $names;
145
  function save_requested_in ($post) {
146
  return (isset($post['save']) or isset($post['submit']));
147
  }
148
+ function update_requested_in ($post) {
149
+ return (isset($post['update']) and (strlen($post['update']) > 0));
150
+ }
151
+
152
  /*static*/ function submitted_link_id () {
153
  global $fwp_post;
154
 
323
  <option value="<?php print (int) $ddlink->link_id; ?>"<?php if (!is_null($this->link) and ($this->link->id==$ddlink->link_id)) : ?> selected="selected"<?php endif; ?>><?php print esc_html($ddlink->link_name); ?></option>
324
  <?php endforeach; endif; ?>
325
  </select>
326
+ <input id="fwpfs-button" class="button" type="submit" name="go" value="<?php _e('Go') ?> &raquo;" /></li>
327
 
328
  <?php
329
  $this->display_feed_settings_page_links(array(
332
  'after' => '</li>',
333
  'subscription' => $this->link,
334
  ));
335
+
336
+ if ($this->for_feed_settings()) :
337
  ?>
338
+ <li><input class="button" type="submit" name="update" value="Update Now" /></li>
339
+ <?php
340
+ endif;
341
+ ?>
342
+ </ul>
343
  </div>
344
  <?php
345
  } /* FeedWordPressAdminPage::display_feed_select_dropdown() */
352
  }
353
 
354
  function display_update_notice_if_updated ($pagename = 'Syndication', $mesg = NULL) {
355
+ if (!is_null($mesg)) :
356
+ $this->mesg = $mesg;
357
+ endif;
358
+
359
  if ($this->updated) :
360
  if ($this->updated === true) :
361
+ $this->mesg = $pagename . ' settings updated.';
362
  else :
363
+ $this->mesg = $this->updated;
364
  endif;
365
  endif;
366
 
367
+ if (!is_null($this->mesg)) :
368
  ?>
369
  <div class="updated">
370
+ <p><?php print esc_html($this->mesg); ?></p>
371
  </div>
372
  <?php
373
  endif;
399
  } /* FeedWordPressAdminPage::form_action () */
400
 
401
  function update_message () {
402
+ return $this->mesg;
403
  }
404
 
405
  function display () {
564
  // This allows us to provide an alternative set of human-readable
565
  // labels for each potential value. For use in Currently: line.
566
  if (isset($params['labels'])) : $labels = $params['labels'];
567
+ elseif (is_callable($options)) : $labels = NULL;
568
  else : $labels = $options;
569
  endif;
570
 
644
  <span class="current-setting">Currently:
645
  <strong><?php if (is_callable($labels)) :
646
  print call_user_func($labels, $globalSetting, $defaulted, $params);
647
+ elseif (is_null($labels)) :
648
+ print $globalSetting;
649
  else :
650
  print $labels[$globalSetting];
651
  endif; ?></strong> (<a href="<?php print $href; ?>">change</a>)</span></li>
750
  $tax_name = (isset($params['taxonomy']) ? $params['taxonomy'] : 'post_tag');
751
  $desc = "<p style=\"font-size:smaller;font-style:bold;margin:0\">Tag $object as...</p>";
752
 
753
+ if (isset($params['textarea_name'])) :
754
+ $textAreaName = $params['textarea_name'];
755
+ else :
756
+ $textAreaName = "tax_input[$tax_name]";
757
+ endif;
758
  print $desc;
759
  $helps = __('Separate tags with commas.');
760
  $box['title'] = __('Tags');
763
  <div class="jaxtag">
764
  <div class="nojs-tags hide-if-js">
765
  <p><?php _e('Add or remove tags'); ?></p>
766
+ <textarea name="<?php echo esc_html($textAreaName); ?>" class="the-tags" id="tax-input[<?php echo $tax_name; ?>]"><?php echo esc_attr(implode(",", $tags)); ?></textarea></div>
767
 
768
  <div class="ajaxtag hide-if-no-js">
769
  <label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $box['title']; ?></label>
884
  global $wpdb;
885
  $ret = array();
886
 
887
+ $users = get_users_of_blog();
888
  if (is_array($users)) :
889
  foreach ($users as $user) :
890
  $id = (int) $user->ID;
927
  function admin_styles () {
928
  ?>
929
  <style type="text/css">
930
+ #feedwordpress-admin-feeds .link-rss-params-remove .x, .feedwordpress-admin .remove-it .x {
931
+ background: url(<?php print admin_url('images/xit.gif') ?>) no-repeat scroll 0 0 transparent;
932
+ }
933
+
934
+ #feedwordpress-admin-feeds .link-rss-params-remove:hover .x, .feedwordpress-admin .remove-it:hover .x {
935
+ background: url(<?php print admin_url('images/xit.gif') ?>) no-repeat scroll -10px 0 transparent;
936
+ }
937
+
938
  .fwpfs {
939
  background-image: url(<?php print admin_url('images/fav.png'); ?>);
940
  background-repeat: repeat-x;
977
  } /* FeedWordPressSettingsUI::fix_toggles_js () */
978
 
979
  function magic_input_tip_js ($id) {
980
+ if (!preg_match('/^[.#]/', $id)) :
981
+ $id = '#'.$id;
982
+ endif;
983
  ?>
984
  <script type="text/javascript">
985
  jQuery(document).ready( function () {
986
+ var inputBox = jQuery("<?php print $id; ?>");
987
  var boxEl = inputBox.get(0);
988
  if (boxEl.value==boxEl.defaultValue) { inputBox.addClass('form-input-tip'); }
989
  inputBox.focus(function() {
1159
  <td class="feed-missing"><p><strong>no feed assigned</strong></p></td>
1160
  <?php endif; ?>
1161
 
1162
+ <td><div style="float: right; padding-left: 10px">
1163
+ <input type="submit" class="button" name="update_uri[<?php print esc_html($link->link_rss); ?>]" value="<?php _e('Update Now'); ?>" />
1164
+ </div>
1165
+ <?php print $lastUpdated; ?>
1166
  <?php print $errorsSince; ?>
1167
  <?php print $nextUpdate; ?>
1168
  </td>
authors-page.php CHANGED
@@ -5,11 +5,21 @@ class FeedWordPressAuthorsPage extends FeedWordPressAdminPage {
5
  var $authorlist = NULL;
6
  var $rule_count = 0;
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 () {
@@ -21,7 +31,7 @@ class FeedWordPressAuthorsPage extends FeedWordPressAdminPage {
21
  $unfamiliar = array ('create' => '','default' => '','filter' => '');
22
 
23
  if ($page->for_feed_settings()) :
24
- $key = $link->setting('unfamiliar author', NULL, 'site-default');
25
  $unfamiliar['site-default'] = '';
26
  else :
27
  $key = FeedWordPress::on_unfamiliar('author');
@@ -34,45 +44,52 @@ class FeedWordPressAuthorsPage extends FeedWordPressAdminPage {
34
  // Hey ho, let's go...
35
  ?>
36
  <table class="form-table">
37
- <tbody>
38
- <tr>
39
- <th>New authors</th>
40
- <td><span>Authors who haven't been syndicated before</span>
41
- <select style="max-width: 27.0em" id="unfamiliar-author" name="unfamiliar_author" onchange="contextual_appearance('unfamiliar-author', 'unfamiliar-author-newuser', 'unfamiliar-author-default', 'newuser', 'inline');">
42
- <?php if ($page->for_feed_settings()) : ?>
43
- <option value="site-default"<?php print $unfamiliar['site-default']; ?>>are handled according to the default for all feeds</option>
 
 
 
 
 
44
  <?php endif; ?>
45
- <option value="create"<?php print $unfamiliar['create']; ?>>will have a new author account created for them</option>
46
- <?php foreach ($page->authorlist as $author_id => $author_name) : ?>
47
- <option value="<?php echo $author_id; ?>"<?php print (isset($unfamiliar[$author_id]) ? $unfamiliar[$author_id] : ''); ?>>will have their posts attributed to <?php echo $author_name; ?></option>
 
 
48
  <?php endforeach; ?>
49
- <option value="newuser">will have their posts attributed to a new user...</option>
50
- <option value="filter"<?php print $unfamiliar['filter'] ?>>get filtered out</option>
51
  </select>
 
 
 
 
 
 
 
 
52
 
53
- <span id="unfamiliar-author-newuser">named <input type="text" name="unfamiliar_author_newuser" value="" /></span></p>
54
- </td>
55
- </tr>
56
-
57
- <?php
58
- if ($page->for_feed_settings()) :
59
- ?>
60
- <tr><th>Syndicated authors</th>
61
- <td>For attributing posts by specific authors. Blank out a name to delete the rule. Fill in a new name at the bottom to create a new rule.</p>
62
  <table style="width: 100%">
63
  <?php
64
- if (isset($link->settings['map authors'])) :
65
  ?>
66
  <?php
67
  $page->rule_count=0;
68
- foreach ($link->settings['map authors'] as $author_rules) :
69
  foreach ($author_rules as $author_name => $author_action) :
70
- $page->rule_count++;
 
71
  ?>
72
  <tr>
73
  <th style="text-align: left; width: 15.0em">Posts by <input type="text" name="author_rules_name[]" value="<?php echo htmlspecialchars($author_name); ?>" size="11" /></th>
74
  <td>
75
- <select id="author-rules-<?php echo $page->rule_count; ?>" name="author_rules_action[]" onchange="contextual_appearance('author-rules-<?php echo $page->rule_count; ?>', 'author-rules-<?php echo $page->rule_count; ?>-newuser', 'author-rules-<?php echo $page->rule_count; ?>-default', 'newuser', 'inline');">
76
  <?php foreach ($page->authorlist as $local_author_id => $local_author_name) : ?>
77
  <option value="<?php echo $local_author_id; ?>"<?php if ($local_author_id==$author_action) : echo ' selected="selected"'; endif; ?>>are assigned to <?php echo $local_author_name; ?></option>
78
  <?php endforeach; ?>
@@ -80,10 +97,12 @@ if ($page->for_feed_settings()) :
80
  <option value="filter"<?php if ('filter'==$author_action) : echo ' selected="selected"'; endif; ?>>get filtered out</option>
81
  </select>
82
 
83
- <span id="author-rules-<?php echo $page->rule_count; ?>-newuser">named <input type="text" name="author_rules_newuser[]" value="" /></span>
84
  </td>
85
  </tr>
86
- <?php endforeach;
 
 
87
  endforeach;
88
  endif;
89
  ?>
@@ -102,7 +121,29 @@ if ($page->for_feed_settings()) :
102
  <span id="add-author-rule-newuser">named <input type="text" name="add_author_rule_newuser" value="" /></span>
103
  </td>
104
  </tr>
105
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  </td>
107
  </tr>
108
  <?php endif; ?>
@@ -155,46 +196,75 @@ if ($page->for_feed_settings()) :
155
  </table>
156
  <?php
157
  } /* FeedWordPressAuthorsPage::fix_authors_box () */
158
- } /* class FeedWordPressAuthorsPage */
159
 
160
- function fwp_authors_page () {
161
- global $wpdb, $wp_db_version;
 
 
 
 
 
 
162
 
163
- if (FeedWordPress::needs_upgrade()) :
164
- fwp_upgrade_page();
165
- return;
166
- endif;
 
167
 
168
- FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_author_settings', /*capability=*/ 'manage_links');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
- $link = FeedWordPressAdminPage::submitted_link();
171
- $authorsPage = new FeedWordPressAuthorsPage($link);
 
 
 
 
 
172
 
173
- $mesg = null;
174
- $updated_link = false;
175
 
176
- if (isset($GLOBALS['fwp_post']['fix_mismatch'])) :
177
- if ('newuser'==$GLOBALS['fwp_post']['fix_mismatch_to']) :
178
- $newuser_name = trim($GLOBALS['fwp_post']['fix_mismatch_to_newuser']);
179
- $fix_mismatch_to_id = fwp_insert_new_user($newuser_name);
180
  else :
181
- $fix_mismatch_to_id = $GLOBALS['fwp_post']['fix_mismatch_to'];
182
  endif;
183
- $fix_mismatch_from_id = (int) $GLOBALS['fwp_post']['fix_mismatch_from'];
184
- if (is_numeric($fix_mismatch_from_id)) :
185
- // Make a list of all the items by this author syndicated from this feed...
 
 
186
  $post_ids = $wpdb->get_col("
187
  SELECT {$wpdb->posts}.id
188
  FROM {$wpdb->posts}, {$wpdb->postmeta}
189
  WHERE ({$wpdb->posts}.id = {$wpdb->postmeta}.post_id)
190
  AND {$wpdb->postmeta}.meta_key = 'syndication_feed_id'
191
- AND {$wpdb->postmeta}.meta_value = '{$link->id}'
192
- AND {$wpdb->posts}.post_author = '{$fix_mismatch_from_id}'
193
  ");
194
 
195
  if (count($post_ids) > 0) :
 
 
 
196
  // Re-assign them all to the correct author
197
- if (is_numeric($fix_mismatch_to_id)) : // re-assign to a particular user
198
  $post_set = "(".implode(",", $post_ids).")";
199
 
200
  // Getting the revisions too, if there are any
@@ -202,189 +272,121 @@ function fwp_authors_page () {
202
 
203
  $wpdb->query("
204
  UPDATE {$wpdb->posts}
205
- SET post_author='{$fix_mismatch_to_id}'
206
  WHERE ({$wpdb->posts}.id IN $post_set
207
  $parent_in_clause)
208
  ");
209
- $mesg = "Re-assigned ".count($post_ids)." post".((count($post_ids)==1)?'':'s').".";
210
 
211
  // ... and kill them all
212
- elseif ($fix_mismatch_to_id=='filter') :
213
  foreach ($post_ids as $post_id) :
214
  wp_delete_post($post_id);
215
- endforeach;
216
- $mesg = "Deleted ".count($post_ids)." post".((count($post_ids)==1)?'':'s').".";
 
217
  endif;
218
  else :
219
- $mesg = "Couldn't find any posts that matched your criteria.";
220
  endif;
221
  endif;
222
- $updated_link = false;
223
- elseif (isset($GLOBALS['fwp_post']['save'])) :
224
- if (is_object($link) and $link->found()) :
 
 
 
225
  $alter = array ();
226
 
227
  // Unfamiliar author rule
228
- if (isset($GLOBALS['fwp_post']["unfamiliar_author"])) :
229
- if ('site-default'==$GLOBALS['fwp_post']["unfamiliar_author"]) :
230
- unset($link->settings["unfamiliar author"]);
231
- elseif ('newuser'==$GLOBALS['fwp_post']["unfamiliar_author"]) :
232
- $newuser_name = trim($GLOBALS['fwp_post']["unfamiliar_author_newuser"]);
233
- $link->map_name_to_new_user(/*name=*/ NULL, $newuser_name);
234
  else :
235
- $link->settings["unfamiliar author"] = $GLOBALS['fwp_post']["unfamiliar_author"];
 
 
 
 
236
  endif;
237
  endif;
238
 
239
  // Handle author mapping rules
240
- if (isset($GLOBALS['fwp_post']['author_rules_name']) and isset($GLOBALS['fwp_post']['author_rules_action'])) :
241
- unset($link->settings['map authors']);
242
- foreach ($GLOBALS['fwp_post']['author_rules_name'] as $key => $name) :
 
 
 
 
 
 
 
 
 
 
 
243
  // Normalize for case and whitespace
244
  $name = strtolower(trim($name));
245
- $author_action = strtolower(trim($GLOBALS['fwp_post']['author_rules_action'][$key]));
246
 
247
  if (strlen($name) > 0) :
248
  if ('newuser' == $author_action) :
249
- $newuser_name = trim($GLOBALS['fwp_post']['author_rules_newuser'][$key]);
250
- $link->map_name_to_new_user($name, $newuser_name);
251
  else :
252
- $link->settings['map authors']['name'][$name] = $author_action;
253
  endif;
254
  endif;
255
  endforeach;
256
  endif;
257
 
258
- if (isset($GLOBALS['fwp_post']['add_author_rule_name']) and isset($GLOBALS['fwp_post']['add_author_rule_action'])) :
259
- $name = strtolower(trim($GLOBALS['fwp_post']['add_author_rule_name']));
260
- $author_action = strtolower(trim($GLOBALS['fwp_post']['add_author_rule_action']));
 
 
261
  if (strlen($name) > 0) :
262
  if ('newuser' == $author_action) :
263
- $newuser_name = trim($GLOBALS['fwp_post']['add_author_rule_newuser']);
264
- $link->map_name_to_new_user($name, $newuser_name);
265
  else :
266
- $link->settings['map authors']['name'][$name] = $author_action;
267
  endif;
268
  endif;
269
  endif;
270
-
271
- // Save settings
272
- $link->save_settings(/*reload=*/ true);
273
- $updated_link = true;
274
-
275
- // Reset, reload
276
- $link_id = $link->id;
277
- unset($link);
278
- $link = new SyndicatedLink($link_id);
279
  else :
280
- if ('newuser'==$GLOBALS['fwp_post']['unfamiliar_author']) :
281
- $newuser_name = trim($GLOBALS['fwp_post']['unfamiliar_author_newuser']);
282
- $newuser_id = fwp_insert_new_user($newuser_name);
283
- if (is_numeric($newuser_id)) :
284
- update_option('feedwordpress_unfamiliar_author', $newuser_id);
285
  else :
286
  // TODO: Add some error detection and reporting
 
287
  endif;
288
  else :
289
- update_option('feedwordpress_unfamiliar_author', $GLOBALS['fwp_post']['unfamiliar_author']);
290
  endif;
291
 
292
- if (isset($GLOBALS['fwp_post']['match_author_by_email']) and $GLOBALS['fwp_post']['match_author_by_email']=='yes') :
293
- update_option('feedwordpress_do_not_match_author_by_email', 'no');
294
- else :
295
- update_option('feedwordpress_do_not_match_author_by_email', 'yes');
296
- endif;
 
297
 
298
- if (isset($GLOBALS['fwp_post']['null_emails'])) :
299
- update_option('feedwordpress_null_email_set', $GLOBALS['fwp_post']['null_emails']);
300
  endif;
301
-
302
- $updated_link = true;
303
  endif;
304
 
305
- do_action('feedwordpress_admin_page_authors_save', $GLOBALS['fwp_post'], $authorsPage);
306
- $authorsPage->refresh_author_list();
307
- else :
308
- $updated_link = false;
309
- endif;
310
-
311
- ////////////////////////////////////////////////
312
- // Prepare settings page ///////////////////////
313
- ////////////////////////////////////////////////
314
-
315
- if ($updated_link) :
316
- ?>
317
- <div class="updated"><p>Syndicated author settings updated.</p></div>
318
- <?php elseif (!is_null($mesg)) : ?>
319
- <div class="updated"><p><?php print esc_html($mesg); ?></p></div>
320
- <?php endif;
321
-
322
- if (function_exists('add_meta_box')) :
323
- add_action(
324
- FeedWordPressCompatibility::bottom_script_hook(__FILE__),
325
- /*callback=*/ array($authorsPage, 'fix_toggles'),
326
- /*priority=*/ 10000
327
- );
328
- FeedWordPressSettingsUI::ajax_nonce_fields();
329
- endif;
330
-
331
- $authorsPage->open_sheet('Syndicated Author');
332
- ?>
333
- <div id="post-body">
334
- <?php
335
- ////////////////////////////////////////////////
336
- // Display settings boxes //////////////////////
337
- ////////////////////////////////////////////////
338
-
339
- $boxes_by_methods = array(
340
- 'syndicated_authors_box' => __('Syndicated Authors'),
341
- 'fix_authors_box' => __('Reassign Authors'),
342
- );
343
- if ($authorsPage->for_default_settings()) :
344
- unset($boxes_by_methods['fix_authors_box']);
345
- endif;
346
-
347
- foreach ($boxes_by_methods as $method => $row) :
348
- if (is_array($row)) :
349
- $id = $row['id'];
350
- $title = $row['title'];
351
- else :
352
- $id = 'feedwordpress_'.$method;
353
- $title = $row;
354
- endif;
355
-
356
- add_meta_box(
357
- /*id=*/ $id,
358
- /*title=*/ $title,
359
- /*callback=*/ array('FeedWordPressAuthorsPage', $method),
360
- /*page=*/ $authorsPage->meta_box_context(),
361
- /*context=*/ $authorsPage->meta_box_context()
362
- );
363
- endforeach;
364
- do_action('feedwordpress_admin_page_authors_meta_boxes', $authorsPage);
365
- ?>
366
- <div class="metabox-holder">
367
- <?php
368
- fwp_do_meta_boxes($authorsPage->meta_box_context(), $authorsPage->meta_box_context(), $authorsPage);
369
- ?>
370
- </div> <!-- class="metabox-holder" -->
371
- </div> <!-- id="post-body" -->
372
- <?php $authorsPage->close_sheet(); ?>
373
-
374
- <script type="text/javascript">
375
- contextual_appearance('unfamiliar-author', 'unfamiliar-author-newuser', 'unfamiliar-author-default', 'newuser', 'inline');
376
- <?php if (is_object($link) and $link->found()) : ?>
377
- <?php for ($j=1; $j<=$authorsPage->rule_count; $j++) : ?>
378
- contextual_appearance('author-rules-<?php echo $j; ?>', 'author-rules-<?php echo $j; ?>-newuser', 'author-rules-<?php echo $j; ?>-default', 'newuser', 'inline');
379
- <?php endfor; ?>
380
- contextual_appearance('add-author-rule', 'add-author-rule-newuser', 'add-author-rule-default', 'newuser', 'inline');
381
- contextual_appearance('fix-mismatch-to', 'fix-mismatch-to-newuser', null, 'newuser', 'inline');
382
- <?php else : ?>
383
- contextual_appearance('match-author-by-email', 'unless-null-email', null, 'yes', 'block', /*checkbox=*/ true);
384
- <?php endif; ?>
385
- </script>
386
- <?php
387
- } /* function fwp_authors_page () */
388
 
389
- fwp_authors_page();
 
390
 
5
  var $authorlist = NULL;
6
  var $rule_count = 0;
7
 
8
+ function FeedWordPressAuthorsPage ($link = -1) {
9
+ if (is_numeric($link) and -1 == $link) :
10
+ $link = FeedWordPressAdminPage::submitted_link();
11
+ endif;
12
+
13
  FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpressauthors', $link);
14
  $this->refresh_author_list();
15
  $this->dispatch = 'feedwordpress_author_settings';
16
  $this->filename = __FILE__;
17
+
18
+ $this->pagenames = array(
19
+ 'default' => 'Authors',
20
+ 'settings-update' => 'Syndicated Authors',
21
+ 'open-sheet' => 'Syndicated Author',
22
+ );
23
  }
24
 
25
  function refresh_author_list () {
31
  $unfamiliar = array ('create' => '','default' => '','filter' => '');
32
 
33
  if ($page->for_feed_settings()) :
34
+ $key = $this->link->setting('unfamiliar author', NULL, 'site-default');
35
  $unfamiliar['site-default'] = '';
36
  else :
37
  $key = FeedWordPress::on_unfamiliar('author');
44
  // Hey ho, let's go...
45
  ?>
46
  <table class="form-table">
47
+ <?php
48
+ if ($page->for_feed_settings()) :
49
+ $map = $this->link->setting('map authors', NULL, array());
50
+ ?>
51
+ <tr><th>Matching authors</th>
52
+ <td><p>How should FeedWordPress attribute posts from this feed to WordPress
53
+ authors?</p>
54
+ <ul class="settings">
55
+ <li><p><input type="radio" name="author_rules_name[all]" value="*"
56
+ <?php if (isset($map['name']['*'])) : $author_action = $map['name']['*']; ?>
57
+ checked="checked"
58
+ <?php else : $author_action = NULL; ?>
59
  <?php endif; ?>
60
+ /> All posts syndicated
61
+ from this feed <select class="author-rules" id="author-rules-all"
62
+ name="author_rules_action[all]" onchange="contextual_appearance('author-rules-all', 'author-rules-all-newuser', 'author-rules-all-default', 'newuser', 'inline');">
63
+ <?php foreach ($page->authorlist as $local_author_id => $local_author_name) : ?>
64
+ <option value="<?php echo $local_author_id; ?>"<?php if ($local_author_id==$author_action) : echo ' selected="selected"'; endif; ?>>are assigned to <?php echo $local_author_name; ?></option>
65
  <?php endforeach; ?>
66
+ <option value="newuser">will be assigned to a new user...</option>
67
+ <option value="filter"<?php if ('filter'==$author_action) : echo ' selected="selected"'; endif; ?>>get filtered out</option>
68
  </select>
69
+ <span class="author-rules-newuser" id="author-rules-all-newuser">named
70
+ <input type="text" name="author_rules_newuser[all]" value="" /></span></p></li>
71
+ <li><p><input type="radio" name="author_rules_name[all]" value=""
72
+ <?php if (!isset($map['name']['*'])) : ?>
73
+ checked="checked"
74
+ <?php endif; ?>
75
+ /> Attribute posts to authors based on automatic mapping rules. (Blank out a
76
+ name to delete the rule. Fill in a new name at the bottom to create a new rule.)</p>
77
 
 
 
 
 
 
 
 
 
 
78
  <table style="width: 100%">
79
  <?php
80
+ if (isset($this->link->settings['map authors'])) :
81
  ?>
82
  <?php
83
  $page->rule_count=0;
84
+ foreach ($this->link->settings['map authors'] as $author_rules) :
85
  foreach ($author_rules as $author_name => $author_action) :
86
+ if ($author_name != '*') :
87
+ $page->rule_count++;
88
  ?>
89
  <tr>
90
  <th style="text-align: left; width: 15.0em">Posts by <input type="text" name="author_rules_name[]" value="<?php echo htmlspecialchars($author_name); ?>" size="11" /></th>
91
  <td>
92
+ <select class="author-rules" id="author-rules-<?php echo $page->rule_count; ?>" name="author_rules_action[]" onchange="contextual_appearance('author-rules-<?php echo $page->rule_count; ?>', 'author-rules-<?php echo $page->rule_count; ?>-newuser', 'author-rules-<?php echo $page->rule_count; ?>-default', 'newuser', 'inline');">
93
  <?php foreach ($page->authorlist as $local_author_id => $local_author_name) : ?>
94
  <option value="<?php echo $local_author_id; ?>"<?php if ($local_author_id==$author_action) : echo ' selected="selected"'; endif; ?>>are assigned to <?php echo $local_author_name; ?></option>
95
  <?php endforeach; ?>
97
  <option value="filter"<?php if ('filter'==$author_action) : echo ' selected="selected"'; endif; ?>>get filtered out</option>
98
  </select>
99
 
100
+ <span class="author-rules-newuser" id="author-rules-<?php echo $page->rule_count; ?>-newuser">named <input type="text" name="author_rules_newuser[]" value="" /></span>
101
  </td>
102
  </tr>
103
+ <?php
104
+ endif;
105
+ endforeach;
106
  endforeach;
107
  endif;
108
  ?>
121
  <span id="add-author-rule-newuser">named <input type="text" name="add_author_rule_newuser" value="" /></span>
122
  </td>
123
  </tr>
124
+
125
+ <tr>
126
+ <th style="text-align: left; width: 15.0em">Unmatched authors</th>
127
+ <td>
128
+ <span>Authors who haven't been syndicated before</span>
129
+ <select style="max-width: 27.0em" id="unfamiliar-author" name="unfamiliar_author" onchange="contextual_appearance('unfamiliar-author', 'unfamiliar-author-newuser', 'unfamiliar-author-default', 'newuser', 'inline');">
130
+ <?php if ($page->for_feed_settings()) : ?>
131
+ <option value="site-default"<?php print $unfamiliar['site-default']; ?>>are handled according to the default for all feeds</option>
132
+ <?php endif; ?>
133
+ <option value="create"<?php print $unfamiliar['create']; ?>>will have a new author account created for them</option>
134
+ <?php foreach ($page->authorlist as $author_id => $author_name) : ?>
135
+ <option value="<?php echo $author_id; ?>"<?php print (isset($unfamiliar[$author_id]) ? $unfamiliar[$author_id] : ''); ?>>will have their posts attributed to <?php echo $author_name; ?></option>
136
+ <?php endforeach; ?>
137
+ <option value="newuser">will have their posts attributed to a user named ...</option>
138
+ <option value="filter"<?php print $unfamiliar['filter'] ?>>get filtered out</option>
139
+ </select>
140
+
141
+ <span id="unfamiliar-author-newuser"><input type="text" name="unfamiliar_author_newuser" value="" /></span></p>
142
+ </td>
143
+ </tr>
144
+ </table></li>
145
+ </ul>
146
+
147
  </td>
148
  </tr>
149
  <?php endif; ?>
196
  </table>
197
  <?php
198
  } /* FeedWordPressAuthorsPage::fix_authors_box () */
 
199
 
200
+ function display () {
201
+ $this->boxes_by_methods = array(
202
+ 'syndicated_authors_box' => __('Syndicated Authors'),
203
+ 'fix_authors_box' => __('Reassign Authors'),
204
+ );
205
+ if ($this->for_default_settings()) :
206
+ unset($this->boxes_by_methods['fix_authors_box']);
207
+ endif;
208
 
209
+ parent::display();
210
+ ?>
211
+ <script type="text/javascript">
212
+ contextual_appearance('unfamiliar-author', 'unfamiliar-author-newuser', 'unfamiliar-author-default', 'newuser', 'inline');
213
+ </script>
214
 
215
+ <?php if ($this->for_feed_settings()) : ?>
216
+ <script type="text/javascript">
217
+ jQuery('.author-rules').each ( function () {
218
+ contextual_appearance(this.id, this.id+'-newuser', this.id+'-default', 'newuser', 'inline');
219
+ } );
220
+
221
+ contextual_appearance('add-author-rule', 'add-author-rule-newuser', 'add-author-rule-default', 'newuser', 'inline');
222
+ contextual_appearance('fix-mismatch-to', 'fix-mismatch-to-newuser', null, 'newuser', 'inline');
223
+ </script>
224
+ <?php else : ?>
225
+ <script type="text/javascript">
226
+ contextual_appearance('match-author-by-email', 'unless-null-email', null, 'yes', 'block', /*checkbox=*/ true);
227
+ </script>
228
+ <?php endif;
229
+ } /* FeedWordPressAuthorsPage::display () */
230
 
231
+ function accept_POST ($post) {
232
+ if (isset($post['fix_mismatch']) and (strlen($post['fix_mismatch']) > 0)) :
233
+ $this->fix_mismatch($post);
234
+ else :
235
+ parent::accept_POST($post);
236
+ endif;
237
+ }
238
 
239
+ function fix_mismatch ($post) {
240
+ global $wpdb;
241
 
242
+ if ('newuser'==$post['fix_mismatch_to']) :
243
+ $newuser_name = trim($post['fix_mismatch_to_newuser']);
244
+ $to = fwp_insert_new_user($newuser_name);
 
245
  else :
246
+ $to = $post['fix_mismatch_to'];
247
  endif;
248
+
249
+ $from = (int) $post['fix_mismatch_from'];
250
+ if (is_numeric($from)) :
251
+ // Make a list of all the items by this author
252
+ // syndicated from this feed...
253
  $post_ids = $wpdb->get_col("
254
  SELECT {$wpdb->posts}.id
255
  FROM {$wpdb->posts}, {$wpdb->postmeta}
256
  WHERE ({$wpdb->posts}.id = {$wpdb->postmeta}.post_id)
257
  AND {$wpdb->postmeta}.meta_key = 'syndication_feed_id'
258
+ AND {$wpdb->postmeta}.meta_value = '{$this->link->id}'
259
+ AND {$wpdb->posts}.post_author = '{$from}'
260
  ");
261
 
262
  if (count($post_ids) > 0) :
263
+ $N = count($post_ids);
264
+ $posts = 'post'.(($N==1) ? '' : 's');
265
+
266
  // Re-assign them all to the correct author
267
+ if (is_numeric($to)) : // re-assign to a particular user
268
  $post_set = "(".implode(",", $post_ids).")";
269
 
270
  // Getting the revisions too, if there are any
272
 
273
  $wpdb->query("
274
  UPDATE {$wpdb->posts}
275
+ SET post_author='{$to}'
276
  WHERE ({$wpdb->posts}.id IN $post_set
277
  $parent_in_clause)
278
  ");
279
+ $this->mesg = sprintf(__("Re-assigned %d ${posts}."), $N);
280
 
281
  // ... and kill them all
282
+ elseif ('filter'==$to) :
283
  foreach ($post_ids as $post_id) :
284
  wp_delete_post($post_id);
285
+ endforeach;
286
+
287
+ $this->mesg = sprintf(__("Deleted %d ${posts}."), $N);
288
  endif;
289
  else :
290
+ $this->mesg = __("Couldn't find any posts that matched your criteria.");
291
  endif;
292
  endif;
293
+ $this->updated = false;
294
+ }
295
+
296
+ function save_settings ($post) {
297
+
298
+ if ($this->for_feed_settings()) :
299
  $alter = array ();
300
 
301
  // Unfamiliar author rule
302
+ if (isset($post["unfamiliar_author"])) :
303
+ if ('newuser'==$post['unfamiliar_author']) :
304
+ $new_name = trim($post["unfamiliar_author_newuser"]);
305
+ $this->link->map_name_to_new_user(/*name=*/ NULL, $new_name);
 
 
306
  else :
307
+ $this->link->update_setting(
308
+ "unfamiliar author",
309
+ $post['unfamiliar_author'],
310
+ 'site-default'
311
+ );
312
  endif;
313
  endif;
314
 
315
  // Handle author mapping rules
316
+ if (isset($post['author_rules_name'])
317
+ and isset($post['author_rules_action'])) :
318
+ if (isset($post['author_rules_name']['all'])) :
319
+ if (strlen($post['author_rules_name']['all']) > 0) :
320
+ $post['author_rules_name'] = array(
321
+ 'all' => $post['author_rules_name']['all'],
322
+ );
323
+
324
+ // Erase all the rest.
325
+ endif;
326
+ endif;
327
+
328
+ unset($this->link->settings['map authors']);
329
+ foreach ($post['author_rules_name'] as $key => $name) :
330
  // Normalize for case and whitespace
331
  $name = strtolower(trim($name));
332
+ $author_action = strtolower(trim($post['author_rules_action'][$key]));
333
 
334
  if (strlen($name) > 0) :
335
  if ('newuser' == $author_action) :
336
+ $new_name = trim($post['author_rules_newuser'][$key]);
337
+ $this->link->map_name_to_new_user($name, $new_name);
338
  else :
339
+ $this->link->settings['map authors']['name'][$name] = $author_action;
340
  endif;
341
  endif;
342
  endforeach;
343
  endif;
344
 
345
+ if (isset($post['add_author_rule_name'])
346
+ and isset($post['add_author_rule_action'])) :
347
+ $name = strtolower(trim($post['add_author_rule_name']));
348
+ $author_action = strtolower(trim($post['add_author_rule_action']));
349
+
350
  if (strlen($name) > 0) :
351
  if ('newuser' == $author_action) :
352
+ $new_name = trim($post['add_author_rule_newuser']);
353
+ $this->link->map_name_to_new_user($name, $new_name);
354
  else :
355
+ $this->link->settings['map authors']['name'][$name] = $author_action;
356
  endif;
357
  endif;
358
  endif;
 
 
 
 
 
 
 
 
 
359
  else :
360
+ if ('newuser'==$post['unfamiliar_author']) :
361
+ $new_name = trim($post['unfamiliar_author_newuser']);
362
+ $new_id = fwp_insert_new_user($new_name);
363
+ if (is_numeric($new_id)) :
364
+ update_option('feedwordpress_unfamiliar_author', $new_id);
365
  else :
366
  // TODO: Add some error detection and reporting
367
+ // Put WP_Error stuff into $this->mesg ?
368
  endif;
369
  else :
370
+ update_option('feedwordpress_unfamiliar_author', $post['unfamiliar_author']);
371
  endif;
372
 
373
+ update_option('feedwordpress_do_not_match_author_by_email',
374
+ (isset($post['match_author_by_email'])
375
+ and 'yes'==$post['match_author_by_email'])
376
+ ? 'no'
377
+ : 'yes'
378
+ );
379
 
380
+ if (isset($post['null_emails'])) :
381
+ update_option('feedwordpress_null_email_set', $post['null_emails']);
382
  endif;
 
 
383
  endif;
384
 
385
+ parent::save_settings($post);
386
+ $this->refresh_author_list();
387
+ }
388
+ } /* class FeedWordPressAuthorsPage */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
 
390
+ $authorsPage = new FeedWordPressAuthorsPage;
391
+ $authorsPage->display();
392
 
categories-page.php CHANGED
@@ -457,17 +457,15 @@ blank.</p></td>
457
  <td class="secondary">
458
  <h4>Site-wide <?php print $taxonomy->labels->name; ?></h4>
459
  <?php if (count($globalCats) > 0) : ?>
460
- <ul class="current-setting">
461
- <?php
462
- foreach ($globalDogs as $dog) :
463
- ?>
464
- <li><?php $cat = get_term($dog, $tax); print $cat->name; ?></li>
465
- <?php endforeach; ?>
466
- </ul>
467
- </div>
468
- <p>
469
  <?php else : ?>
470
- <p>Site-wide settings may also assign categories to syndicated
471
  posts.
472
  <?php endif; ?>
473
  Should <?php print $page->these_posts_phrase(); ?> be assigned
@@ -476,7 +474,7 @@ blank.</p></td>
476
 
477
  <ul class="settings">
478
  <li><p><label><input type="radio" name="add_global[<?php print $tax; ?>]" value="yes" <?php print $checked['yes']; ?> /> Yes. Place <?php print $page->these_posts_phrase(); ?> under all these categories.</label></p></li>
479
- <li><p><label><input type="radio" name="add_global[<?php print $tax; ?>]" value="no" <?php print $checked['no']; ?> /> No. Only use the categories I set up on the left. Do not ise the global defaults for <?php print $page->these_posts_phrase(); ?></label></p></li>
480
  </ul>
481
  </td>
482
  </tr>
457
  <td class="secondary">
458
  <h4>Site-wide <?php print $taxonomy->labels->name; ?></h4>
459
  <?php if (count($globalCats) > 0) : ?>
460
+ <ul class="current-setting">
461
+ <?php foreach ($globalDogs as $dog) : ?>
462
+ <li><?php $cat = get_term($dog, $tax); print $cat->name; ?></li>
463
+ <?php endforeach; ?>
464
+ </ul>
465
+ </div>
466
+ <p>
 
 
467
  <?php else : ?>
468
+ <p>Site-wide settings may also assign categories to syndicated
469
  posts.
470
  <?php endif; ?>
471
  Should <?php print $page->these_posts_phrase(); ?> be assigned
474
 
475
  <ul class="settings">
476
  <li><p><label><input type="radio" name="add_global[<?php print $tax; ?>]" value="yes" <?php print $checked['yes']; ?> /> Yes. Place <?php print $page->these_posts_phrase(); ?> under all these categories.</label></p></li>
477
+ <li><p><label><input type="radio" name="add_global[<?php print $tax; ?>]" value="no" <?php print $checked['no']; ?> /> No. Only use the categories I set up on the left. Do not use the global defaults for <?php print $page->these_posts_phrase(); ?></label></p></li>
478
  </ul>
479
  </td>
480
  </tr>
compatability.php CHANGED
@@ -4,7 +4,17 @@
4
  ################################################################################
5
 
6
  class FeedWordPressCompatibility {
7
- // version testing based on database schema version
 
 
 
 
 
 
 
 
 
 
8
  /*static*/ function test_version ($floor, $ceiling = null) {
9
  global $wp_db_version;
10
 
@@ -19,12 +29,23 @@ class FeedWordPressCompatibility {
19
  /*static*/ function insert_link_category ($name) {
20
  global $wpdb;
21
 
22
- $name = $wpdb->escape($name);
23
-
24
  // WordPress 2.3+ term/taxonomy API
25
  $term = wp_insert_term($name, 'link_category');
26
- $cat_id = $term['term_id'];
27
-
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  // Return newly-created category ID
29
  return $cat_id;
30
  } /* FeedWordPressCompatibility::insert_link_category () */
@@ -122,6 +143,38 @@ if (!function_exists('disabled')) {
122
  }
123
  } /* if */
124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  if (!function_exists('term_exists')) {
126
  // Fucking WordPress 3.0 wordsmithing.
127
  function term_exists ( $term, $taxonomy = '', $parent = 0 ) {
@@ -140,7 +193,7 @@ function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selec
140
  $taxonomy = (isset($params['taxonomy']) ? $params['taxonomy'] : 'category');
141
  endif;
142
 
143
- $walker = new FeedWordPress_Walker_Category_Checklist;
144
  $walker->set_prefix($prefix);
145
  $walker->set_taxonomy($taxonomy);
146
  wp_terms_checklist(/*post_id=*/ $post_id, array(
4
  ################################################################################
5
 
6
  class FeedWordPressCompatibility {
7
+
8
+ /**
9
+ * FeedWordPressCompatibility::test_version: test version of WordPress
10
+ * based on the database schema version.
11
+ *
12
+ * @param int $floor The minimum version necessary
13
+ * @param mixed $ceiling The first version that is too high. If omitted
14
+ * or NULL, no version is too high.
15
+ * @return bool TRUE if within the range of versions, FALSE if too low
16
+ * or too high.
17
+ */
18
  /*static*/ function test_version ($floor, $ceiling = null) {
19
  global $wp_db_version;
20
 
29
  /*static*/ function insert_link_category ($name) {
30
  global $wpdb;
31
 
 
 
32
  // WordPress 2.3+ term/taxonomy API
33
  $term = wp_insert_term($name, 'link_category');
34
+
35
+ // OK: returned array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id)
36
+ if (!is_wp_error($term)) :
37
+ $cat_id = $term['term_id'];
38
+
39
+ // Error: term with this name already exists. Well, let's use that then.
40
+ elseif ($term->get_error_code() == 'term_exists') :
41
+ // Already-existing term ID is returned in data field
42
+ $cat_id = $term->get_error_data('term_exists');
43
+
44
+ // Error: another kind of error, harder to recover from. Return WP_Error.
45
+ else :
46
+ $cat_id = $term;
47
+ endif;
48
+
49
  // Return newly-created category ID
50
  return $cat_id;
51
  } /* FeedWordPressCompatibility::insert_link_category () */
143
  }
144
  } /* if */
145
 
146
+ // Compat
147
+
148
+ if (!function_exists('set_post_field')) {
149
+
150
+ /**
151
+ * Update data from a post field based on Post ID
152
+ *
153
+ * Examples of the post field will be, 'post_type', 'post_status', 'post_content', etc.
154
+ *
155
+ * The context values are based off of the taxonomy filter functions and
156
+ * supported values are found within those functions.
157
+ *
158
+ * @uses sanitize_post_field()
159
+ *
160
+ * @param string $field Post field name
161
+ * @param mixed $value New value for post field
162
+ * @param id $post Post ID
163
+ * @return bool Result of UPDATE query
164
+ *
165
+ * Included under terms of GPL from WordPress Ticket #10946 <http://core.trac.wordpress.org/attachment/ticket/10946/post.php.diff>
166
+ */
167
+ function set_post_field ($field, $value, $post_id) {
168
+ global $wpdb;
169
+
170
+ $post_id = absint($post_id);
171
+ // sigh ... when FWP is active, I need to avoid avoid_kses_munge
172
+ // $value = sanitize_post_field($field, $value, $post_id, 'db');
173
+ return $wpdb->update($wpdb->posts, array($field => $value), array('ID' => $post_id));
174
+ } /* function set_post_field () */
175
+
176
+ } /* if */
177
+
178
  if (!function_exists('term_exists')) {
179
  // Fucking WordPress 3.0 wordsmithing.
180
  function term_exists ( $term, $taxonomy = '', $parent = 0 ) {
193
  $taxonomy = (isset($params['taxonomy']) ? $params['taxonomy'] : 'category');
194
  endif;
195
 
196
+ $walker = new FeedWordPress_Walker_Category_Checklist($params);
197
  $walker->set_prefix($prefix);
198
  $walker->set_taxonomy($taxonomy);
199
  wp_terms_checklist(/*post_id=*/ $post_id, array(
diagnostics-page.php CHANGED
@@ -82,6 +82,24 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
82
  endif;
83
  update_option('feedwordpress_diagnostics_show', $post['diagnostics_show']);
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  $this->updated = true; // Default update message
86
  endif;
87
  } /* FeedWordPressDiagnosticsPage::accept_POST () */
@@ -92,6 +110,16 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
92
 
93
  $diagnostics_output = get_option('feedwordpress_diagnostics_output', array());
94
 
 
 
 
 
 
 
 
 
 
 
95
  // Hey ho, let's go...
96
  ?>
97
  <table class="edit-form">
@@ -116,21 +144,60 @@ testing but absolutely inappropriate for a production server.</p>
116
  <li><input type="checkbox" name="diagnostics_output[]" value="admin_footer" <?php print (in_array('admin_footer', $diagnostics_output) ? ' checked="checked"' : ''); ?> /> Display in WordPress admin footer</label></li>
117
  <li><input type="checkbox" name="diagnostics_output[]" value="echo" <?php print (in_array('echo', $diagnostics_output) ? ' checked="checked"' : ''); ?> /> Echo in web browser as they are issued</label></li>
118
  <li><input type="checkbox" name="diagnostics_output[]" value="echo_in_cronjob" <?php print (in_array('echo_in_cronjob', $diagnostics_output) ? ' checked="checked"' : ''); ?> /> Echo to output when they are issued during an update cron job</label></li>
119
- <li><input type="checkbox" name="diagnostics_output[]" value="email" <?php print (in_array('email', $diagnostics_output) ? ' checked="checked"' : ''); ?> /> Send a daily email digest to the site administrator</label></li>
 
 
 
 
 
 
 
120
  </ul></td>
121
  </tr>
122
  </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  <?php
124
  } /* FeedWordPressDiagnosticsPage::diagnostics_box () */
125
 
126
  /*static*/ function updates_box ($page, $box = NULL) {
127
- $checked = array(
128
- 'updated_feeds' => '', 'updated_feeds:errors' => '',
129
- 'updated_feeds:errors:persistent' => '',
130
- "syndicated_posts" => '', 'syndicated_posts:meta_data' => '',
131
- 'feed_items' => '',
132
- 'memory_usage' => '',
133
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
134
 
135
  $diagnostics_show = get_option('feedwordpress_diagnostics_show', array());
136
  if (is_array($diagnostics_show)) : foreach ($diagnostics_show as $thingy) :
@@ -140,25 +207,21 @@ testing but absolutely inappropriate for a production server.</p>
140
  // Hey ho, let's go...
141
  ?>
142
  <table class="edit-form">
143
- <tr>
144
- <th scope="row">Update diagnostics:</th>
145
- <td><p>Show a diagnostic message...</p>
146
- <ul class="options">
147
- <li><label><input type="checkbox" name="diagnostics_show[]" value="updated_feeds" <?php print $checked['updated_feeds']; ?> /> as each feed checked for updates</label></li>
148
- <li><label><input type="checkbox" name="diagnostics_show[]" value="updated_feeds:errors:persistent" <?php print $checked['updated_feeds:errors:persistent'] ?> /> when FeedWordPress encounters repeated errors while checking a feed for updates</label></li>
149
- <li><label><input type="checkbox" name="diagnostics_show[]" value="updated_feeds:errors" <?php print $checked['updated_feeds:errors']; ?> /> any time FeedWordPress encounters any errors while checking a feed for updates</label></li>
150
- <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>
151
- <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>
152
- <li><label><input type="checkbox" name="diagnostics_show[]" value="memory_usage" <?php print $checked['memory_usage']; ?> /> indicating how much memory was used</label></li>
153
- </ul></td>
154
- </tr>
155
- <tr>
156
- <th>Syndicated post details:</th>
157
- <td><p>Show a diagnostic message...</p>
158
- <ul class="options">
159
- <li><label><input type="checkbox" name="diagnostics_show[]" value="syndicated_posts:meta_data" <?php print $checked['syndicated_posts:meta_data']; ?> /> as syndication meta-data is added on the post</label></li>
160
- </ul></td>
161
- </tr>
162
  </table>
163
  <?php
164
  } /* FeedWordPressDiagnosticsPage::updates_box () */
82
  endif;
83
  update_option('feedwordpress_diagnostics_show', $post['diagnostics_show']);
84
 
85
+ if ($post['diagnostics_show']
86
+ and in_array('updated_feeds:errors:persistent', $post['diagnostics_show'])) :
87
+ update_option('feedwordpress_diagnostics_persistent_errors_hours', (int) $post['diagnostics_persistent_error_hours']);
88
+ else :
89
+ delete_option('feedwordpress_diagnostics_persistent_errors_hours');
90
+ endif;
91
+
92
+ if (in_array('email', $post['diagnostics_output'])) :
93
+ $ded = $post['diagnostics_email_destination'];
94
+ if ('mailto'==$ded) :
95
+ $ded .= ':'.$post['diagnostics_email_destination_address'];
96
+ endif;
97
+
98
+ update_option('feedwordpress_diagnostics_email_destination', $ded);
99
+ else :
100
+ delete_option('feedwordpress_diagnostics_email_destination');
101
+ endif;
102
+
103
  $this->updated = true; // Default update message
104
  endif;
105
  } /* FeedWordPressDiagnosticsPage::accept_POST () */
110
 
111
  $diagnostics_output = get_option('feedwordpress_diagnostics_output', array());
112
 
113
+ $users = fwp_author_list();
114
+
115
+ $ded = get_option('feedwordpress_diagnostics_email_destination', 'admins');
116
+
117
+ if (preg_match('/^mailto:(.*)$/', $ded, $ref)) :
118
+ $ded_addy = $ref[1];
119
+ else :
120
+ $ded_addy = NULL;
121
+ endif;
122
+
123
  // Hey ho, let's go...
124
  ?>
125
  <table class="edit-form">
144
  <li><input type="checkbox" name="diagnostics_output[]" value="admin_footer" <?php print (in_array('admin_footer', $diagnostics_output) ? ' checked="checked"' : ''); ?> /> Display in WordPress admin footer</label></li>
145
  <li><input type="checkbox" name="diagnostics_output[]" value="echo" <?php print (in_array('echo', $diagnostics_output) ? ' checked="checked"' : ''); ?> /> Echo in web browser as they are issued</label></li>
146
  <li><input type="checkbox" name="diagnostics_output[]" value="echo_in_cronjob" <?php print (in_array('echo_in_cronjob', $diagnostics_output) ? ' checked="checked"' : ''); ?> /> Echo to output when they are issued during an update cron job</label></li>
147
+ <li><input type="checkbox" name="diagnostics_output[]" value="email" <?php print (in_array('email', $diagnostics_output) ? ' checked="checked"' : ''); ?> /> Send a daily email digest to:</label> <select name="diagnostics_email_destination" id="diagnostics-email-destination" size="1">
148
+ <option value="admins"<?php if ('admins'==$ded) : ?> selected="selected"<?php endif; ?>>the site administrators</option>
149
+ <?php foreach ($users as $id => $name) : ?>
150
+ <option value="user:<?php print (int) $id; ?>"<?php if (sprintf('user:%d', (int) $id)==$ded) : ?> selected="selected"<?php endif; ?>><?php print esc_html($name); ?></option>
151
+ <?php endforeach; ?>
152
+ <option value="mailto"<?php if (!is_null($ded_addy)) : ?> selected="selected"<?php endif; ?>>another e-mail address...</option>
153
+ </select>
154
+ <input type="email" id="diagnostics-email-destination-address" name="diagnostics_email_destination_address" value="<?php print $ded_addy; ?>" placeholder="email address" /></li>
155
  </ul></td>
156
  </tr>
157
  </table>
158
+
159
+ <script type="text/javascript">
160
+ contextual_appearance(
161
+ 'diagnostics-email-destination',
162
+ 'diagnostics-email-destination-address',
163
+ 'diagnostics-email-destination-default',
164
+ 'mailto',
165
+ 'inline'
166
+ );
167
+ jQuery('#diagnostics-email-destination').change ( function () {
168
+ contextual_appearance(
169
+ 'diagnostics-email-destination',
170
+ 'diagnostics-email-destination-address',
171
+ 'diagnostics-email-destination-default',
172
+ 'mailto',
173
+ 'inline'
174
+ );
175
+ } );
176
+ </script>
177
  <?php
178
  } /* FeedWordPressDiagnosticsPage::diagnostics_box () */
179
 
180
  /*static*/ function updates_box ($page, $box = NULL) {
181
+ $hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
182
+ $fields = apply_filters('feedwordpress_diagnostics', array(
183
+ 'Update Diagnostics' => array(
184
+ 'updated_feeds' => 'as each feed checked for updates',
185
+ 'updated_feeds:errors:persistent' => 'when attempts to update a feed have resulted in errors</label> <label>for at least <input type="number" min="1" max="360" step="1" name="diagnostics_persistent_error_hours" value="'.$hours.'" /> hours',
186
+ 'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
187
+ 'syndicated_posts' => 'as each syndicated post is added to the database',
188
+ 'feed_items' => 'as each syndicated item is considered on the feed',
189
+ 'memory_usage' => 'indicating how much memory was used',
190
+ ),
191
+ 'Syndicated Post Details' => array(
192
+ 'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
193
+ ),
194
+ ), $page);
195
+
196
+ foreach ($fields as $section => $items) :
197
+ foreach ($items as $key => $label) :
198
+ $checked[$key] = '';
199
+ endforeach;
200
+ endforeach;
201
 
202
  $diagnostics_show = get_option('feedwordpress_diagnostics_show', array());
203
  if (is_array($diagnostics_show)) : foreach ($diagnostics_show as $thingy) :
207
  // Hey ho, let's go...
208
  ?>
209
  <table class="edit-form">
210
+ <?php foreach ($fields as $section => $ul) : ?>
211
+ <tr>
212
+ <th scope="row"><?php print esc_html($section); ?>:</th>
213
+ <td><p>Show a diagnostic message...</p>
214
+ <ul class="options">
215
+ <?php foreach ($ul as $key => $label) : ?>
216
+ <li><label><input
217
+ type="checkbox" name="diagnostics_show[]"
218
+ value="<?php print esc_html($key); ?>"
219
+ <?php print $checked[$key]; ?> />
220
+ <?php print $label; ?></label></li>
221
+ <?php endforeach; ?>
222
+ </ul></td>
223
+ </tr>
224
+ <?php endforeach; ?>
 
 
 
 
225
  </table>
226
  <?php
227
  } /* FeedWordPressDiagnosticsPage::updates_box () */
feedfinder.class.php CHANGED
@@ -165,7 +165,7 @@ class FeedFinder {
165
  // Use WordPress API function
166
  $client = wp_remote_request($this->uri, array(
167
  'headers' => $headers,
168
- 'timeout' => FEEDWORDPRESS_FETCH_TIME_OUT,
169
  ));
170
 
171
  $this->_response = $client;
165
  // Use WordPress API function
166
  $client = wp_remote_request($this->uri, array(
167
  'headers' => $headers,
168
+ 'timeout' => FeedWordPress::fetch_timeout(),
169
  ));
170
 
171
  $this->_response = $client;
feeds-page.php CHANGED
@@ -47,31 +47,10 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
47
  );
48
  var $updatedPosts = NULL;
49
 
50
- /**
51
- * Constructs the Feeds page object
52
- *
53
- * @param mixed $link An object of class {@link SyndicatedLink} if created for one feed's settings, NULL if created for global default settings
54
- */
55
- function FeedWordPressFeedsPage ($link = -1) {
56
- if (is_numeric($link) and -1 == $link) :
57
- $link = FeedWordPressAdminPage::submitted_link();
58
- endif;
59
-
60
- FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpressfeeds', $link);
61
-
62
- $this->dispatch = 'feedwordpress_admin_page_feeds';
63
- $this->pagenames = array(
64
- 'default' => 'Feeds',
65
- 'settings-update' => 'Syndicated feed',
66
- 'open-sheet' => 'Feed and Update',
67
- );
68
- $this->filename = __FILE__;
69
- $this->updatedPosts = new UpdatedPostsControl($this);
70
- } /* FeedWordPressFeedsPage constructor */
71
-
72
  var $special_settings = array ( /* Regular expression syntax is OK here */
73
  'cats',
74
  'cat_split',
 
75
  'freeze updates',
76
  'hardcode name',
77
  'hardcode url',
@@ -84,6 +63,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
84
  'ping status',
85
  'post status',
86
  'postmeta',
 
87
  'resolve relative',
88
  'syndicated post type',
89
  'tags',
@@ -91,12 +71,37 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
91
  'unfamliar categories', /* Deprecated */
92
  'unfamiliar category',
93
  'unfamiliar post_tag',
 
94
  'update/.*',
95
  'feed/.*',
96
  'link/.*',
97
  'match/.*',
98
  );
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  function display () {
101
  global $fwp_post;
102
  global $post_source;
@@ -106,6 +111,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
106
  'global_feeds_box' => __('Update Scheduling'),
107
  'updated_posts_box' => __('Updated Posts'),
108
  'custom_settings_box' => __('Custom Feed Settings (for use in templates)'),
 
109
  );
110
  if ($this->for_default_settings()) :
111
  unset($this->boxes_by_methods['custom_settings_box']);
@@ -298,8 +304,47 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
298
  return sprintf(__($caption), $updateWindow);
299
  } /* FeedWordPressFeedsPage::update_window_currently () */
300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  function feed_information_box ($page, $box = NULL) {
302
  global $wpdb;
 
 
 
 
 
303
  if ($page->for_feed_settings()) :
304
  $info['name'] = esc_html($page->link->link->link_name);
305
  $info['description'] = esc_html($page->link->link->link_description);
@@ -353,7 +398,69 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
353
  <td><a href="<?php echo esc_html($rss_url); ?>"><?php echo esc_html($rss_url); ?></a>
354
  (<a href="<?php echo FEEDVALIDATOR_URI; ?>?url=<?php echo urlencode($rss_url); ?>"
355
  title="Check feed &lt;<?php echo esc_html($rss_url); ?>&gt; for validity">validate</a>)
356
- <input type="submit" name="feedfinder" value="switch &rarr;" style="font-size:smaller" /></td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
  </tr>
358
 
359
  <?php
@@ -735,6 +842,20 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
735
 
736
  function save_settings ($post) {
737
  if ($this->for_feed_settings()) :
 
 
 
 
 
 
 
 
 
 
 
 
 
 
738
  // custom feed settings first
739
  foreach ($post['notes'] as $mn) :
740
  $mn['key0'] = (isset($mn['key0']) ? trim($mn['key0']) : NULL);
@@ -803,6 +924,20 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
803
  $hardcode = (isset($post["hardcode_{$what}"]) ? $post["hardcode_{$what}"] : 'yes');
804
  update_option("feedwordpress_hardcode_{$what}", $hardcode);
805
  endforeach;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
806
  endif;
807
 
808
  $this->updatedPosts->accept_POST($post);
47
  );
48
  var $updatedPosts = NULL;
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  var $special_settings = array ( /* Regular expression syntax is OK here */
51
  'cats',
52
  'cat_split',
53
+ 'fetch timeout',
54
  'freeze updates',
55
  'hardcode name',
56
  'hardcode url',
63
  'ping status',
64
  'post status',
65
  'postmeta',
66
+ 'query parameters',
67
  'resolve relative',
68
  'syndicated post type',
69
  'tags',
71
  'unfamliar categories', /* Deprecated */
72
  'unfamiliar category',
73
  'unfamiliar post_tag',
74
+ 'add/.*',
75
  'update/.*',
76
  'feed/.*',
77
  'link/.*',
78
  'match/.*',
79
  );
80
 
81
+ /**
82
+ * Constructs the Feeds page object
83
+ *
84
+ * @param mixed $link An object of class {@link SyndicatedLink} if created for one feed's settings, NULL if created for global default settings
85
+ */
86
+ function FeedWordPressFeedsPage ($link = -1) {
87
+ if (is_numeric($link) and -1 == $link) :
88
+ $link = FeedWordPressAdminPage::submitted_link();
89
+ endif;
90
+
91
+ FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpressfeeds', $link);
92
+
93
+ $this->dispatch = 'feedwordpress_admin_page_feeds';
94
+ $this->pagenames = array(
95
+ 'default' => 'Feeds',
96
+ 'settings-update' => 'Syndicated feed',
97
+ 'open-sheet' => 'Feed and Update',
98
+ );
99
+ $this->filename = __FILE__;
100
+ $this->updatedPosts = new UpdatedPostsControl($this);
101
+
102
+ $this->special_settings = apply_filters('syndicated_feed_special_settings', $this->special_settings, $this);
103
+ } /* FeedWordPressFeedsPage constructor */
104
+
105
  function display () {
106
  global $fwp_post;
107
  global $post_source;
111
  'global_feeds_box' => __('Update Scheduling'),
112
  'updated_posts_box' => __('Updated Posts'),
113
  'custom_settings_box' => __('Custom Feed Settings (for use in templates)'),
114
+ 'fetch_settings_box' => __('Settings for Fetching Feeds (Advanced)'),
115
  );
116
  if ($this->for_default_settings()) :
117
  unset($this->boxes_by_methods['custom_settings_box']);
304
  return sprintf(__($caption), $updateWindow);
305
  } /* FeedWordPressFeedsPage::update_window_currently () */
306
 
307
+ function fetch_timeout_setting ($setting, $defaulted, $params) {
308
+ $timeout = intval($this->setting('fetch timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT));
309
+
310
+ if ($this->for_feed_settings()) :
311
+ $article = 'this';
312
+ else :
313
+ $article = 'a';
314
+ endif;
315
+ ?>
316
+ <p>Wait no more than
317
+ than <input name="fetch_timeout" type="number" min="0" size="3" value="<?php print $timeout; ?>" />
318
+ second(s) when trying to fetch <?php print $article; ?> feed to check for updates.</p>
319
+ <p>If <?php print $article; ?> source's web server does not respond before time runs
320
+ out, FeedWordPress will skip over the source and try again during
321
+ the next update cycle.</p>
322
+ <?php
323
+ }
324
+ function fetch_timeout_setting_value ($setting, $defaulted, $params) {
325
+ print number_format(intval($setting)) . " " . (($setting==1) ? "second" : "seconds");
326
+ }
327
+
328
+ function fetch_settings_box ($page, $box = NULL) {
329
+ $this->setting_radio_control(
330
+ 'fetch timeout', 'fetch_timeout',
331
+ array(&$this, 'fetch_timeout_setting'),
332
+ array(
333
+ 'global-setting-default' => FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT,
334
+ 'input-name' => 'fetch_timeout',
335
+ 'default-input-name' => 'fetch_timeout_default',
336
+ 'labels' => array(&$this, 'fetch_timeout_setting_value'),
337
+ )
338
+ );
339
+ } /* FeedWordPressFeedsPage::fetch_settings_box () */
340
+
341
  function feed_information_box ($page, $box = NULL) {
342
  global $wpdb;
343
+ $link_rss_params = maybe_unserialize($page->setting('query parameters', ''));
344
+ if (!is_array($link_rss_params)) :
345
+ $link_rss_params = array();
346
+ endif;
347
+
348
  if ($page->for_feed_settings()) :
349
  $info['name'] = esc_html($page->link->link->link_name);
350
  $info['description'] = esc_html($page->link->link->link_description);
398
  <td><a href="<?php echo esc_html($rss_url); ?>"><?php echo esc_html($rss_url); ?></a>
399
  (<a href="<?php echo FEEDVALIDATOR_URI; ?>?url=<?php echo urlencode($rss_url); ?>"
400
  title="Check feed &lt;<?php echo esc_html($rss_url); ?>&gt; for validity">validate</a>)
401
+ <input type="submit" name="feedfinder" value="switch &rarr;" style="font-size:smaller" />
402
+
403
+ <table id="link-rss-params">
404
+ <tbody>
405
+ <?php
406
+ $link_rss_params['new'] = array('', '');
407
+ $i = 0;
408
+ foreach ($link_rss_params as $index => $pair) :
409
+ ?>
410
+ <tr class="link-rss-params-row" id="link-rss-params-<?php print $index; ?>">
411
+ <td><label>Parameter: <input type="text" class="link_params_key"
412
+ name="link_rss_params_key[<?php print $index; ?>]" value="<?php print esc_html($pair[0]); ?>"
413
+ size="5" style="width: 5em" placeholder="name" /></label></td>
414
+ <td class="link-rss-params-value-cell"><label class="link_params_value_label">= <input type="text" class="link_params_value"
415
+ name="link_rss_params_value[<?php print $index; ?>]" value="<?php print esc_html($pair[1]); ?>"
416
+ size="8" placeholder="value" /></label></td>
417
+ </tr>
418
+ <?php
419
+ $i++;
420
+ endforeach;
421
+ ?>
422
+ </tbody>
423
+ </table>
424
+
425
+ <div><input type="hidden" id="link-rss-params-num" name="link_rss_params_num" value="<?php print $i; ?>" /></div>
426
+
427
+ <script type="text/javascript">
428
+ function linkParamsRowRemove (element) {
429
+ jQuery(element).closest('tr').fadeOut('slow', function () {
430
+ jQuery(this).remove();
431
+ } );
432
+ }
433
+
434
+ jQuery('<td><a href="#" class="add-remove link-rss-params-remove"><span class="x">(X)</span> Remove</a></td>').insertAfter('.link-rss-params-value-cell');
435
+
436
+ jQuery('#link-rss-params-new').hide();
437
+ jQuery('<a class="add-remove" id="link-rss-params-add" href="#">+ Add a query parameter</a>').insertAfter('#link-rss-params');
438
+ jQuery('#link-rss-params-add').click( function () {
439
+ var next = jQuery('#link-rss-params-num').val();
440
+ var newRow = jQuery('#link-rss-params-new').clone().attr('id', 'link-rss-params-'+next);
441
+ newRow.find('.link_params_key').attr('name', 'link_rss_params_key['+next+']');
442
+ newRow.find('.link_params_value').attr('name', 'link_rss_params_value['+next+']');
443
+
444
+ newRow.find('.link-rss-params-remove').click( function () {
445
+ linkParamsRowRemove(this);
446
+ return false;
447
+ } );
448
+
449
+ newRow.appendTo('#link-rss-params');
450
+ newRow.show();
451
+
452
+ // Update counter for next row.
453
+ next++;
454
+ jQuery('#link-rss-params-num').val(next);
455
+
456
+ return false;
457
+ } );
458
+ jQuery('.link-rss-params-remove').click( function () {
459
+ linkParamsRowRemove(this);
460
+ return false;
461
+ } );
462
+ </script>
463
+ </td>
464
  </tr>
465
 
466
  <?php
842
 
843
  function save_settings ($post) {
844
  if ($this->for_feed_settings()) :
845
+ if (isset($post['link_rss_params_key'])) :
846
+ $qp = array();
847
+ foreach ($post['link_rss_params_key'] as $index => $key) :
848
+ if (strlen($key) > 0) :
849
+ if (isset($post['link_rss_params_value'][$index])
850
+ and strlen($post['link_rss_params_value'][$index])) :
851
+ $value = $post['link_rss_params_value'][$index];
852
+ $qp[] = array($key, $value);
853
+ endif;
854
+ endif;
855
+ endforeach;
856
+ $this->update_setting('query parameters', serialize($qp));
857
+ endif;
858
+
859
  // custom feed settings first
860
  foreach ($post['notes'] as $mn) :
861
  $mn['key0'] = (isset($mn['key0']) ? trim($mn['key0']) : NULL);
924
  $hardcode = (isset($post["hardcode_{$what}"]) ? $post["hardcode_{$what}"] : 'yes');
925
  update_option("feedwordpress_hardcode_{$what}", $hardcode);
926
  endforeach;
927
+
928
+ endif;
929
+
930
+ if (isset($post['fetch_timeout'])) :
931
+ if (isset($post['fetch_timeout_default']) and $post['fetch_timeout_default']=='yes') :
932
+ $timeout = NULL;
933
+ else :
934
+ $timeout = $post['fetch_timeout'];
935
+ endif;
936
+
937
+ if (is_int($timeout)) :
938
+ $timeout = intval($timeout);
939
+ endif;
940
+ $this->update_setting('fetch timeout', $timeout);
941
  endif;
942
 
943
  $this->updatedPosts->accept_POST($post);
feedtime.class.php CHANGED
@@ -103,13 +103,17 @@ class FeedTime {
103
  if ( isset($match[15]) and $match[15] == 'Z' ) :
104
  # zulu time, aka GMT
105
  else :
106
- $tz_mod = $match[12];
107
- $tz_hour = $match[13];
108
- $tz_min = $match[14];
109
 
110
  # zero out the variables
111
- if ( ! $tz_hour ) { $tz_hour = 0; }
112
- if ( ! $tz_min ) { $tz_min = 0; }
 
 
 
 
113
 
114
  $offset_secs = (($tz_hour*60)+$tz_min)*60;
115
 
103
  if ( isset($match[15]) and $match[15] == 'Z' ) :
104
  # zulu time, aka GMT
105
  else :
106
+ $tz_mod = (isset($match[12]) ? $match[12] : NULL);
107
+ $tz_hour = (isset($match[13]) ? $match[13] : NULL);
108
+ $tz_min = (isset($match[14]) ? $match[14] : NULL);
109
 
110
  # zero out the variables
111
+ if ( is_null($tz_hour) ) :
112
+ $offset = (int) get_option('gmt_offset');
113
+ $tz_hour = abs($offset);
114
+ $tz_mod = ((abs($offset) != $offset) ? '-' : '+');
115
+ endif;
116
+ if ( is_null($tz_min) ) : $tz_min = 0; endif;
117
 
118
  $offset_secs = (($tz_hour*60)+$tz_min)*60;
119
 
feedwordpress-elements.css CHANGED
@@ -379,3 +379,36 @@ table.twofer td.secondary { padding-left: 10px; width: 30%; }
379
  background-color: #FFFFD0;
380
  }
381
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  background-color: #FFFFD0;
380
  }
381
 
382
+ #feedwordpress-admin-feeds .add-remove, .feedwordpress-admin .remove-it {
383
+ padding-left: 1.5em;
384
+ font-size: 0.80em;
385
+ text-transform: uppercase;
386
+ text-decoration: none !important;
387
+ vertical-align: middle;
388
+ }
389
+
390
+ #feedwordpress-admin-feeds .link-rss-params-row { vertical-align: middle; }
391
+ #feedwordpress-admin-feeds .link-rss-params-remove, .feedwordpress-admin .remove-it {
392
+ display: block;
393
+ padding-left: 0em !important;
394
+ margin-top: 7px;
395
+ color: #777;
396
+ }
397
+
398
+ #feedwordpress-admin-feeds .link-rss-params-remove:hover, .feedwordpress-admin .remove-it:hover {
399
+ color: #aa3030;
400
+ }
401
+
402
+ #feedwordpress-admin-feeds .link-rss-params-remove .x, .feedwordpress-admin .remove-it .x {
403
+ cursor: pointer;
404
+ display: block;
405
+ float: left;
406
+ width: 10px; height: 10px;
407
+ margin-right: 2px;
408
+ overflow: hidden;
409
+ text-indent: -9999px;
410
+ }
411
+
412
+
413
+ #feedwordpress-admin-feeds #link-rss-params td { width: auto !important; }
414
+
feedwordpress-elements.js CHANGED
@@ -448,7 +448,7 @@ jQuery(document).ready(function($){
448
  'change',
449
  function () { this.form.submit(); }
450
  );
451
- $('#fwpfs-container .button').css( 'display', 'none' );
452
 
453
  $('table.twofer td.active input[type="radio"], table.twofer td.inactive input[type="radio"]').each( function () {
454
  $(this).click( function () {
448
  'change',
449
  function () { this.form.submit(); }
450
  );
451
+ $('#fwpfs-button').css( 'display', 'none' );
452
 
453
  $('table.twofer td.active input[type="radio"], table.twofer td.inactive input[type="radio"]').each( function () {
454
  $(this).click( function () {
feedwordpress-walker-category-checklist.class.php CHANGED
@@ -12,8 +12,13 @@ require_once(ABSPATH.'/wp-admin/includes/template.php');
12
 
13
  class FeedWordPress_Walker_Category_Checklist extends Walker_Category_Checklist {
14
  var $prefix = ''; var $taxonomy = 'category';
15
- function FeedWordPress_Walker_Category_Checklist () {
 
16
  $this->set_taxonomy('category');
 
 
 
 
17
  }
18
 
19
  function set_prefix ($prefix) {
@@ -29,7 +34,9 @@ class FeedWordPress_Walker_Category_Checklist extends Walker_Category_Checklist
29
  $taxonomy = 'category';
30
  endif;
31
 
32
- if ($taxonomy=='category') :
 
 
33
  $name = 'post_category';
34
  else :
35
  $name = 'tax_input['.$taxonomy.']';
12
 
13
  class FeedWordPress_Walker_Category_Checklist extends Walker_Category_Checklist {
14
  var $prefix = ''; var $taxonomy = 'category';
15
+ var $checkbox_name = NULL;
16
+ function FeedWordPress_Walker_Category_Checklist ($params = array()) {
17
  $this->set_taxonomy('category');
18
+
19
+ if (isset($params['checkbox_name'])) :
20
+ $this->checkbox_name = $params['checkbox_name'];
21
+ endif;
22
  }
23
 
24
  function set_prefix ($prefix) {
34
  $taxonomy = 'category';
35
  endif;
36
 
37
+ if (!is_null($this->checkbox_name)) :
38
+ $name = $this->checkbox_name;
39
+ elseif ($taxonomy=='category') :
40
  $name = 'post_category';
41
  else :
42
  $name = 'tax_input['.$taxonomy.']';
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.0905
7
  Author: Charles Johnson
8
  Author URI: http://radgeek.com/
9
  License: GPL
@@ -11,7 +11,7 @@ License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
- * @version 2010.0905
15
  */
16
 
17
  # This uses code derived from:
@@ -34,7 +34,7 @@ License: GPL
34
 
35
  # -- Don't change these unless you know what you're doing...
36
 
37
- define ('FEEDWORDPRESS_VERSION', '2010.0905');
38
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
39
 
40
  if (!defined('FEEDWORDPRESS_BLEG')) :
@@ -86,13 +86,13 @@ if (FEEDWORDPRESS_DEBUG) :
86
  // used for more than testing purposes!
87
  define('FEEDWORDPRESS_CACHE_AGE', 1);
88
  define('FEEDWORDPRESS_CACHE_LIFETIME', 1);
89
- define('FEEDWORDPRESS_FETCH_TIME_OUT', 60);
90
  else :
91
  // Hold onto data all day for conditional GET purposes,
92
  // but consider it stale after 1 min (requiring a conditional GET)
93
  define('FEEDWORDPRESS_CACHE_LIFETIME', 24*60*60);
94
  define('FEEDWORDPRESS_CACHE_AGE', 1*60);
95
- define('FEEDWORDPRESS_FETCH_TIME_OUT', 10);
96
  endif;
97
 
98
  // Use our the cache settings that we want.
@@ -105,7 +105,9 @@ if (!class_exists('SimplePie')) :
105
  endif;
106
  require_once(ABSPATH . WPINC . '/class-feed.php');
107
 
108
- require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
 
 
109
 
110
  require_once(dirname(__FILE__) . '/admin-ui.php');
111
  require_once(dirname(__FILE__) . '/feedwordpresssyndicationpage.class.php');
@@ -118,7 +120,10 @@ require_once(dirname(__FILE__) . '/feedwordpress-content-type-sniffer.class.php'
118
 
119
  // Magic quotes are just about the stupidest thing ever.
120
  if (is_array($_POST)) :
121
- $fwp_post = stripslashes_deep($_POST);
 
 
 
122
  endif;
123
 
124
  // Get the path relative to the plugins directory in which FWP is stored
@@ -253,7 +258,11 @@ class FeedWordPressDiagnostic {
253
  'updated_feeds:errors',
254
  "Feed Error: [${url}] update returned error: $mesg"
255
  );
256
- if ($error['ts'] > $error['since']) :
 
 
 
 
257
  $since = date('r', $error['since']);
258
  $mostRecent = date('r', $error['ts']);
259
  FeedWordPress::diagnostic(
@@ -270,7 +279,8 @@ class FeedWordPressDiagnostic {
270
  $users = get_users_of_blog($id);
271
  $recipients = array();
272
  foreach ($users as $user) :
273
- $dude = new WP_User($user->user_id);
 
274
  if ($dude->has_cap('administrator')) :
275
  if ($dude->user_email) :
276
  $recipients[] = $dude->user_email;
@@ -670,21 +680,53 @@ function syndication_comments_feed_link ($link) {
670
  ################################################################################
671
 
672
  function fwp_add_pages () {
673
- global $fwp_path;
674
-
675
- add_menu_page('Syndicated Sites', 'Syndication', 'manage_links', $fwp_path.'/syndication.php', NULL, WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-tiny.png');
676
- do_action('feedwordpress_admin_menu_pre_feeds');
677
- add_submenu_page($fwp_path.'/syndication.php', 'Syndicated Feeds & Updates', 'Feeds & Updates', 'manage_options', $fwp_path.'/feeds-page.php');
678
- do_action('feedwordpress_admin_menu_pre_posts');
679
- add_submenu_page($fwp_path.'/syndication.php', 'Syndicated Posts & Links', 'Posts & Links', 'manage_options', $fwp_path.'/posts-page.php');
680
- do_action('feedwordpress_admin_menu_pre_authors');
681
- add_submenu_page($fwp_path.'/syndication.php', 'Syndicated Authors', 'Authors', 'manage_options', $fwp_path.'/authors-page.php');
682
- do_action('feedwordpress_admin_menu_pre_categories');
683
- add_submenu_page($fwp_path.'/syndication.php', 'Categories'.FEEDWORDPRESS_AND_TAGS, 'Categories'.FEEDWORDPRESS_AND_TAGS, 'manage_options', $fwp_path.'/categories-page.php');
684
- do_action('feedwordpress_admin_menu_pre_performance');
685
- add_submenu_page($fwp_path.'/syndication.php', 'FeedWordPress Performance', 'Performance', 'manage_options', $fwp_path.'/performance-page.php');
686
- do_action('feedwordpress_admin_menu_pre_diagnostics');
687
- add_submenu_page($fwp_path.'/syndication.php', 'FeedWordPress Diagnostics', 'Diagnostics', 'manage_options', $fwp_path.'/diagnostics-page.php');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
688
  } /* function fwp_add_pages () */
689
 
690
  function fwp_check_debug () {
@@ -939,12 +981,7 @@ class FeedWordPress {
939
  do_action('feedwordpress_update', $uri);
940
 
941
  if (is_null($crash_ts)) :
942
- $crash_dt = (int) get_option('feedwordpress_update_time_limit');
943
- if ($crash_dt > 0) :
944
- $crash_ts = time() + $crash_dt;
945
- else :
946
- $crash_ts = NULL;
947
- endif;
948
  endif;
949
 
950
  // Randomize order for load balancing purposes
@@ -990,6 +1027,16 @@ class FeedWordPress {
990
  return $delta;
991
  }
992
 
 
 
 
 
 
 
 
 
 
 
993
  function stale () {
994
  if (get_option('feedwordpress_automatic_updates')) :
995
  // Do our best to avoid possible simultaneous
@@ -1027,54 +1074,58 @@ class FeedWordPress {
1027
  } /* FeedWordPress::init() */
1028
 
1029
  function dashboard_setup () {
1030
- // Get the stylesheet
1031
- wp_enqueue_style('feedwordpress-elements');
1032
-
1033
- $widget_id = 'feedwordpress_dashboard';
1034
- $widget_name = __('Syndicated Sources');
1035
- $column = 'side';
1036
- $priority = 'core';
1037
-
1038
- // I would love to use wp_add_dashboard_widget() here and save
1039
- // myself some trouble. But WP 3 does not yet have any way to
1040
- // push a dashboard widget onto the side, or to give it a default
1041
- // location.
1042
- add_meta_box(
1043
- /*id=*/ $widget_id,
1044
- /*title=*/ $widget_name,
1045
- /*callback=*/ array(&$this, 'dashboard'),
1046
- /*page=*/ 'dashboard',
1047
- /*context=*/ $column,
1048
- /*priority=*/ $priority
1049
- );
1050
- /*control_callback= array(&$this, 'dashboard_control') */
1051
 
1052
- // This is kind of rude, I know, but the dashboard widget isn't
1053
- // worth much if users don't know that it exists, and I don't
1054
- // know of any better way to reorder the boxen.
1055
- //
1056
- // Gleefully ripped off of codex.wordpress.org/Dashboard_Widgets_API
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1057
 
1058
- // Globalize the metaboxes array, this holds all the widgets for wp-admin
1059
- global $wp_meta_boxes;
1060
-
1061
- // Get the regular dashboard widgets array
1062
- // (which has our new widget already but at the end)
1063
-
1064
- $normal_dashboard = $wp_meta_boxes['dashboard'][$column][$priority];
 
 
1065
 
1066
- // Backup and delete our new dashbaord widget from the end of the array
1067
- if (isset($normal_dashboard[$widget_id])) :
1068
- $backup = array();
1069
- $backup[$widget_id] = $normal_dashboard[$widget_id];
1070
- unset($normal_dashboard[$widget_id]);
1071
-
1072
- // Merge the two arrays together so our widget is at the
1073
- // beginning
1074
- $sorted_dashboard = array_merge($backup, $normal_dashboard);
1075
-
1076
- // Save the sorted array back into the original metaboxes
1077
- $wp_meta_boxes['dashboard'][$column][$priority] = $sorted_dashboard;
1078
  endif;
1079
  } /* FeedWordPress::dashboard_setup () */
1080
 
@@ -1170,7 +1221,12 @@ class FeedWordPress {
1170
  function syndicate_link ($name, $uri, $rss) {
1171
  // Get the category ID#
1172
  $cat_id = FeedWordPress::link_category_id();
1173
-
 
 
 
 
 
1174
  // WordPress gets cranky if there's no homepage URI
1175
  if (!is_string($uri) or strlen($uri)<1) : $uri = $rss; endif;
1176
 
@@ -1180,7 +1236,7 @@ class FeedWordPress {
1180
  "link_rss" => $rss,
1181
  "link_name" => $name,
1182
  "link_url" => $uri,
1183
- "link_category" => array($cat_id),
1184
  "link_visible" => 'Y', // reactivate if inactivated
1185
  ));
1186
 
@@ -1243,10 +1299,14 @@ class FeedWordPress {
1243
 
1244
  function syndicated_links ($args = array()) {
1245
  $contributors = FeedWordPress::link_category_id();
1246
- $links = get_bookmarks(array_merge(
1247
- array("category" => $contributors),
1248
- $args
1249
- ));
 
 
 
 
1250
  return $links;
1251
  } // function FeedWordPress::syndicated_links()
1252
 
@@ -1273,9 +1333,10 @@ class FeedWordPress {
1273
  // make a new one for ourselves.
1274
  if (!$cat_id) :
1275
  $cat_id = FeedWordPressCompatibility::insert_link_category(DEFAULT_SYNDICATION_CATEGORY);
1276
-
1277
- // Stamp it
1278
- update_option('feedwordpress_cat_id', $cat_id);
 
1279
  endif;
1280
 
1281
  return $cat_id;
@@ -1404,14 +1465,47 @@ class FeedWordPress {
1404
  ");
1405
  }
1406
 
1407
- /*static*/ function fetch ($url, $force_feed = true) {
1408
- $feed = new SimplePie();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1409
  $feed->set_feed_url($url);
1410
- $feed->set_cache_class('WP_Feed_Cache');
1411
- $feed->set_file_class('WP_SimplePie_File');
1412
- $feed->set_content_type_sniffer_class('FeedWordPress_Content_Type_Sniffer');
1413
- $feed->set_file_class('FeedWordPress_File');
1414
- $feed->set_parser_class('FeedWordPress_Parser');
 
 
1415
  $feed->force_feed($force_feed);
1416
  $feed->set_cache_duration(FeedWordPress::cache_duration());
1417
  $feed->init();
@@ -1568,11 +1662,6 @@ class FeedWordPress {
1568
 
1569
  function email_diagnostic_log () {
1570
  $dlog = get_option('feedwordpress_diagnostics_log', array());
1571
-
1572
- $recipients = get_option('feedwordpress_diagnostics_log_recipients', NULL);
1573
- if (is_null($recipients)) :
1574
- $recipients = FeedWordPressDiagnostic::admin_emails();
1575
- endif;
1576
 
1577
  if (isset($dlog['schedule']) and isset($dlog['schedule']['last'])) :
1578
  if (time() > ($dlog['schedule']['last'] + $dlog['schedule']['freq'])) :
@@ -1636,6 +1725,23 @@ $body
1636
  </html>
1637
 
1638
  EOMAIL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1639
  foreach ($recipients as $email) :
1640
  add_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
1641
  wp_mail($email, $subj, $body);
@@ -1652,7 +1758,7 @@ EOMAIL;
1652
  endif;
1653
  else :
1654
  $dlog['schedule'] = array(
1655
- 'freq' =>24 /*hr*/ * 60 /*min*/ * 60 /*s*/,
1656
  'last' => time(),
1657
  );
1658
  endif;
@@ -1679,6 +1785,42 @@ EOMAIL;
1679
  endif;
1680
  return $prefix;
1681
  } /* FeedWordPress::log_prefix () */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1682
  } // class FeedWordPress
1683
 
1684
  class FeedWordPress_File extends WP_SimplePie_File {
3
  Plugin Name: FeedWordPress
4
  Plugin URI: http://feedwordpress.radgeek.com/
5
  Description: simple and flexible Atom/RSS syndication for WordPress
6
+ Version: 2011.0211
7
  Author: Charles Johnson
8
  Author URI: http://radgeek.com/
9
  License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
+ * @version 2011.0211
15
  */
16
 
17
  # This uses code derived from:
34
 
35
  # -- Don't change these unless you know what you're doing...
36
 
37
+ define ('FEEDWORDPRESS_VERSION', '2011.0211');
38
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
39
 
40
  if (!defined('FEEDWORDPRESS_BLEG')) :
86
  // used for more than testing purposes!
87
  define('FEEDWORDPRESS_CACHE_AGE', 1);
88
  define('FEEDWORDPRESS_CACHE_LIFETIME', 1);
89
+ define('FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT', 60);
90
  else :
91
  // Hold onto data all day for conditional GET purposes,
92
  // but consider it stale after 1 min (requiring a conditional GET)
93
  define('FEEDWORDPRESS_CACHE_LIFETIME', 24*60*60);
94
  define('FEEDWORDPRESS_CACHE_AGE', 1*60);
95
+ define('FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT', 20);
96
  endif;
97
 
98
  // Use our the cache settings that we want.
105
  endif;
106
  require_once(ABSPATH . WPINC . '/class-feed.php');
107
 
108
+ if (!function_exists('wp_insert_user')) :
109
+ require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
110
+ endif;
111
 
112
  require_once(dirname(__FILE__) . '/admin-ui.php');
113
  require_once(dirname(__FILE__) . '/feedwordpresssyndicationpage.class.php');
120
 
121
  // Magic quotes are just about the stupidest thing ever.
122
  if (is_array($_POST)) :
123
+ $fwp_post = $_POST;
124
+ if (get_magic_quotes_gpc()) :
125
+ $fwp_post = stripslashes_deep($fwp_post);
126
+ endif;
127
  endif;
128
 
129
  // Get the path relative to the plugins directory in which FWP is stored
258
  'updated_feeds:errors',
259
  "Feed Error: [${url}] update returned error: $mesg"
260
  );
261
+
262
+ $hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
263
+ $span = ($error['ts'] - $error['since']);
264
+
265
+ if ($span >= ($hours * 60 * 60)) :
266
  $since = date('r', $error['since']);
267
  $mostRecent = date('r', $error['ts']);
268
  FeedWordPress::diagnostic(
279
  $users = get_users_of_blog($id);
280
  $recipients = array();
281
  foreach ($users as $user) :
282
+ $user_id = (isset($user->user_id) ? $user->user_id : $user->ID);
283
+ $dude = new WP_User($user_id);
284
  if ($dude->has_cap('administrator')) :
285
  if ($dude->user_email) :
286
  $recipients[] = $dude->user_email;
680
  ################################################################################
681
 
682
  function fwp_add_pages () {
683
+ $menu_cap = FeedWordPress::menu_cap();
684
+ $settings_cap = FeedWordPress::menu_cap(/*sub=*/ true);
685
+ $syndicationMenu = FeedWordPress::path('syndication.php');
686
+
687
+ add_menu_page(
688
+ 'Syndicated Sites', 'Syndication',
689
+ $menu_cap,
690
+ $syndicationMenu,
691
+ NULL,
692
+ WP_PLUGIN_URL.'/'.FeedWordPress::path('feedwordpress-tiny.png')
693
+ );
694
+
695
+ do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
696
+ add_submenu_page(
697
+ $syndicationMenu, 'Syndicated Feeds & Updates', 'Feeds & Updates',
698
+ $settings_cap, FeedWordPress::path('feeds-page.php')
699
+ );
700
+
701
+ do_action('feedwordpress_admin_menu_pre_posts', $menu_cap, $settings_cap);
702
+ add_submenu_page(
703
+ $syndicationMenu, 'Syndicated Posts & Links', 'Posts & Links',
704
+ $settings_cap, FeedWordPress::path('posts-page.php')
705
+ );
706
+
707
+ do_action('feedwordpress_admin_menu_pre_authors', $menu_cap, $settings_cap);
708
+ add_submenu_page(
709
+ $syndicationMenu, 'Syndicated Authors', 'Authors',
710
+ $settings_cap, FeedWordPress::path('authors-page.php')
711
+ );
712
+
713
+ do_action('feedwordpress_admin_menu_pre_categories', $menu_cap, $settings_cap);
714
+ add_submenu_page(
715
+ $syndicationMenu, 'Categories'.FEEDWORDPRESS_AND_TAGS, 'Categories'.FEEDWORDPRESS_AND_TAGS,
716
+ $settings_cap, FeedWordPress::path('categories-page.php')
717
+ );
718
+
719
+ do_action('feedwordpress_admin_menu_pre_performance', $menu_cap, $settings_cap);
720
+ add_submenu_page(
721
+ $syndicationMenu, 'FeedWordPress Performance', 'Performance',
722
+ $settings_cap, FeedWordPress::path('performance-page.php')
723
+ );
724
+
725
+ do_action('feedwordpress_admin_menu_pre_diagnostics', $menu_cap, $settings_cap);
726
+ add_submenu_page(
727
+ $syndicationMenu, 'FeedWordPress Diagnostics', 'Diagnostics',
728
+ $settings_cap, FeedWordPress::path('diagnostics-page.php')
729
+ );
730
  } /* function fwp_add_pages () */
731
 
732
  function fwp_check_debug () {
981
  do_action('feedwordpress_update', $uri);
982
 
983
  if (is_null($crash_ts)) :
984
+ $crash_ts = $this->crash_ts();
 
 
 
 
 
985
  endif;
986
 
987
  // Randomize order for load balancing purposes
1027
  return $delta;
1028
  }
1029
 
1030
+ function crash_ts ($default = NULL) {
1031
+ $crash_dt = (int) get_option('feedwordpress_update_time_limit', 0);
1032
+ if ($crash_dt > 0) :
1033
+ $crash_ts = time() + $crash_dt;
1034
+ else :
1035
+ $crash_ts = $default;
1036
+ endif;
1037
+ return $crash_ts;
1038
+ }
1039
+
1040
  function stale () {
1041
  if (get_option('feedwordpress_automatic_updates')) :
1042
  // Do our best to avoid possible simultaneous
1074
  } /* FeedWordPress::init() */
1075
 
1076
  function dashboard_setup () {
1077
+ $see_it = FeedWordPress::menu_cap();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1078
 
1079
+ if (current_user_can($see_it)) :
1080
+ // Get the stylesheet
1081
+ wp_enqueue_style('feedwordpress-elements');
1082
+
1083
+ $widget_id = 'feedwordpress_dashboard';
1084
+ $widget_name = __('Syndicated Sources');
1085
+ $column = 'side';
1086
+ $priority = 'core';
1087
+
1088
+ // I would love to use wp_add_dashboard_widget() here and save
1089
+ // myself some trouble. But WP 3 does not yet have any way to
1090
+ // push a dashboard widget onto the side, or to give it a default
1091
+ // location.
1092
+ add_meta_box(
1093
+ /*id=*/ $widget_id,
1094
+ /*title=*/ $widget_name,
1095
+ /*callback=*/ array(&$this, 'dashboard'),
1096
+ /*page=*/ 'dashboard',
1097
+ /*context=*/ $column,
1098
+ /*priority=*/ $priority
1099
+ );
1100
+ /*control_callback= array(&$this, 'dashboard_control') */
1101
+
1102
+ // This is kind of rude, I know, but the dashboard widget isn't
1103
+ // worth much if users don't know that it exists, and I don't
1104
+ // know of any better way to reorder the boxen.
1105
+ //
1106
+ // Gleefully ripped off of codex.wordpress.org/Dashboard_Widgets_API
1107
+
1108
+ // Globalize the metaboxes array, this holds all the widgets for wp-admin
1109
+ global $wp_meta_boxes;
1110
+
1111
+ // Get the regular dashboard widgets array
1112
+ // (which has our new widget already but at the end)
1113
+
1114
+ $normal_dashboard = $wp_meta_boxes['dashboard'][$column][$priority];
1115
 
1116
+ // Backup and delete our new dashbaord widget from the end of the array
1117
+ if (isset($normal_dashboard[$widget_id])) :
1118
+ $backup = array();
1119
+ $backup[$widget_id] = $normal_dashboard[$widget_id];
1120
+ unset($normal_dashboard[$widget_id]);
1121
+
1122
+ // Merge the two arrays together so our widget is at the
1123
+ // beginning
1124
+ $sorted_dashboard = array_merge($backup, $normal_dashboard);
1125
 
1126
+ // Save the sorted array back into the original metaboxes
1127
+ $wp_meta_boxes['dashboard'][$column][$priority] = $sorted_dashboard;
1128
+ endif;
 
 
 
 
 
 
 
 
 
1129
  endif;
1130
  } /* FeedWordPress::dashboard_setup () */
1131
 
1221
  function syndicate_link ($name, $uri, $rss) {
1222
  // Get the category ID#
1223
  $cat_id = FeedWordPress::link_category_id();
1224
+ if (!is_wp_error($cat_id)) :
1225
+ $link_category = array($cat_id);
1226
+ else :
1227
+ $link_category = array();
1228
+ endif;
1229
+
1230
  // WordPress gets cranky if there's no homepage URI
1231
  if (!is_string($uri) or strlen($uri)<1) : $uri = $rss; endif;
1232
 
1236
  "link_rss" => $rss,
1237
  "link_name" => $name,
1238
  "link_url" => $uri,
1239
+ "link_category" => $link_category,
1240
  "link_visible" => 'Y', // reactivate if inactivated
1241
  ));
1242
 
1299
 
1300
  function syndicated_links ($args = array()) {
1301
  $contributors = FeedWordPress::link_category_id();
1302
+ if (!is_wp_error($contributors)) :
1303
+ $links = get_bookmarks(array_merge(
1304
+ array("category" => $contributors),
1305
+ $args
1306
+ ));
1307
+ else :
1308
+ $links = array();
1309
+ endif;
1310
  return $links;
1311
  } // function FeedWordPress::syndicated_links()
1312
 
1333
  // make a new one for ourselves.
1334
  if (!$cat_id) :
1335
  $cat_id = FeedWordPressCompatibility::insert_link_category(DEFAULT_SYNDICATION_CATEGORY);
1336
+ if (!is_wp_error($cat_id)) :
1337
+ // Stamp it
1338
+ update_option('feedwordpress_cat_id', $cat_id);
1339
+ endif;
1340
  endif;
1341
 
1342
  return $cat_id;
1465
  ");
1466
  }
1467
 
1468
+ /*static*/ function fetch_timeout () {
1469
+ return apply_filters(
1470
+ 'feedwordpress_fetch_timeout',
1471
+ intval(get_option('feedwordpress_fetch_timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT))
1472
+ );
1473
+ }
1474
+
1475
+ /*static*/ function fetch ($url, $params = array()) {
1476
+ $force_feed = true; // Default
1477
+
1478
+ // Allow user to change default feed-fetch timeout with a global setting. Props Erigami Scholey-Fuller <http://www.piepalace.ca/blog/2010/11/feedwordpress-broke-my-heart.html> 'timeout' =>
1479
+ $timeout = FeedWordPress::fetch_timeout();
1480
+
1481
+ if (!is_array($params)) :
1482
+ $force_feed = $params;
1483
+ else : // Parameter array
1484
+ $args = shortcode_atts(array(
1485
+ 'force_feed' => $force_feed,
1486
+ 'timeout' => $timeout
1487
+ ), $params);
1488
+
1489
+ extract($args);
1490
+ endif;
1491
+ $timeout = intval($timeout);
1492
+
1493
+ $pie_class = apply_filters('feedwordpress_simplepie_class', 'SimplePie');
1494
+ $cache_class = apply_filters('feedwordpress_cache_class', 'WP_Feed_Cache');
1495
+ $file_class = apply_filters('feedwordpress_file_class', 'FeedWordPress_File');
1496
+ $parser_class = apply_filters('feedwordpress_parser_class', 'FeedWordPress_Parser');
1497
+
1498
+ $sniffer_class = apply_filters('feedwordpress_sniffer_class', 'FeedWordPress_Content_Type_Sniffer');
1499
+
1500
+ $feed = new $pie_class;
1501
  $feed->set_feed_url($url);
1502
+ $feed->set_cache_class($cache_class);
1503
+ $feed->set_timeout($timeout);
1504
+
1505
+ //$feed->set_file_class('WP_SimplePie_File');
1506
+ $feed->set_content_type_sniffer_class($sniffer_class);
1507
+ $feed->set_file_class($file_class);
1508
+ $feed->set_parser_class($parser_class);
1509
  $feed->force_feed($force_feed);
1510
  $feed->set_cache_duration(FeedWordPress::cache_duration());
1511
  $feed->init();
1662
 
1663
  function email_diagnostic_log () {
1664
  $dlog = get_option('feedwordpress_diagnostics_log', array());
 
 
 
 
 
1665
 
1666
  if (isset($dlog['schedule']) and isset($dlog['schedule']['last'])) :
1667
  if (time() > ($dlog['schedule']['last'] + $dlog['schedule']['freq'])) :
1725
  </html>
1726
 
1727
  EOMAIL;
1728
+
1729
+ $ded = get_option('feedwordpress_diagnostics_email_destination', 'admins');
1730
+
1731
+ // e-mail address
1732
+ if (preg_match('/^mailto:(.*)$/', $ded, $ref)) :
1733
+ $recipients = array($ref[1]);
1734
+
1735
+ // userid
1736
+ elseif (preg_match('/^user:(.*)$/', $ded, $ref)) :
1737
+ $userdata = get_userdata((int) $ref[1]);
1738
+ $recipients = array($userdata->user_email);
1739
+
1740
+ // admins
1741
+ else :
1742
+ $recipients = FeedWordPressDiagnostic::admin_emails();
1743
+ endif;
1744
+
1745
  foreach ($recipients as $email) :
1746
  add_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
1747
  wp_mail($email, $subj, $body);
1758
  endif;
1759
  else :
1760
  $dlog['schedule'] = array(
1761
+ 'freq' => 24 /*hr*/ * 60 /*min*/ * 60 /*s*/,
1762
  'last' => time(),
1763
  );
1764
  endif;
1785
  endif;
1786
  return $prefix;
1787
  } /* FeedWordPress::log_prefix () */
1788
+
1789
+ function menu_cap ($sub = false) {
1790
+ if ($sub) :
1791
+ $cap = apply_filters('feedwordpress_menu_settings_capacity', 'manage_options');
1792
+ else :
1793
+ $cap = apply_filters('feedwordpress_menu_main_capacity', 'manage_links');
1794
+ endif;
1795
+ return $cap;
1796
+ } /* FeedWordPress::menu_cap () */
1797
+
1798
+ function path ($filename = '') {
1799
+ global $fwp_path;
1800
+
1801
+ $path = $fwp_path;
1802
+ if (strlen($filename) > 0) :
1803
+ $path .= '/'.$filename;
1804
+ endif;
1805
+ return $path;
1806
+ }
1807
+
1808
+ function param ($key, $type = 'REQUEST', $default = NULL) {
1809
+ $where = '_'.strtoupper($type);
1810
+ $ret = $default;
1811
+ if (isset($GLOBALS[$where]) and is_array($GLOBALS[$where])) :
1812
+ if (isset($GLOBALS[$where][$key])) :
1813
+ $ret = $GLOBALS[$where][$key];
1814
+ if (get_magic_quotes_gpc()) :
1815
+ $ret = stripslashes_deep($ret);
1816
+ endif;
1817
+ endif;
1818
+ endif;
1819
+ return $ret;
1820
+ }
1821
+ function post ($key, $default = NULL) {
1822
+ return FeedWordPress::param($key, 'POST');
1823
+ }
1824
  } // class FeedWordPress
1825
 
1826
  class FeedWordPress_File extends WP_SimplePie_File {
feedwordpresssyndicationpage.class.php CHANGED
@@ -74,15 +74,16 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
74
  global $wpdb;
75
 
76
  if (isset($_POST['update']) or isset($_POST['action']) or isset($_POST['update_uri'])) :
77
- // Only do things with side-effects for HTTP POST or command line
78
- $fwp_update_invoke = 'post';
79
  else :
80
  $fwp_update_invoke = 'get';
81
  endif;
82
 
83
  $update_set = array();
84
  if ($fwp_update_invoke != 'get') :
85
- if (isset($_POST['link_ids']) and is_array($_POST['link_ids']) and ($_POST['action']==FWP_UPDATE_CHECKED)) :
 
86
  $targets = $wpdb->get_results("
87
  SELECT * FROM $wpdb->links
88
  WHERE link_id IN (".implode(",",$_POST['link_ids']).")
@@ -94,11 +95,16 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
94
  else : // This should never happen
95
  FeedWordPress::critical_bug('fwp_syndication_manage_page::targets', $targets, __LINE__);
96
  endif;
97
- elseif (isset($_POST['update_uri'])) :
98
- $targets = $_POST['update_uri'];
99
  if (!is_array($targets)) :
100
  $targets = array($targets);
101
  endif;
 
 
 
 
 
102
  $update_set = $targets;
103
  endif;
104
  endif;
@@ -577,30 +583,38 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
577
  endif;
578
  ?>
579
 
580
- <?php if (count($sources[$visibility]) > 0) : ?>
581
- <div style="clear: left" class="alignleft">
582
- <?php if ($showInactive) : ?>
583
- <input class="button-secondary" type="submit" name="action" value="<?php print FWP_RESUB_CHECKED; ?>" />
584
- <input class="button-secondary" type="submit" name="action" value="<?php print FWP_DELETE_CHECKED; ?>" />
585
- <?php else : ?>
586
- <input class="button-secondary" type="submit" name="action" value="<?php print FWP_UPDATE_CHECKED; ?>" />
587
- <input class="button-secondary delete" type="submit" name="action" value="<?php print FWP_UNSUB_CHECKED; ?>" />
588
- <?php endif ; ?>
589
- </div> <!-- class="alignleft" -->
590
-
591
- <?php else : ?>
592
  <?php fwp_syndication_manage_page_links_subsubsub($sources, $showInactive); ?>
593
- <?php endif; ?>
594
-
595
- <br class="clear" />
596
-
597
  <?php
 
 
598
  fwp_syndication_manage_page_links_table_rows($sources[$visibility], $this, $visibility);
 
599
  ?>
600
  </form>
601
  <?php
602
  } /* FeedWordPressSyndicationPage::syndicated_sources_box() */
603
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
604
  function bleg_thanks ($page, $box = NULL) {
605
  ?>
606
  <div class="donation-thanks">
@@ -969,12 +983,7 @@ function fwp_dashboard_update_if_requested ($object) {
969
  add_action('feedwordpress_check_feed', 'update_feeds_mention');
970
  add_action('feedwordpress_check_feed_complete', 'update_feeds_finish', 10, 3);
971
 
972
- $crash_dt = (int) get_option('feedwordpress_update_time_limit');
973
- if ($crash_dt > 0) :
974
- $crash_ts = time() + $crash_dt;
975
- else :
976
- $crash_ts = NULL;
977
- endif;
978
 
979
  echo "<div class=\"update-results\">\n";
980
  echo "<ul>\n";
@@ -995,7 +1004,9 @@ function fwp_dashboard_update_if_requested ($object) {
995
  $tdelta['updated'] += $delta['updated'];
996
  endif;
997
  else :
998
- echo "<li><p><strong>Error:</strong> There was a problem updating <a href=\"$uri\">$uri</a></p></li>\n";
 
 
999
  endif;
1000
  endforeach;
1001
  echo "</ul>\n";
74
  global $wpdb;
75
 
76
  if (isset($_POST['update']) or isset($_POST['action']) or isset($_POST['update_uri'])) :
77
+ // Only do things with side-effects for HTTP POST or command line
78
+ $fwp_update_invoke = 'post';
79
  else :
80
  $fwp_update_invoke = 'get';
81
  endif;
82
 
83
  $update_set = array();
84
  if ($fwp_update_invoke != 'get') :
85
+ if (is_array(FeedWordPress::post('link_ids'))
86
+ and (FeedWordPress::post('action')==FWP_UPDATE_CHECKED)) :
87
  $targets = $wpdb->get_results("
88
  SELECT * FROM $wpdb->links
89
  WHERE link_id IN (".implode(",",$_POST['link_ids']).")
95
  else : // This should never happen
96
  FeedWordPress::critical_bug('fwp_syndication_manage_page::targets', $targets, __LINE__);
97
  endif;
98
+ elseif (!is_null(FeedWordPress::post('update_uri'))) :
99
+ $targets = FeedWordPress::post('update_uri');
100
  if (!is_array($targets)) :
101
  $targets = array($targets);
102
  endif;
103
+
104
+ $first = each($targets);
105
+ if (!is_numeric($first['key'])) : // URLs in keys
106
+ $targets = array_keys($targets);
107
+ endif;
108
  $update_set = $targets;
109
  endif;
110
  endif;
583
  endif;
584
  ?>
585
 
586
+ <?php
587
+ if (count($sources[$visibility]) > 0) :
588
+ $this->display_button_bar($showInactive);
589
+ else :
590
+ ?>
 
 
 
 
 
 
 
591
  <?php fwp_syndication_manage_page_links_subsubsub($sources, $showInactive); ?>
 
 
 
 
592
  <?php
593
+ endif;
594
+
595
  fwp_syndication_manage_page_links_table_rows($sources[$visibility], $this, $visibility);
596
+ $this->display_button_bar($showInactive);
597
  ?>
598
  </form>
599
  <?php
600
  } /* FeedWordPressSyndicationPage::syndicated_sources_box() */
601
 
602
+ function display_button_bar ($showInactive) {
603
+ ?>
604
+ <div style="clear: left" class="alignleft">
605
+ <?php if ($showInactive) : ?>
606
+ <input class="button-secondary" type="submit" name="action" value="<?php print FWP_RESUB_CHECKED; ?>" />
607
+ <input class="button-secondary" type="submit" name="action" value="<?php print FWP_DELETE_CHECKED; ?>" />
608
+ <?php else : ?>
609
+ <input class="button-secondary" type="submit" name="action" value="<?php print FWP_UPDATE_CHECKED; ?>" />
610
+ <input class="button-secondary delete" type="submit" name="action" value="<?php print FWP_UNSUB_CHECKED; ?>" />
611
+ <?php endif ; ?>
612
+ </div> <!-- class="alignleft" -->
613
+
614
+ <br class="clear" />
615
+ <?php
616
+ }
617
+
618
  function bleg_thanks ($page, $box = NULL) {
619
  ?>
620
  <div class="donation-thanks">
983
  add_action('feedwordpress_check_feed', 'update_feeds_mention');
984
  add_action('feedwordpress_check_feed_complete', 'update_feeds_finish', 10, 3);
985
 
986
+ $crash_ts = $feedwordpress->crash_ts();
 
 
 
 
 
987
 
988
  echo "<div class=\"update-results\">\n";
989
  echo "<ul>\n";
1004
  $tdelta['updated'] += $delta['updated'];
1005
  endif;
1006
  else :
1007
+ $display_uri = esc_html(feedwordpress_display_url($uri));
1008
+ $uri = esc_html($uri);
1009
+ echo "<li><p><strong>Error:</strong> There was a problem updating <code><a href=\"$uri\">${display_uri}</a></code></p></li>\n";
1010
  endif;
1011
  endforeach;
1012
  echo "</ul>\n";
magpiefromsimplepie.class.php CHANGED
@@ -58,18 +58,35 @@ class MagpieFromSimplePie {
58
  * MagpieFromSimplePie constructor
59
  *
60
  * @param SimplePie $pie The feed to convert to MagpieRSS format.
 
61
  *
 
 
62
  * @uses MagpieFromSimplePie::processItemData
63
  * @uses MagpieFromSimplePie::normalize
 
64
  */
65
- function MagpieFromSimplePie ($pie) {
66
  $this->pie = $pie;
67
- $this->originals = $this->pie->get_items();
68
 
69
- $this->channel = $this->processFeedData($this->pie->data);
70
- foreach ($this->originals as $key => $item) :
71
- $this->items[$key] = $this->processItemData($item->data);
72
- endforeach;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
  $this->normalize();
75
 
@@ -80,16 +97,31 @@ class MagpieFromSimplePie {
80
  } /* MagpieFromSimplePie constructor */
81
 
82
  /**
83
- * MagpieFromSimplePie::get_item: returns a MagpieRSS format array
84
- * which is equivalent to the SimplePie_Item object from which this
85
  * object was constructed.
86
  *
87
- * @return array A MagpieRSS format array representing this feed item.
88
  */
89
  function get_items () {
90
  return $this->items;
91
- } /* MagpieFromSimplePie::get_item */
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  /**
94
  * MagpieFromSimplePie::processFeedData
95
  *
@@ -354,113 +386,117 @@ class MagpieFromSimplePie {
354
  * @uses FeedTime::timestamp
355
  */
356
  function normalize () {
357
- // Normalize channel data
358
- if ( $this->is_atom() ) :
359
- // Atom 1.0 elements <=> Atom 0.3 elements (Thanks, o brilliant wordsmiths of the Atom 1.0 standard!)
360
- if ($this->feed_version() < 1.0) :
361
- $this->normalize_element($this->channel, 'tagline', $this->channel, 'subtitle');
362
- $this->normalize_element($this->channel, 'copyright', $this->channel, 'rights');
363
- $this->normalize_element($this->channel, 'modified', $this->channel, 'updated');
364
- else :
365
- $this->normalize_element($this->channel, 'subtitle', $this->channel, 'tagline');
366
- $this->normalize_element($this->channel, 'rights', $this->channel, 'copyright');
367
- $this->normalize_element($this->channel, 'updated', $this->channel, 'modified');
368
- endif;
369
- $this->normalize_element($this->channel, 'author', $this->channel['dc'], 'creator', 'normalize_atom_person');
370
- $this->normalize_element($this->channel, 'contributor', $this->channel['dc'], 'contributor', 'normalize_atom_person');
371
-
372
- // Atom elements to RSS elements
373
- $this->normalize_element($this->channel, 'subtitle', $this->channel, 'description');
374
-
375
- if ( isset($this->channel['logo']) ) :
376
- $this->normalize_element($this->channel, 'logo', $this->image, 'url');
377
- $this->normalize_element($this->channel, 'link', $this->image, 'link');
378
- $this->normalize_element($this->channel, 'title', $this->image, 'title');
379
- endif;
380
-
381
- elseif ( $this->is_rss() ) :
382
- // Normalize image element from where stupid MagpieRSS puts it
383
- //$this->normalize_element($this->channel, 'image_title', $this->image, 'title');
384
- //$this->normalize_element($this->channel, 'image_link', $this->image, 'link');
385
- //$this->normalize_element($this->channel, 'image_url', $this->image, 'url');
386
-
387
- // ... and, gag, textInput
388
- //$this->normalize_element($this->channel, 'textinput_title', $this->textinput, 'title');
389
- //$this->normalize_element($this->channel, 'textinput_link', $this->textinput, 'link');
390
- //$this->normalize_element($this->channel, 'textinput_name', $this->textinput, 'name');
391
- //$this->normalize_element($this->channel, 'textinput_description', $this->textinput, 'description');
392
-
393
- // RSS elements to Atom elements
394
- $this->normalize_element($this->channel, 'description', $this->channel, 'tagline'); // Atom 0.3
395
- $this->normalize_element($this->channel, 'description', $this->channel, 'subtitle'); // Atom 1.0 (yay wordsmithing!)
396
- $this->normalize_element($this->image, 'url', $this->channel, 'logo');
397
- endif;
398
-
399
- // Now loop through and normalize item data
400
- for ( $i = 0; $i < count($this->items); $i++) :
401
- $item = $this->items[$i];
402
-
403
- // if atom populate rss fields and normalize 0.3 and 1.0 feeds
404
  if ( $this->is_atom() ) :
405
- // Atom 1.0 elements <=> Atom 0.3 elements
406
  if ($this->feed_version() < 1.0) :
407
- $this->normalize_element($item, 'modified', $item, 'updated');
408
- $this->normalize_element($item, 'issued', $item, 'published');
 
409
  else :
410
- $this->normalize_element($item, 'updated', $item, 'modified');
411
- $this->normalize_element($item, 'published', $item, 'issued');
 
412
  endif;
413
-
414
- $this->normalize_author_inheritance($item, $this->originals[$i]);
415
 
416
  // Atom elements to RSS elements
417
- $this->normalize_element($item, 'author', $item['dc'], 'creator', 'normalize_atom_person');
418
- $this->normalize_element($item, 'contributor', $item['dc'], 'contributor', 'normalize_atom_person');
419
- $this->normalize_element($item, 'summary', $item, 'description');
420
- $this->normalize_element($item, 'atom_content', $item['content'], 'encoded');
421
- $this->normalize_element($item, 'link_enclosure', $item, 'enclosure', 'normalize_enclosure');
422
-
423
- // Categories
424
- if ( isset($item['category#']) ) : // Atom 1.0 categories to dc:subject and RSS 2.0 categories
425
- $this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category');
426
- elseif ( isset($item['dc']['subject#']) ) : // dc:subject to Atom 1.0 and RSS 2.0 categories
427
- $this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject');
428
  endif;
429
 
430
- // Normalized item timestamp
431
- $item_date = (isset($item['published']) ) ? $item['published'] : $item['updated'];
432
  elseif ( $this->is_rss() ) :
 
 
 
 
 
 
 
 
 
 
 
433
  // RSS elements to Atom elements
434
- $this->normalize_element($item, 'description', $item, 'summary');
435
- $this->normalize_element($item, 'enclosure', $item, 'link_enclosure', 'normalize_enclosure');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
 
437
- // Categories
438
- if ( isset($item['category#']) ) : // RSS 2.0 categories to dc:subject and Atom 1.0 categories
439
- $this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category');
440
- elseif ( isset($item['dc']['subject#']) ) : // dc:subject to Atom 1.0 and RSS 2.0 categories
441
- $this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject');
442
- endif;
443
 
444
- // Normalized item timestamp
445
- if (isset($item['pubdate'])) :
446
- $item_date = $item['pubdate'];
447
- elseif (isset($item['dc']['date'])) :
448
- $item_date = $item['dc']['date'];
449
- else :
450
- $item_date = null;
 
451
  endif;
452
- endif;
453
 
454
- if ( $item_date ) :
455
- $date_timestamp = new FeedTime($item_date);
456
 
457
- if (!$date_timestamp->failed()) :
458
- $item['date_timestamp'] = $date_timestamp->timestamp();
 
459
  endif;
460
- endif;
461
 
462
- $this->items[$i] = $item;
463
- endfor;
 
464
  } /* MagpieFromSimplePie::normalize() */
465
 
466
  /**
58
  * MagpieFromSimplePie constructor
59
  *
60
  * @param SimplePie $pie The feed to convert to MagpieRSS format.
61
+ * @param mixed $item
62
  *
63
+ * @uses SimplePie::get_items
64
+ * @uses MagpieFromSimplePie::processFeedData
65
  * @uses MagpieFromSimplePie::processItemData
66
  * @uses MagpieFromSimplePie::normalize
67
+ * @uses MagpieFromSimplePie::is_atom
68
  */
69
+ function MagpieFromSimplePie ($pie, $item = true) {
70
  $this->pie = $pie;
 
71
 
72
+ // item in {NULL, true} = process channel data
73
+ if (!is_a($item, 'SimplePie_Item')) :
74
+ $this->originals = $this->pie->get_items();
75
+
76
+ $this->channel = $this->processFeedData($this->pie->data);
77
+ else :
78
+ $this->originals = array($item);
79
+ $this->channel = NULL;
80
+ endif;
81
+
82
+ // item in {true, SimplePie_Item} = process item data
83
+ if (!is_null($item)) :
84
+ foreach ($this->originals as $key => $item) :
85
+ $this->items[$key] = $this->processItemData($item->data);
86
+ endforeach;
87
+ else :
88
+ $this->items = NULL;
89
+ endif;
90
 
91
  $this->normalize();
92
 
97
  } /* MagpieFromSimplePie constructor */
98
 
99
  /**
100
+ * MagpieFromSimplePie::get_items: returns an array of MagpieRSS format arrays
101
+ * equivalent to the SimplePie_Item objects in the SimplePie object from which this
102
  * object was constructed.
103
  *
104
+ * @return array An array of MagpieRSS-format arrays representing the items on this feed
105
  */
106
  function get_items () {
107
  return $this->items;
108
+ } /* MagpieFromSimplePie::get_items () */
109
 
110
+ /**
111
+ * MagpieFromSimplePie::get_item: returns a single MagpieRSS format array equivalent
112
+ * to a SimplePie_Item object from which this object was constructed.
113
+ *
114
+ * @return array A MagpieRSS-format array representing an item on this feed
115
+ */
116
+ function get_item () {
117
+ if (is_array($this->items)) :
118
+ $ret = reset($this->items);
119
+ else :
120
+ $ret = NULL;
121
+ endif;
122
+ return $ret;
123
+ } /* MagpieFromSimplePie::get_item () */
124
+
125
  /**
126
  * MagpieFromSimplePie::processFeedData
127
  *
386
  * @uses FeedTime::timestamp
387
  */
388
  function normalize () {
389
+ if (!is_null($this->channel)) :
390
+ // Normalize channel data
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391
  if ( $this->is_atom() ) :
392
+ // Atom 1.0 elements <=> Atom 0.3 elements (Thanks, o brilliant wordsmiths of the Atom 1.0 standard!)
393
  if ($this->feed_version() < 1.0) :
394
+ $this->normalize_element($this->channel, 'tagline', $this->channel, 'subtitle');
395
+ $this->normalize_element($this->channel, 'copyright', $this->channel, 'rights');
396
+ $this->normalize_element($this->channel, 'modified', $this->channel, 'updated');
397
  else :
398
+ $this->normalize_element($this->channel, 'subtitle', $this->channel, 'tagline');
399
+ $this->normalize_element($this->channel, 'rights', $this->channel, 'copyright');
400
+ $this->normalize_element($this->channel, 'updated', $this->channel, 'modified');
401
  endif;
402
+ $this->normalize_element($this->channel, 'author', $this->channel['dc'], 'creator', 'normalize_atom_person');
403
+ $this->normalize_element($this->channel, 'contributor', $this->channel['dc'], 'contributor', 'normalize_atom_person');
404
 
405
  // Atom elements to RSS elements
406
+ $this->normalize_element($this->channel, 'subtitle', $this->channel, 'description');
407
+
408
+ if ( isset($this->channel['logo']) ) :
409
+ $this->normalize_element($this->channel, 'logo', $this->image, 'url');
410
+ $this->normalize_element($this->channel, 'link', $this->image, 'link');
411
+ $this->normalize_element($this->channel, 'title', $this->image, 'title');
 
 
 
 
 
412
  endif;
413
 
 
 
414
  elseif ( $this->is_rss() ) :
415
+ // Normalize image element from where stupid MagpieRSS puts it
416
+ //$this->normalize_element($this->channel, 'image_title', $this->image, 'title');
417
+ //$this->normalize_element($this->channel, 'image_link', $this->image, 'link');
418
+ //$this->normalize_element($this->channel, 'image_url', $this->image, 'url');
419
+
420
+ // ... and, gag, textInput
421
+ //$this->normalize_element($this->channel, 'textinput_title', $this->textinput, 'title');
422
+ //$this->normalize_element($this->channel, 'textinput_link', $this->textinput, 'link');
423
+ //$this->normalize_element($this->channel, 'textinput_name', $this->textinput, 'name');
424
+ //$this->normalize_element($this->channel, 'textinput_description', $this->textinput, 'description');
425
+
426
  // RSS elements to Atom elements
427
+ $this->normalize_element($this->channel, 'description', $this->channel, 'tagline'); // Atom 0.3
428
+ $this->normalize_element($this->channel, 'description', $this->channel, 'subtitle'); // Atom 1.0 (yay wordsmithing!)
429
+ $this->normalize_element($this->image, 'url', $this->channel, 'logo');
430
+ endif;
431
+ endif;
432
+
433
+ if (!is_null($this->items)) :
434
+ // Now loop through and normalize item data
435
+ for ( $i = 0; $i < count($this->items); $i++) :
436
+ $item = $this->items[$i];
437
+
438
+ // if atom populate rss fields and normalize 0.3 and 1.0 feeds
439
+ if ( $this->is_atom() ) :
440
+ // Atom 1.0 elements <=> Atom 0.3 elements
441
+ if ($this->feed_version() < 1.0) :
442
+ $this->normalize_element($item, 'modified', $item, 'updated');
443
+ $this->normalize_element($item, 'issued', $item, 'published');
444
+ else :
445
+ $this->normalize_element($item, 'updated', $item, 'modified');
446
+ $this->normalize_element($item, 'published', $item, 'issued');
447
+ endif;
448
+
449
+ $this->normalize_author_inheritance($item, $this->originals[$i]);
450
+
451
+ // Atom elements to RSS elements
452
+ $this->normalize_element($item, 'author', $item['dc'], 'creator', 'normalize_atom_person');
453
+ $this->normalize_element($item, 'contributor', $item['dc'], 'contributor', 'normalize_atom_person');
454
+ $this->normalize_element($item, 'summary', $item, 'description');
455
+ $this->normalize_element($item, 'atom_content', $item['content'], 'encoded');
456
+ $this->normalize_element($item, 'link_enclosure', $item, 'enclosure', 'normalize_enclosure');
457
+
458
+ // Categories
459
+ if ( isset($item['category#']) ) : // Atom 1.0 categories to dc:subject and RSS 2.0 categories
460
+ $this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category');
461
+ elseif ( isset($item['dc']['subject#']) ) : // dc:subject to Atom 1.0 and RSS 2.0 categories
462
+ $this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject');
463
+ endif;
464
+
465
+ // Normalized item timestamp
466
+ $item_date = (isset($item['published']) ) ? $item['published'] : $item['updated'];
467
+ elseif ( $this->is_rss() ) :
468
+ // RSS elements to Atom elements
469
+ $this->normalize_element($item, 'description', $item, 'summary');
470
+ $this->normalize_element($item, 'enclosure', $item, 'link_enclosure', 'normalize_enclosure');
471
 
472
+ // Categories
473
+ if ( isset($item['category#']) ) : // RSS 2.0 categories to dc:subject and Atom 1.0 categories
474
+ $this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category');
475
+ elseif ( isset($item['dc']['subject#']) ) : // dc:subject to Atom 1.0 and RSS 2.0 categories
476
+ $this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject');
477
+ endif;
478
 
479
+ // Normalized item timestamp
480
+ if (isset($item['pubdate'])) :
481
+ $item_date = $item['pubdate'];
482
+ elseif (isset($item['dc']['date'])) :
483
+ $item_date = $item['dc']['date'];
484
+ else :
485
+ $item_date = null;
486
+ endif;
487
  endif;
 
488
 
489
+ if ( $item_date ) :
490
+ $date_timestamp = new FeedTime($item_date);
491
 
492
+ if (!$date_timestamp->failed()) :
493
+ $item['date_timestamp'] = $date_timestamp->timestamp();
494
+ endif;
495
  endif;
 
496
 
497
+ $this->items[$i] = $item;
498
+ endfor;
499
+ endif;
500
  } /* MagpieFromSimplePie::normalize() */
501
 
502
  /**
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: Charles Johnson
3
  Donate link: http://feedwordpress.radgeek.com/
4
  Tags: syndication, aggregation, feed, atom, rss
5
  Requires at least: 3.0
6
- Tested up to: 3.0.1
7
- Stable tag: 2010.0905
8
 
9
  FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
10
 
3
  Donate link: http://feedwordpress.radgeek.com/
4
  Tags: syndication, aggregation, feed, atom, rss
5
  Requires at least: 3.0
6
+ Tested up to: 3.0.4
7
+ Stable tag: 2011.0211
8
 
9
  FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
10
 
syndicatedlink.class.php CHANGED
@@ -112,14 +112,34 @@ class SyndicatedLink {
112
  endforeach;
113
 
114
  if (isset($this->settings['terms'])) :
115
- $this->settings['terms'] = explode(FEEDWORDPRESS_CAT_SEPARATOR.FEEDWORDPRESS_CAT_SEPARATOR, $this->settings['terms']);
116
- $terms = array();
117
- foreach ($this->settings['terms'] as $line) :
118
- $line = explode(FEEDWORDPRESS_CAT_SEPARATOR, $line);
119
- $tax = array_shift($line);
120
- $terms[$tax] = $line;
121
- endforeach;
122
- $this->settings['terms'] = $terms;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  endif;
124
 
125
  if (isset($this->settings['map authors'])) :
@@ -163,11 +183,14 @@ class SyndicatedLink {
163
  function poll ($crash_ts = NULL) {
164
  global $wpdb;
165
 
166
- FeedWordPress::diagnostic('updated_feeds', 'Polling feed ['.$this->link->link_rss.']');
 
 
 
167
 
168
  $this->simplepie = apply_filters(
169
  'syndicated_feed',
170
- FeedWordPress::fetch($this->link->link_rss),
171
  $this
172
  );
173
 
@@ -175,7 +198,7 @@ class SyndicatedLink {
175
  if (is_wp_error($this->simplepie)) :
176
  $this->magpie = $this->simplepie;
177
  else :
178
- $this->magpie = new MagpieFromSimplePie($this->simplepie);
179
  endif;
180
 
181
  $new_count = NULL;
@@ -288,16 +311,15 @@ class SyndicatedLink {
288
 
289
  $posts = apply_filters(
290
  'syndicated_feed_items',
291
- $this->magpie->originals,
292
- $this
293
  );
 
 
 
294
  if (is_array($posts)) :
295
- foreach ($posts as $key => $original) :
296
- $item = $this->magpie->items[$key];
297
- $post = new SyndicatedPost(array(
298
- 'simplepie' => $original,
299
- 'magpie' => $item,
300
- ), $this);
301
 
302
  if (!$resume or !in_array(trim($post->guid()), $processed)) :
303
  $processed[] = $post->guid();
@@ -470,11 +492,8 @@ class SyndicatedLink {
470
  endforeach;
471
 
472
  if (isset($to_notes['terms']) and is_array($to_notes['terms'])) :
473
- $tt = array();
474
- foreach ($to_notes['terms'] as $tax => $terms) :
475
- $tt[] = $tax.FEEDWORDPRESS_CAT_SEPARATOR.implode(FEEDWORDPRESS_CAT_SEPARATOR, $terms);
476
- endforeach;
477
- $to_notes['terms'] = implode(FEEDWORDPRESS_CAT_SEPARATOR.FEEDWORDPRESS_CAT_SEPARATOR, $tt);
478
  endif;
479
 
480
  // Collapse the author mapping rule structure back into a flat string
@@ -532,7 +551,7 @@ class SyndicatedLink {
532
  * @param mixed $fallback_value If the link setting and the global setting are nonexistent or marked as a use-default value, fall back to this constant value.
533
  * @return bool TRUE on success, FALSE on failure.
534
  */
535
- function setting ($name, $fallback_global = NULL, $fallback_value = NULL) {
536
  $ret = NULL;
537
  if (isset($this->settings[$name])) :
538
  $ret = $this->settings[$name];
@@ -540,16 +559,19 @@ class SyndicatedLink {
540
 
541
  $no_value = (
542
  is_null($ret)
543
- or (is_string($ret) and strtolower($ret)=='default')
544
  );
545
 
546
  if ($no_value and !is_null($fallback_global)) :
 
 
 
547
  $ret = get_option('feedwordpress_'.$fallback_global, /*default=*/ NULL);
548
  endif;
549
 
550
  $no_value = (
551
  is_null($ret)
552
- or (is_string($ret) and strtolower($ret)=='default')
553
  );
554
 
555
  if ($no_value and !is_null($fallback_value)) :
@@ -566,8 +588,33 @@ class SyndicatedLink {
566
  endif;
567
  } /* SyndicatedLink::update_setting () */
568
 
569
- function uri () {
570
- return (is_object($this->link) ? $this->link->link_rss : NULL);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
571
  } /* SyndicatedLink::uri () */
572
 
573
  function property_cascade ($fromFeed, $link_field, $setting, $simplepie_method) {
112
  endforeach;
113
 
114
  if (isset($this->settings['terms'])) :
115
+ // Look for new format
116
+ $this->settings['terms'] = maybe_unserialize($this->settings['terms']);
117
+
118
+ if (!is_array($this->settings['terms'])) :
119
+ // Deal with old format instead. Ugh.
120
+
121
+ // Split on two *or more* consecutive breaks
122
+ // because in the old format, a taxonomy
123
+ // without any associated terms would
124
+ // produce tax_name#1\n\n\ntax_name#2\nterm,
125
+ // and the naive split on the first \n\n
126
+ // would screw up the tax_name#2 list.
127
+ //
128
+ // Props to David Morris for pointing this
129
+ // out.
130
+
131
+ $this->settings['terms'] = preg_split(
132
+ "/".FEEDWORDPRESS_CAT_SEPARATOR."{2,}/",
133
+ $this->settings['terms']
134
+ );
135
+ $terms = array();
136
+ foreach ($this->settings['terms'] as $line) :
137
+ $line = explode(FEEDWORDPRESS_CAT_SEPARATOR, $line);
138
+ $tax = array_shift($line);
139
+ $terms[$tax] = $line;
140
+ endforeach;
141
+ $this->settings['terms'] = $terms;
142
+ endif;
143
  endif;
144
 
145
  if (isset($this->settings['map authors'])) :
183
  function poll ($crash_ts = NULL) {
184
  global $wpdb;
185
 
186
+ $url = $this->uri(array('add_params' => true));
187
+ FeedWordPress::diagnostic('updated_feeds', 'Polling feed ['.$url.']');
188
+
189
+ $timeout = $this->setting('fetch timeout', 'feedwordpress_fetch_timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT);
190
 
191
  $this->simplepie = apply_filters(
192
  'syndicated_feed',
193
+ FeedWordPress::fetch($url, array('timeout' => $timeout)),
194
  $this
195
  );
196
 
198
  if (is_wp_error($this->simplepie)) :
199
  $this->magpie = $this->simplepie;
200
  else :
201
+ $this->magpie = new MagpieFromSimplePie($this->simplepie, NULL);
202
  endif;
203
 
204
  $new_count = NULL;
311
 
312
  $posts = apply_filters(
313
  'syndicated_feed_items',
314
+ $this->simplepie->get_items(),
315
+ &$this
316
  );
317
+
318
+ $this->magpie->originals = $posts;
319
+
320
  if (is_array($posts)) :
321
+ foreach ($posts as $key => $item) :
322
+ $post = new SyndicatedPost($item, $this);
 
 
 
 
323
 
324
  if (!$resume or !in_array(trim($post->guid()), $processed)) :
325
  $processed[] = $post->guid();
492
  endforeach;
493
 
494
  if (isset($to_notes['terms']) and is_array($to_notes['terms'])) :
495
+ // Serialize it.
496
+ $to_notes['terms'] = serialize($to_notes['terms']);
 
 
 
497
  endif;
498
 
499
  // Collapse the author mapping rule structure back into a flat string
551
  * @param mixed $fallback_value If the link setting and the global setting are nonexistent or marked as a use-default value, fall back to this constant value.
552
  * @return bool TRUE on success, FALSE on failure.
553
  */
554
+ function setting ($name, $fallback_global = NULL, $fallback_value = NULL, $default = 'default') {
555
  $ret = NULL;
556
  if (isset($this->settings[$name])) :
557
  $ret = $this->settings[$name];
559
 
560
  $no_value = (
561
  is_null($ret)
562
+ or (is_string($ret) and strtolower($ret)==$default)
563
  );
564
 
565
  if ($no_value and !is_null($fallback_global)) :
566
+ // Avoid duplication of this correction
567
+ $fallback_global = preg_replace('/^feedwordpress_/', '', $fallback_global);
568
+
569
  $ret = get_option('feedwordpress_'.$fallback_global, /*default=*/ NULL);
570
  endif;
571
 
572
  $no_value = (
573
  is_null($ret)
574
+ or (is_string($ret) and strtolower($ret)==$default)
575
  );
576
 
577
  if ($no_value and !is_null($fallback_value)) :
588
  endif;
589
  } /* SyndicatedLink::update_setting () */
590
 
591
+ function uri ($params = array()) {
592
+ $params = shortcode_atts(array(
593
+ 'add_params' => false,
594
+ ), $params);
595
+
596
+ $uri = (is_object($this->link) ? $this->link->link_rss : NULL);
597
+ if (!is_null($uri) and strlen($uri) > 0 and $params['add_params']) :
598
+ $qp = maybe_unserialize($this->setting('query parameters', array()));
599
+
600
+ // For high-tech HTTP feed request kung fu
601
+ $qp = apply_filters('syndicated_feed_parameters', $qp, $uri, $this);
602
+
603
+ $q = array();
604
+ if (is_array($qp) and count($qp) > 0) :
605
+ foreach ($qp as $pair) :
606
+ $q[] = urlencode($pair[0]).'='.urlencode($pair[1]);
607
+ endforeach;
608
+
609
+ // Are we appending to a URI that already has params?
610
+ $sep = ((strpos('?', $uri)===false) ? '?' : '&');
611
+
612
+ // Tack it on
613
+ $uri .= $sep . implode("&", $q);
614
+ endif;
615
+ endif;
616
+
617
+ return $uri;
618
  } /* SyndicatedLink::uri () */
619
 
620
  function property_cascade ($fromFeed, $link_field, $setting, $simplepie_method) {
syndicatedpost.class.php CHANGED
@@ -24,6 +24,10 @@ class SyndicatedPost {
24
 
25
  var $post = array ();
26
 
 
 
 
 
27
  var $_freshness = null;
28
  var $_wp_id = null;
29
 
@@ -36,7 +40,7 @@ class SyndicatedPost {
36
  * @param array $item The item syndicated from the feed.
37
  * @param SyndicatedLink $source The feed it was syndicated from.
38
  */
39
- function SyndicatedPost ($item, $source) {
40
  global $wpdb;
41
 
42
  if (is_array($item)
@@ -45,11 +49,20 @@ class SyndicatedPost {
45
  $this->entry = $item['simplepie'];
46
  $this->item = $item['magpie'];
47
  $item = $item['magpie'];
 
 
 
 
 
 
 
 
 
48
  else :
49
  $this->item = $item;
50
  endif;
51
 
52
- $this->link = $source;
53
  $this->feed = $source->magpie;
54
  $this->feedmeta = $source->settings;
55
 
@@ -94,7 +107,7 @@ class SyndicatedPost {
94
  $this
95
  );
96
  $this->item = $changed;
97
-
98
  # Filters can halt further processing by returning NULL
99
  if (is_null($this->item)) :
100
  $this->post = NULL;
@@ -109,7 +122,7 @@ class SyndicatedPost {
109
  $this->entry->get_title(), $this
110
  );
111
 
112
- $this->post['named']['author'] = apply_filters(
113
  'syndicated_item_author',
114
  $this->author(), $this
115
  );
@@ -126,17 +139,16 @@ class SyndicatedPost {
126
  if (!empty($excerpt)):
127
  $this->post['post_excerpt'] = $excerpt;
128
  endif;
129
-
130
- $this->post['epoch']['issued'] = apply_filters('syndicated_item_published', $this->published(), $this);
131
- $this->post['epoch']['created'] = apply_filters('syndicated_item_created', $this->created(), $this);
132
- $this->post['epoch']['modified'] = apply_filters('syndicated_item_updated', $this->updated(), $this);
133
 
134
  // Dealing with timestamps in WordPress is so fucking fucked.
135
  $offset = (int) get_option('gmt_offset') * 60 * 60;
136
- $this->post['post_date'] = gmdate('Y-m-d H:i:s', apply_filters('syndicated_item_published', $this->published(/*fallback=*/ true, /*default=*/ -1), $this) + $offset);
137
- $this->post['post_modified'] = gmdate('Y-m-d H:i:s', apply_filters('syndicated_item_updated', $this->updated(/*fallback=*/ true, /*default=*/ -1), $this) + $offset);
138
- $this->post['post_date_gmt'] = gmdate('Y-m-d H:i:s', apply_filters('syndicated_item_published', $this->published(/*fallback=*/ true, /*default=*/ -1), $this));
139
- $this->post['post_modified_gmt'] = gmdate('Y-m-d H:i:s', apply_filters('syndicated_item_updated', $this->updated(/*fallback=*/ true, /*default=*/ -1), $this));
 
 
 
140
 
141
  // Use feed-level preferences or the global default.
142
  $this->post['post_status'] = $this->link->syndicated_status('post', 'publish');
@@ -291,7 +303,7 @@ class SyndicatedPost {
291
  if (is_array($fc)) :
292
  $cats = array_merge($cats, $fc);
293
  endif;
294
- $this->post['pretax']['category'] = $cats;
295
 
296
  // Now add categories from the post, if we have 'em
297
  $cats = array();
@@ -316,7 +328,7 @@ class SyndicatedPost {
316
  endif;
317
  endforeach; endif;
318
 
319
- $this->post['taxed']['category'] = apply_filters('syndicated_item_categories', $cats, $this);
320
 
321
  // Tags: start with default tags, if any
322
  $tags = array();
@@ -329,11 +341,11 @@ class SyndicatedPost {
329
  if (is_array($ft)) :
330
  $tags = array_merge($tags, $ft);
331
  endif;
332
- $this->post['pretax']['post_tag'] = $tags;
333
 
334
  // Scan post for /a[@rel='tag'] and use as tags if present
335
  $tags = $this->inline_tags();
336
- $this->post['taxed']['post_tag'] = apply_filters('syndicated_item_tags', $tags, $this);
337
 
338
  $taxonomies = $this->link->taxonomies();
339
  $feedTerms = $this->link->setting('terms', NULL, array());
@@ -357,7 +369,7 @@ class SyndicatedPost {
357
  endif;
358
 
359
  // That's all, folks.
360
- $this->post['pretax'][$tax] = $terms;
361
  endif;
362
  endforeach;
363
 
@@ -627,7 +639,10 @@ class SyndicatedPost {
627
  return $permalink;
628
  }
629
 
630
- function created () {
 
 
 
631
  $date = '';
632
  if (isset($this->item['dc']['created'])) :
633
  $date = $this->item['dc']['created'];
@@ -637,13 +652,24 @@ class SyndicatedPost {
637
  $date = $this->item['created'];
638
  endif;
639
 
640
- $epoch = new FeedTime($date);
641
- return $epoch->timestamp();
 
 
 
 
642
  } /* SyndicatedPost::created() */
643
 
644
- function published ($fallback = true, $default = NULL) {
 
 
 
 
 
 
 
645
  $date = '';
646
- $epoch = null;
647
 
648
  # RSS is a fucking mess. Figure out whether we have a date in
649
  # <dc:date>, <issued>, <pubDate>, etc., and get it into Unix
@@ -663,26 +689,36 @@ class SyndicatedPost {
663
 
664
  if (strlen($date) > 0) :
665
  $time = new FeedTime($date);
666
- $epoch = $time->timestamp();
667
  elseif ($fallback) : // Fall back to <updated> / <modified> if present
668
- $epoch = $this->updated(/*fallback=*/ false, /*default=*/ $default);
669
  endif;
670
 
671
  # If everything failed, then default to the current time.
672
- if (is_null($epoch)) :
673
  if (-1 == $default) :
674
- $epoch = time();
675
  else :
676
- $epoch = $default;
677
  endif;
678
  endif;
679
 
680
- return $epoch;
 
 
 
681
  } /* SyndicatedPost::published() */
682
 
683
- function updated ($fallback = true, $default = -1) {
 
 
 
 
 
 
 
684
  $date = '';
685
- $epoch = null;
686
 
687
  # As far as I know, only dcterms and Atom have reliable ways to
688
  # specify when something was *modified* last. If neither is
@@ -693,27 +729,30 @@ class SyndicatedPost {
693
  $date = $this->item['dcterms']['modified'];
694
  elseif (isset($this->item['modified'])): // Atom 0.3
695
  $date = $this->item['modified'];
696
- elseif (isset($this->item['updated'])): // Atom 1.0
697
  $date = $this->item['updated'];
698
  endif;
699
 
700
  if (strlen($date) > 0) :
701
  $time = new FeedTime($date);
702
- $epoch = $time->timestamp();
703
  elseif ($fallback) : // Fall back to issued / dc:date
704
- $epoch = $this->published(/*fallback=*/ false, /*default=*/ $default);
705
  endif;
706
 
707
  # If everything failed, then default to the current time.
708
- if (is_null($epoch)) :
709
  if (-1 == $default) :
710
- $epoch = time();
711
  else :
712
- $epoch = $default;
713
  endif;
714
  endif;
715
 
716
- return $epoch;
 
 
 
717
  } /* SyndicatedPost::updated() */
718
 
719
  function update_hash () {
@@ -724,26 +763,43 @@ class SyndicatedPost {
724
  $guid = null;
725
  if (isset($this->item['id'])): // Atom 0.3 / 1.0
726
  $guid = $this->item['id'];
727
- elseif (isset($this->item['atom']['id'])) : // Namespaced Atom
728
  $guid = $this->item['atom']['id'];
729
- elseif (isset($this->item['guid'])) : // RSS 2.0
730
  $guid = $this->item['guid'];
731
- elseif (isset($this->item['dc']['identifier'])) :// yeah, right
732
  $guid = $this->item['dc']['identifier'];
733
- else :
 
 
 
 
 
 
734
  // The feed does not seem to have provided us with a
735
- // unique identifier, so we'll have to cobble together
736
- // a tag: URI that might work for us. The base of the
737
- // URI will be the host name of the feed source ...
738
  $bits = parse_url($this->link->uri());
739
  $guid = 'tag:'.$bits['host'];
740
 
 
 
 
 
 
 
 
 
 
 
 
741
  // If we have a date of creation, then we can use that
742
  // to uniquely identify the item. (On the other hand, if
743
  // the feed producer was consicentious enough to
744
  // generate dates of creation, she probably also was
745
  // conscientious enough to generate unique identifiers.)
746
- if (!is_null($this->created())) :
747
  $guid .= '://post.'.date('YmdHis', $this->created());
748
 
749
  // Otherwise, use both the URI of the item, *and* the
@@ -1155,41 +1211,40 @@ class SyndicatedPost {
1155
  ");
1156
 
1157
  if (!$result) :
 
1158
  $this->_freshness = 2; // New content
1159
  else:
1160
- $stored_update_hashes = get_post_custom_values('syndication_item_hash', $result->id);
1161
- if (count($stored_update_hashes) > 0) :
1162
- $stored_update_hash = $stored_update_hashes[0];
1163
- $update_hash_changed = ($stored_update_hash != $this->update_hash());
1164
- else :
1165
- $update_hash_changed = true; // Can't find syndication meta-data
1166
- endif;
1167
-
1168
  preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $result->post_modified_gmt, $backref);
1169
 
1170
  $last_rev_ts = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]);
1171
  $updated_ts = $this->updated(/*fallback=*/ true, /*default=*/ NULL);
1172
 
1173
- $frozen_values = get_post_custom_values('_syndication_freeze_updates', $result->id);
1174
- $frozen_post = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
1175
- $frozen_feed = ('yes' == $this->link->setting('freeze updates', 'freeze_updates', NULL));
1176
-
1177
  // Check timestamps...
1178
  $updated = (
1179
  !is_null($updated_ts)
1180
  and ($updated_ts > $last_rev_ts)
1181
  );
1182
 
1183
-
1184
- // Or the hash...
1185
- $updated = ($updated or $update_hash_changed);
 
 
 
 
 
 
 
1186
 
1187
- // But only if the post is not frozen.
1188
- $updated = (
1189
- $updated
1190
- and !$frozen_post
1191
- and !$frozen_feed
1192
- );
 
 
 
1193
 
1194
  if ($updated) :
1195
  $this->_freshness = 1; // Updated content
@@ -1253,7 +1308,7 @@ class SyndicatedPost {
1253
  $taxonomies = array_filter($taxonomies, 'remove_dummy_zero');
1254
 
1255
  $terms = $this->category_ids (
1256
- $this->post['taxed'][$what],
1257
  $this->link->setting("unfamiliar {$what}", "unfamiliar_{$what}", 'create:'.$what),
1258
  /*taxonomies=*/ $taxonomies,
1259
  array(
@@ -1293,7 +1348,7 @@ class SyndicatedPost {
1293
  endforeach;
1294
 
1295
  // Now let's add on the feed and global presets
1296
- foreach ($this->post['pretax'] as $tax => $term_ids) :
1297
  if (!isset($this->post['tax_input'][$tax])) :
1298
  $this->post['tax_input'][$tax] = array();
1299
  endif;
@@ -1313,9 +1368,16 @@ class SyndicatedPost {
1313
  endif;
1314
 
1315
  if (!$this->filtered() and $freshness > 0) :
1316
- unset($this->post['named']);
 
 
 
 
 
 
 
1317
  $this->post = apply_filters('syndicated_post', $this->post, $this);
1318
-
1319
  // Allow for feed-specific syndicated_post filters.
1320
  $this->post = apply_filters(
1321
  "syndicated_post_".$this->link->uri(),
@@ -1332,24 +1394,22 @@ class SyndicatedPost {
1332
  /*arguments=*/ 3
1333
  );
1334
 
1335
- if (!$this->filtered() and $freshness == 2) :
1336
- // The item has not yet been added. So let's add it.
1337
- FeedWordPress::diagnostic('syndicated_posts', 'Inserting new post "'.$this->post['post_title'].'"');
1338
-
1339
- $this->insert_new();
1340
- do_action('post_syndicated_item', $this->wp_id(), $this);
1341
-
1342
- $ret = 'new';
1343
- elseif (!$this->filtered() and $freshness == 1) :
1344
- FeedWordPress::diagnostic('syndicated_posts', 'Updating existing post # '.$this->wp_id().', "'.$this->post['post_title'].'"');
1345
 
1346
- $this->post['ID'] = $this->wp_id();
1347
- $this->update_existing();
1348
- do_action('update_syndicated_item', $this->wp_id(), $this);
 
1349
 
1350
- $ret = 'updated';
1351
- else :
1352
- $ret = false;
1353
  endif;
1354
 
1355
  // Remove add_rss_meta hook
@@ -1396,7 +1456,20 @@ class SyndicatedPost {
1396
  /*priority=*/ -10001, /* very early */
1397
  /*arguments=*/ 3
1398
  );
 
 
 
 
 
 
 
 
 
1399
 
 
 
 
 
1400
  $this->_wp_id = wp_insert_post($dbpost);
1401
 
1402
  remove_action(
@@ -1405,7 +1478,14 @@ class SyndicatedPost {
1405
  /*priority=*/ -10001, /* very early */
1406
  /*arguments=*/ 3
1407
  );
1408
-
 
 
 
 
 
 
 
1409
  // Turn off ridiculous fucking kludges #1 and #2
1410
  remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1411
  remove_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
@@ -1572,6 +1652,29 @@ class SyndicatedPost {
1572
  endif;
1573
  } /* SyndicatedPost::add_terms () */
1574
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1575
  /**
1576
  * SyndicatedPost::add_rss_meta: adds interesting meta-data to each entry
1577
  * using the space for custom keys. The set of keys and values to add is
@@ -1623,16 +1726,46 @@ class SyndicatedPost {
1623
  endif;
1624
  } /* SyndicatedPost::add_rss_meta () */
1625
 
1626
- // SyndicatedPost::author_id (): get the ID for an author name from
1627
- // the feed. Create the author if necessary.
 
 
 
 
 
 
 
1628
  function author_id ($unfamiliar_author = 'create') {
1629
  global $wpdb;
1630
 
1631
- $a = $this->author();
1632
- $author = $a['name'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1633
  $email = (isset($a['email']) ? $a['email'] : NULL);
1634
  $authorUrl = (isset($a['uri']) ? $a['uri'] : NULL);
1635
 
 
1636
  $hostUrl = $this->link->homepage();
1637
  if (is_null($hostUrl) or (strlen($hostUrl) < 0)) :
1638
  $hostUrl = $this->link->uri();
@@ -1679,7 +1812,9 @@ class SyndicatedPost {
1679
  $authorUrl = $wpdb->escape($authorUrl);
1680
 
1681
  // Check for an existing author rule....
1682
- if (isset($this->link->settings['map authors']['name'][strtolower(trim($author))])) :
 
 
1683
  $author_rule = $this->link->settings['map authors']['name'][strtolower(trim($author))];
1684
  else :
1685
  $author_rule = NULL;
@@ -1744,6 +1879,7 @@ class SyndicatedPost {
1744
  $userdata['user_email'] = $email;
1745
  $userdata['user_url'] = $authorUrl;
1746
  $userdata['display_name'] = $author;
 
1747
 
1748
  do { // Keep trying until you get it right. Or until PHP crashes, I guess.
1749
  $id = wp_insert_user($userdata);
@@ -1778,6 +1914,14 @@ class SyndicatedPost {
1778
 
1779
  if ($id) :
1780
  $this->link->settings['map authors']['name'][strtolower(trim($author))] = $id;
 
 
 
 
 
 
 
 
1781
  endif;
1782
  return $id;
1783
  } // function SyndicatedPost::author_id ()
24
 
25
  var $post = array ();
26
 
27
+ var $named = array ();
28
+ var $preset_terms = array ();
29
+ var $feed_terms = array ();
30
+
31
  var $_freshness = null;
32
  var $_wp_id = null;
33
 
40
  * @param array $item The item syndicated from the feed.
41
  * @param SyndicatedLink $source The feed it was syndicated from.
42
  */
43
+ function SyndicatedPost ($item, &$source) {
44
  global $wpdb;
45
 
46
  if (is_array($item)
49
  $this->entry = $item['simplepie'];
50
  $this->item = $item['magpie'];
51
  $item = $item['magpie'];
52
+ elseif (is_a($item, 'SimplePie_Item')) :
53
+ $this->entry = $item;
54
+
55
+ // convert to Magpie for compat purposes
56
+ $mp = new MagpieFromSimplePie($source->simplepie, $this->entry);
57
+ $this->item = $mp->get_item();
58
+
59
+ // done with conversion object
60
+ $mp = NULL; unset($mp);
61
  else :
62
  $this->item = $item;
63
  endif;
64
 
65
+ $this->link =& $source;
66
  $this->feed = $source->magpie;
67
  $this->feedmeta = $source->settings;
68
 
107
  $this
108
  );
109
  $this->item = $changed;
110
+
111
  # Filters can halt further processing by returning NULL
112
  if (is_null($this->item)) :
113
  $this->post = NULL;
122
  $this->entry->get_title(), $this
123
  );
124
 
125
+ $this->named['author'] = apply_filters(
126
  'syndicated_item_author',
127
  $this->author(), $this
128
  );
139
  if (!empty($excerpt)):
140
  $this->post['post_excerpt'] = $excerpt;
141
  endif;
 
 
 
 
142
 
143
  // Dealing with timestamps in WordPress is so fucking fucked.
144
  $offset = (int) get_option('gmt_offset') * 60 * 60;
145
+ $post_date_gmt = $this->published(array('default' => -1));
146
+ $post_modified_gmt = $this->updated(array('default' => -1));
147
+
148
+ $this->post['post_date_gmt'] = gmdate('Y-m-d H:i:s', $post_date_gmt);
149
+ $this->post['post_date'] = gmdate('Y-m-d H:i:s', $post_date_gmt + $offset);
150
+ $this->post['post_modified_gmt'] = gmdate('Y-m-d H:i:s', $post_modified_gmt);
151
+ $this->post['post_modified'] = gmdate('Y-m-d H:i:s', $post_modified_gmt + $offset);
152
 
153
  // Use feed-level preferences or the global default.
154
  $this->post['post_status'] = $this->link->syndicated_status('post', 'publish');
303
  if (is_array($fc)) :
304
  $cats = array_merge($cats, $fc);
305
  endif;
306
+ $this->preset_terms['category'] = $cats;
307
 
308
  // Now add categories from the post, if we have 'em
309
  $cats = array();
328
  endif;
329
  endforeach; endif;
330
 
331
+ $this->feed_terms['category'] = apply_filters('syndicated_item_categories', $cats, $this);
332
 
333
  // Tags: start with default tags, if any
334
  $tags = array();
341
  if (is_array($ft)) :
342
  $tags = array_merge($tags, $ft);
343
  endif;
344
+ $this->preset_terms['post_tag'] = $tags;
345
 
346
  // Scan post for /a[@rel='tag'] and use as tags if present
347
  $tags = $this->inline_tags();
348
+ $this->feed_terms['post_tag'] = apply_filters('syndicated_item_tags', $tags, $this);
349
 
350
  $taxonomies = $this->link->taxonomies();
351
  $feedTerms = $this->link->setting('terms', NULL, array());
369
  endif;
370
 
371
  // That's all, folks.
372
+ $this->preset_terms[$tax] = $terms;
373
  endif;
374
  endforeach;
375
 
639
  return $permalink;
640
  }
641
 
642
+ function created ($params = array()) {
643
+ $unfiltered = false; $default = NULL;
644
+ extract($params);
645
+
646
  $date = '';
647
  if (isset($this->item['dc']['created'])) :
648
  $date = $this->item['dc']['created'];
652
  $date = $this->item['created'];
653
  endif;
654
 
655
+ $time = new FeedTime($date);
656
+ $ts = $time->timestamp();
657
+ if (!$unfiltered) :
658
+ apply_filters('syndicated_item_created', $ts, $this);
659
+ endif;
660
+ return $ts;
661
  } /* SyndicatedPost::created() */
662
 
663
+ function published ($params = array(), $default = NULL) {
664
+ $fallback = true; $unfiltered = false;
665
+ if (!is_array($params)) : // Old style
666
+ $fallback = $params;
667
+ else : // New style
668
+ extract($params);
669
+ endif;
670
+
671
  $date = '';
672
+ $ts = null;
673
 
674
  # RSS is a fucking mess. Figure out whether we have a date in
675
  # <dc:date>, <issued>, <pubDate>, etc., and get it into Unix
689
 
690
  if (strlen($date) > 0) :
691
  $time = new FeedTime($date);
692
+ $ts = $time->timestamp();
693
  elseif ($fallback) : // Fall back to <updated> / <modified> if present
694
+ $ts = $this->updated(/*fallback=*/ false, /*default=*/ $default);
695
  endif;
696
 
697
  # If everything failed, then default to the current time.
698
+ if (is_null($ts)) :
699
  if (-1 == $default) :
700
+ $ts = time();
701
  else :
702
+ $ts = $default;
703
  endif;
704
  endif;
705
 
706
+ if (!$unfiltered) :
707
+ $ts = apply_filters('syndicated_item_published', $ts, $this);
708
+ endif;
709
+ return $ts;
710
  } /* SyndicatedPost::published() */
711
 
712
+ function updated ($params = array(), $default = -1) {
713
+ $fallback = true; $unfiltered = false;
714
+ if (!is_array($params)) : // Old style
715
+ $fallback = $params;
716
+ else : // New style
717
+ extract($params);
718
+ endif;
719
+
720
  $date = '';
721
+ $ts = null;
722
 
723
  # As far as I know, only dcterms and Atom have reliable ways to
724
  # specify when something was *modified* last. If neither is
729
  $date = $this->item['dcterms']['modified'];
730
  elseif (isset($this->item['modified'])): // Atom 0.3
731
  $date = $this->item['modified'];
732
+ elseif (isset($this->item['updated'])): // Atom 1.0
733
  $date = $this->item['updated'];
734
  endif;
735
 
736
  if (strlen($date) > 0) :
737
  $time = new FeedTime($date);
738
+ $ts = $time->timestamp();
739
  elseif ($fallback) : // Fall back to issued / dc:date
740
+ $ts = $this->published(/*fallback=*/ false, /*default=*/ $default);
741
  endif;
742
 
743
  # If everything failed, then default to the current time.
744
+ if (is_null($ts)) :
745
  if (-1 == $default) :
746
+ $ts = time();
747
  else :
748
+ $ts = $default;
749
  endif;
750
  endif;
751
 
752
+ if (!$unfiltered) :
753
+ apply_filters('syndicated_item_updated', $ts, $this);
754
+ endif;
755
+ return $ts;
756
  } /* SyndicatedPost::updated() */
757
 
758
  function update_hash () {
763
  $guid = null;
764
  if (isset($this->item['id'])): // Atom 0.3 / 1.0
765
  $guid = $this->item['id'];
766
+ elseif (isset($this->item['atom']['id'])) : // Namespaced Atom
767
  $guid = $this->item['atom']['id'];
768
+ elseif (isset($this->item['guid'])) : // RSS 2.0
769
  $guid = $this->item['guid'];
770
+ elseif (isset($this->item['dc']['identifier'])) : // yeah, right
771
  $guid = $this->item['dc']['identifier'];
772
+ endif;
773
+
774
+ // Un-set or too long to use as-is. Generate a tag: URI.
775
+ if (is_null($guid) or strlen($guid) > 250) :
776
+ // In case we need to check this again
777
+ $original_guid = $guid;
778
+
779
  // The feed does not seem to have provided us with a
780
+ // usable unique identifier, so we'll have to cobble
781
+ // together a tag: URI that might work for us. The base
782
+ // of the URI will be the host name of the feed source ...
783
  $bits = parse_url($this->link->uri());
784
  $guid = 'tag:'.$bits['host'];
785
 
786
+ // Some ill-mannered feeds (for example, certain feeds
787
+ // coming from Google Calendar) have extraordinarily long
788
+ // guids -- so long that they exceed the 255 character
789
+ // width of the WordPress guid field. But if the string
790
+ // gets clipped by MySQL, uniqueness tests will fail
791
+ // forever after and the post will be endlessly
792
+ // reduplicated. So, instead, Guids Of A Certain Length
793
+ // are hashed down into a nice, manageable tag: URI.
794
+ if (!is_null($original_guid)) :
795
+ $guid .= ',2010-12-03:id.'.md5($original_guid);
796
+
797
  // If we have a date of creation, then we can use that
798
  // to uniquely identify the item. (On the other hand, if
799
  // the feed producer was consicentious enough to
800
  // generate dates of creation, she probably also was
801
  // conscientious enough to generate unique identifiers.)
802
+ elseif (!is_null($this->created())) :
803
  $guid .= '://post.'.date('YmdHis', $this->created());
804
 
805
  // Otherwise, use both the URI of the item, *and* the
1211
  ");
1212
 
1213
  if (!$result) :
1214
+ $this->_wp_id = NULL;
1215
  $this->_freshness = 2; // New content
1216
  else:
 
 
 
 
 
 
 
 
1217
  preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $result->post_modified_gmt, $backref);
1218
 
1219
  $last_rev_ts = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]);
1220
  $updated_ts = $this->updated(/*fallback=*/ true, /*default=*/ NULL);
1221
 
 
 
 
 
1222
  // Check timestamps...
1223
  $updated = (
1224
  !is_null($updated_ts)
1225
  and ($updated_ts > $last_rev_ts)
1226
  );
1227
 
1228
+ if (!$updated) :
1229
+ // Or the hash...
1230
+ $stored_update_hashes = get_post_custom_values('syndication_item_hash', $result->id);
1231
+ if (count($stored_update_hashes) > 0) :
1232
+ $stored_update_hash = $stored_update_hashes[0];
1233
+ $updated = ($stored_update_hash != $this->update_hash());
1234
+ else :
1235
+ $updated = true; // Can't find syndication meta-data
1236
+ endif;
1237
+ endif;
1238
 
1239
+ $frozen = false;
1240
+ if ($updated) : // Ignore if the post is frozen
1241
+ $frozen = ('yes' == $this->link->setting('freeze updates', 'freeze_updates', NULL));
1242
+ if (!$frozen) :
1243
+ $frozen_values = get_post_custom_values('_syndication_freeze_updates', $result->id);
1244
+ $frozen = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
1245
+ endif;
1246
+ endif;
1247
+ $updated = ($updated and !$frozen);
1248
 
1249
  if ($updated) :
1250
  $this->_freshness = 1; // Updated content
1308
  $taxonomies = array_filter($taxonomies, 'remove_dummy_zero');
1309
 
1310
  $terms = $this->category_ids (
1311
+ $this->feed_terms[$what],
1312
  $this->link->setting("unfamiliar {$what}", "unfamiliar_{$what}", 'create:'.$what),
1313
  /*taxonomies=*/ $taxonomies,
1314
  array(
1348
  endforeach;
1349
 
1350
  // Now let's add on the feed and global presets
1351
+ foreach ($this->preset_terms as $tax => $term_ids) :
1352
  if (!isset($this->post['tax_input'][$tax])) :
1353
  $this->post['tax_input'][$tax] = array();
1354
  endif;
1368
  endif;
1369
 
1370
  if (!$this->filtered() and $freshness > 0) :
1371
+ // Filter some individual fields
1372
+
1373
+ // Allow filters to set post slug. Props niska.
1374
+ $post_name = apply_filters('syndicated_post_slug', NULL, $this);
1375
+ if (!empty($post_name)) :
1376
+ $this->post['post_name'] = $post_name;
1377
+ endif;
1378
+
1379
  $this->post = apply_filters('syndicated_post', $this->post, $this);
1380
+
1381
  // Allow for feed-specific syndicated_post filters.
1382
  $this->post = apply_filters(
1383
  "syndicated_post_".$this->link->uri(),
1394
  /*arguments=*/ 3
1395
  );
1396
 
1397
+ $retval = array(1 => 'updated', 2 => 'new');
1398
+
1399
+ $ret = false;
1400
+ if (!$this->filtered() and isset($retval[$freshness])) :
1401
+ $diag = array(
1402
+ 1 => 'Updating existing post # '.$this->wp_id().', "'.$this->post['post_title'].'"',
1403
+ 2 => 'Inserting new post "'.$this->post['post_title'].'"',
1404
+ );
1405
+ FeedWordPress::diagnostic('syndicated_posts', $diag[$freshness]);
 
1406
 
1407
+ $this->insert_post(/*update=*/ ($freshness == 1));
1408
+
1409
+ $hook = array( 1 => 'update_syndicated_item', 2 => 'post_syndicated_item' );
1410
+ do_action($hook[$freshness], $this->wp_id(), $this);
1411
 
1412
+ $ret = $retval[$freshness];
 
 
1413
  endif;
1414
 
1415
  // Remove add_rss_meta hook
1456
  /*priority=*/ -10001, /* very early */
1457
  /*arguments=*/ 3
1458
  );
1459
+
1460
+ // WP3 appears to override whatever you give it for
1461
+ // post_modified. Ugh.
1462
+ add_action(
1463
+ /*hook=*/ 'transition_post_status',
1464
+ /*callback=*/ array(&$this, 'fix_post_modified_ts'),
1465
+ /*priority=*/ -10000, /* very early */
1466
+ /*arguments=*/ 3
1467
+ );
1468
 
1469
+ if ($update) :
1470
+ $this->post['ID'] = $this->wp_id();
1471
+ $dbpost['ID'] = $this->post['ID'];
1472
+ endif;
1473
  $this->_wp_id = wp_insert_post($dbpost);
1474
 
1475
  remove_action(
1478
  /*priority=*/ -10001, /* very early */
1479
  /*arguments=*/ 3
1480
  );
1481
+
1482
+ remove_action(
1483
+ /*hook=*/ 'transition_post_status',
1484
+ /*callback=*/ array(&$this, 'fix_post_modified_ts'),
1485
+ /*priority=*/ -10000, /* very early */
1486
+ /*arguments=*/ 3
1487
+ );
1488
+
1489
  // Turn off ridiculous fucking kludges #1 and #2
1490
  remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1491
  remove_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1652
  endif;
1653
  } /* SyndicatedPost::add_terms () */
1654
 
1655
+ /**
1656
+ * SyndicatedPost::fix_post_modified_ts() -- We would like to set
1657
+ * post_modified and post_modified_gmt to reflect the value of
1658
+ * <atom:updated> or equivalent elements on the feed. Unfortunately,
1659
+ * wp_insert_post() refuses to acknowledge explicitly-set post_modified
1660
+ * fields and overwrites them, either with the post_date (if new) or the
1661
+ * current timestamp (if updated).
1662
+ *
1663
+ * So, wp_insert_post() is not going to do the last-modified assignments
1664
+ * for us. If you want something done right....
1665
+ *
1666
+ * @param string $new_status Unused action parameter.
1667
+ * @param string $old_status Unused action parameter.
1668
+ * @param object $post The database record for the post just inserted.
1669
+ */
1670
+ function fix_post_modified_ts ($new_status, $old_status, $post) {
1671
+ global $wpdb;
1672
+ $wpdb->update( $wpdb->posts, /*data=*/ array(
1673
+ 'post_modified' => $this->post['post_modified'],
1674
+ 'post_modified_gmt' => $this->post['post_modified_gmt'],
1675
+ ), /*where=*/ array('ID' => $post->ID) );
1676
+ } /* SyndicatedPost::fix_post_modified_ts () */
1677
+
1678
  /**
1679
  * SyndicatedPost::add_rss_meta: adds interesting meta-data to each entry
1680
  * using the space for custom keys. The set of keys and values to add is
1726
  endif;
1727
  } /* SyndicatedPost::add_rss_meta () */
1728
 
1729
+ /**
1730
+ * SyndicatedPost::author_id (): get the ID for an author name from
1731
+ * the feed. Create the author if necessary.
1732
+ *
1733
+ * @param string $unfamiliar_author
1734
+ *
1735
+ * @return NULL|int The numeric ID of the author to attribute the post to
1736
+ * NULL if the post should be filtered out.
1737
+ */
1738
  function author_id ($unfamiliar_author = 'create') {
1739
  global $wpdb;
1740
 
1741
+ $a = $this->named['author'];
1742
+
1743
+ $source = $this->source();
1744
+ $forbidden = apply_filters('feedwordpress_forbidden_author_names',
1745
+ array('admin', 'administrator', 'www', 'root'));
1746
+
1747
+ $candidates = array();
1748
+ $candidates[] = $a['name'];
1749
+ if (!is_null($source)) : $candidates[] = $source['title']; endif;
1750
+ $candidates[] = $this->link->name(/*fromFeed=*/ true);
1751
+ $candidates[] = $this->link->name(/*fromFeed=*/ false);
1752
+ if (strlen($this->link->homepage()) > 0) : $candidates[] = feedwordpress_display_url($this->link->homepage()); endif;
1753
+ $candidates[] = feedwordpress_display_url($this->link->uri());
1754
+ $candidates[] = 'unknown author';
1755
+
1756
+ $author = NULL;
1757
+ while (is_null($author) and ($candidate = each($candidates))) :
1758
+ if (!is_null($candidate['value'])
1759
+ and (strlen(trim($candidate['value'])) > 0)
1760
+ and !in_array(strtolower(trim($candidate['value'])), $forbidden)) :
1761
+ $author = $candidate['value'];
1762
+ endif;
1763
+ endwhile;
1764
+
1765
  $email = (isset($a['email']) ? $a['email'] : NULL);
1766
  $authorUrl = (isset($a['uri']) ? $a['uri'] : NULL);
1767
 
1768
+
1769
  $hostUrl = $this->link->homepage();
1770
  if (is_null($hostUrl) or (strlen($hostUrl) < 0)) :
1771
  $hostUrl = $this->link->uri();
1812
  $authorUrl = $wpdb->escape($authorUrl);
1813
 
1814
  // Check for an existing author rule....
1815
+ if (isset($this->link->settings['map authors']['name']['*'])) :
1816
+ $author_rule = $this->link->settings['map authors']['name']['*'];
1817
+ elseif (isset($this->link->settings['map authors']['name'][strtolower(trim($author))])) :
1818
  $author_rule = $this->link->settings['map authors']['name'][strtolower(trim($author))];
1819
  else :
1820
  $author_rule = NULL;
1879
  $userdata['user_email'] = $email;
1880
  $userdata['user_url'] = $authorUrl;
1881
  $userdata['display_name'] = $author;
1882
+ $userdata['role'] = 'contributor';
1883
 
1884
  do { // Keep trying until you get it right. Or until PHP crashes, I guess.
1885
  $id = wp_insert_user($userdata);
1914
 
1915
  if ($id) :
1916
  $this->link->settings['map authors']['name'][strtolower(trim($author))] = $id;
1917
+
1918
+ // Multisite: Check whether the author has been recorded
1919
+ // on *this* blog before. If not, put her down as a
1920
+ // Contributor for *this* blog.
1921
+ $user = new WP_User((int) $id);
1922
+ if (empty($user->roles)) :
1923
+ $user->add_role('contributor');
1924
+ endif;
1925
  endif;
1926
  return $id;
1927
  } // function SyndicatedPost::author_id ()
updatedpostscontrol.class.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  class UpdatedPostsControl {
3
  var $page;
4
- function UpdatedPostsControl ($page) {
5
  $this->page =& $page;
6
  } /* UpdatedPostsControl constructor */
7
 
1
  <?php
2
  class UpdatedPostsControl {
3
  var $page;
4
+ function UpdatedPostsControl (&$page) {
5
  $this->page =& $page;
6
  } /* UpdatedPostsControl constructor */
7