FeedWordPress - Version 2011.0512

Version Description

  • DIAGNOSTICS IMPROVEMENTS; "THERE MAY BE A BUG IN FEEDWORDPRESS" CRITICAL ERROR NOTICES ELIMINATED: This version includes some major improvements to the Syndication --> Diagnostics section, which should aid in troubleshooting difficulties with items failing to be imported, posts failing to be properly inserted into the database, or updates failing to be recorded. If you have been encountering critical error / bug notices with a white screen and the message "THERE MAY BE A BUG IN FEEDWORDPRESS," followed by an extraordinarily long dump of mostly incomprehensible diagnostic information, you'll be happy to know that the condition causing these notices has been eliminated. In the few cases where errors may still crop up with database insertions, FeedWordPress will now produce a significantly more manageable and more useful diagnostic message.

  • BUGFIX: NEW POSTS FAILING TO APPEAR IN A CLEANLY-INSTALLED FEEDWORDPRESS SYSTEM. If you encountered a recurring problem with FeedWordPress failing to import new posts, after a clean install of FeedWordPress (i.e., not an upgrade from a previous version), this problem may have been the result of a bug with author-handling which has now been fixed in the 2011.0512 release. (If the problem does not go away with the upgrade, this version also includes significant improvements to the Diagnostics system, which will help track down what is causing it in your particular case.)

  • PERFORMANCE: New handling of update hashes allows FeedWordPress to avoid a certain kind of infinite loop, caused when two more more different syndicated feeds each carried a version of the same item (for example, because it appeared on two different aggregator feeds that you're syndicating). In previous versions, when this kind of loop cropped up, syndicated posts could pile up an indefinitely large number of revisions -- each revision alternating between the version from each of the two feeds where it appeared -- which would, over time, dramatically inflate the size of the database, and kill the performance of queries on the post table. This issue has been resolved: revisions of the post that have been syndicated once will not be re-syndicated over and over again.

  • AUTHOR LISTS: Lists of authors presented on the Author settings pages should now be easier to scan through, with author names arranged in alphabetical order.

  • FEED ITEM DATE PARSING: More tweaks to make date-time handling more resilient when feeds provide broken or weird values for the timestamps on syndicated items. FWP will now attempt to work around unparseable timezone values.

  • AUTHOR MATCHING: Now attempts to match author names against the WP login name in addition to display_name; when creating user record, also fills in some best-guess values for nickname, firstname and lastname. Also properly picks up Atom 1.0 author/uri data from feed.

  • COMPATIBILITY: FeedWordPress has been successfully tested for compatibility with recent releases of WordPress, up to version 3.1.2.

Download this release

Release Info

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

Code changes from version 2011.0211.2 to 2011.0512

authors-page.php CHANGED
@@ -24,6 +24,9 @@ class FeedWordPressAuthorsPage extends FeedWordPressAdminPage {
24
 
25
  function refresh_author_list () {
26
  $this->authorlist = fwp_author_list();
 
 
 
27
  }
28
 
29
  /*static*/ function syndicated_authors_box ($page, $box = NULL) {
@@ -45,6 +48,26 @@ class FeedWordPressAuthorsPage extends FeedWordPressAdminPage {
45
  ?>
46
  <table class="form-table">
47
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  if ($page->for_feed_settings()) :
49
  $map = $this->link->setting('map authors', NULL, array());
50
  ?>
@@ -55,8 +78,10 @@ authors?</p>
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');">
24
 
25
  function refresh_author_list () {
26
  $this->authorlist = fwp_author_list();
27
+
28
+ // Case-insensitive "natural" alphanumeric sort. Preserves key/value associations.
29
+ if (function_exists('natcasesort')) : natcasesort($this->authorlist); endif;
30
  }
31
 
32
  /*static*/ function syndicated_authors_box ($page, $box = NULL) {
48
  ?>
49
  <table class="form-table">
50
  <?php
51
+ if ($page->for_default_settings()) :
52
+ ?>
53
+ <tr><th>Unmatched authors</th>
54
+ <td><span>Authors who haven&#8217;t been syndicated before</span>
55
+ <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');">
56
+ <option value="create"<?php print $unfamiliar['create']; ?>>will have a new author account created for them</option>
57
+ <?php foreach ($page->authorlist as $author_id => $author_name) : ?>
58
+ <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>
59
+ <?php endforeach; ?>
60
+ <option value="newuser">will have their posts attributed to a new user...</option>
61
+ <option value="filter"<?php print $unfamiliar['filter'] ?>>get filtered out</option>
62
+ </select>
63
+
64
+ <span id="unfamiliar-author-newuser">named <input type="text" name="unfamiliar_author_newuser" value="" /></span></p>
65
+ </td>
66
+ </tr>
67
+
68
+ <?php
69
+ endif;
70
+
71
  if ($page->for_feed_settings()) :
72
  $map = $this->link->setting('map authors', NULL, array());
73
  ?>
78
  <li><p><input type="radio" name="author_rules_name[all]" value="*"
79
  <?php if (isset($map['name']['*'])) : $author_action = $map['name']['*']; ?>
80
  checked="checked"
81
+ <?php
82
+ else :
83
+ $author_action = NULL;
84
+ endif; ?>
85
  /> All posts syndicated
86
  from this feed <select class="author-rules" id="author-rules-all"
87
  name="author_rules_action[all]" onchange="contextual_appearance('author-rules-all', 'author-rules-all-newuser', 'author-rules-all-default', 'newuser', 'inline');">
diagnostics-page.php CHANGED
@@ -228,7 +228,7 @@ testing but absolutely inappropriate for a production server.</p>
228
  $hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
229
  $fields = apply_filters('feedwordpress_diagnostics', array(
230
  'Update Diagnostics' => array(
231
- 'updated_feeds' => 'as each feed checked for updates',
232
  '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',
233
  'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
234
  'syndicated_posts' => 'as each syndicated post is added to the database',
@@ -236,6 +236,8 @@ testing but absolutely inappropriate for a production server.</p>
236
  'memory_usage' => 'indicating how much memory was used',
237
  ),
238
  'Syndicated Post Details' => array(
 
 
239
  'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
240
  ),
241
  ), $page);
228
  $hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
229
  $fields = apply_filters('feedwordpress_diagnostics', array(
230
  'Update Diagnostics' => array(
231
+ 'updated_feeds' => 'as each feed is checked for updates',
232
  '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',
233
  'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
234
  'syndicated_posts' => 'as each syndicated post is added to the database',
236
  'memory_usage' => 'indicating how much memory was used',
237
  ),
238
  'Syndicated Post Details' => array(
239
+ 'feed_items:freshness' => 'as FeedWordPress decides whether to treat an item as a new post, an update, or a duplicate of an existing post',
240
+ 'feed_items:rejected' => 'when FeedWordPress rejects a post without syndicating it',
241
  'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
242
  ),
243
  ), $page);
feedtime.class.php CHANGED
@@ -11,7 +11,7 @@ class FeedTime {
11
  $this->set($time);
12
  } /* FeedTime constructor */
13
 
14
- function set ($time) {
15
  $this->rep = $time;
16
  $this->ts = NULL;
17
  if (is_numeric($time)) : // Presumably a Unix-epoch timestamp
@@ -23,7 +23,7 @@ class FeedTime {
23
  if ($this->failed()) :
24
  // In some versions of PHP, strtotime() does not support
25
  // the UT timezone. Since UT is by definition within 1
26
- // second of UTC, we'll just convert it here to avoid
27
  // problems.
28
  $time = preg_replace(
29
  '/(\s)UT$/',
@@ -31,6 +31,12 @@ class FeedTime {
31
  $time
32
  );
33
  $this->ts = strtotime($time);
 
 
 
 
 
 
34
  endif;
35
  endif;
36
  } /* FeedTime::set() */
11
  $this->set($time);
12
  } /* FeedTime constructor */
13
 
14
+ function set ($time, $recurse = false) {
15
  $this->rep = $time;
16
  $this->ts = NULL;
17
  if (is_numeric($time)) : // Presumably a Unix-epoch timestamp
23
  if ($this->failed()) :
24
  // In some versions of PHP, strtotime() does not support
25
  // the UT timezone. Since UT is by definition within 1
26
+ // second of UTC, we'll just convert it preemptively to avoid
27
  // problems.
28
  $time = preg_replace(
29
  '/(\s)UT$/',
31
  $time
32
  );
33
  $this->ts = strtotime($time);
34
+
35
+ if ($this->failed()
36
+ and preg_match('/^(.*)([+\-][0-9]+|\s+[A-Za-z]{1,3})$/', $time, $matches)) :
37
+ // Try dropping the time zone and recurse
38
+ $this->set($matches[1], /*recurse=*/ true);
39
+ endif;
40
  endif;
41
  endif;
42
  } /* FeedTime::set() */
feedwordpress.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: FeedWordPress
4
  Plugin URI: http://feedwordpress.radgeek.com/
5
  Description: simple and flexible Atom/RSS syndication for WordPress
6
- Version: 2011.0211.2
7
  Author: Charles Johnson
8
  Author URI: http://radgeek.com/
9
  License: GPL
@@ -11,7 +11,7 @@ License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
- * @version 2011.0211.2
15
  */
16
 
17
  # This uses code derived from:
@@ -34,7 +34,7 @@ License: GPL
34
 
35
  # -- Don't change these unless you know what you're doing...
36
 
37
- define ('FEEDWORDPRESS_VERSION', '2011.0211.2');
38
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
39
 
40
  if (!defined('FEEDWORDPRESS_BLEG')) :
@@ -1059,7 +1059,7 @@ class FeedWordPress {
1059
 
1060
  // This should never happen.
1061
  else :
1062
- FeedWordPress::critical_bug('FeedWordPress::stale::last', $last, __LINE__);
1063
  endif;
1064
 
1065
  else :
@@ -1577,23 +1577,29 @@ class FeedWordPress {
1577
  }
1578
 
1579
  # Internal debugging functions
1580
- function critical_bug ($varname, $var, $line) {
1581
  global $wp_version;
1582
-
1583
- echo '<p>There may be a bug in FeedWordPress. Please <a href="'.FEEDWORDPRESS_AUTHOR_CONTACT.'">contact the author</a> and paste the following information into your e-mail:</p>';
1584
- echo "\n<plaintext>";
1585
- echo "Triggered at line # ".$line."\n";
1586
- echo "FeedWordPress version: ".FEEDWORDPRESS_VERSION."\n";
1587
- echo "WordPress version: {$wp_version}\n";
1588
- echo "PHP version: ".phpversion()."\n";
1589
- echo "\n";
1590
- echo $varname.": "; var_dump($var); echo "\n";
 
 
 
 
 
 
1591
  die;
1592
  }
1593
 
1594
- function noncritical_bug ($varname, $var, $line) {
1595
  if (FEEDWORDPRESS_DEBUG) : // halt only when we are doing debugging
1596
- FeedWordPress::critical_bug($varname, $var, $line);
1597
  endif;
1598
  }
1599
 
@@ -1625,7 +1631,9 @@ class FeedWordPress {
1625
  foreach ($output as $method) :
1626
  switch ($method) :
1627
  case 'echo' :
1628
- echo "<div><pre><strong>Diag".str_repeat('====', $diagnostic_nesting-1).'|</strong> '.$out."</pre></div>";
 
 
1629
  break;
1630
  case 'echo_in_cronjob' :
1631
  if (FeedWordPress::update_requested()) :
3
  Plugin Name: FeedWordPress
4
  Plugin URI: http://feedwordpress.radgeek.com/
5
  Description: simple and flexible Atom/RSS syndication for WordPress
6
+ Version: 2011.0512
7
  Author: Charles Johnson
8
  Author URI: http://radgeek.com/
9
  License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
+ * @version 2011.0512
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.0512');
38
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
39
 
40
  if (!defined('FEEDWORDPRESS_BLEG')) :
1059
 
1060
  // This should never happen.
1061
  else :
1062
+ FeedWordPress::critical_bug('FeedWordPress::stale::last', $last, __LINE__, __FILE__);
1063
  endif;
1064
 
1065
  else :
1577
  }
1578
 
1579
  # Internal debugging functions
1580
+ function critical_bug ($varname, $var, $line, $file = NULL) {
1581
  global $wp_version;
1582
+
1583
+ if (!is_null($file)) :
1584
+ $location = "line # ${line} of ".basename($file);
1585
+ else :
1586
+ $location = "line # ${line}";
1587
+ endif;
1588
+
1589
+ print '<p><strong>Critical error:</strong> There may be a bug in FeedWordPress. Please <a href="'.FEEDWORDPRESS_AUTHOR_CONTACT.'">contact the author</a> and paste the following information into your e-mail:</p>';
1590
+ print "\n<plaintext>";
1591
+ print "Triggered at ${location}\n";
1592
+ print "FeedWordPress: ".FEEDWORDPRESS_VERSION."\n";
1593
+ print "WordPress: {$wp_version}\n";
1594
+ print "PHP: ".phpversion()."\n";
1595
+ print "Error data: ";
1596
+ print $varname.": "; var_dump($var); echo "\n";
1597
  die;
1598
  }
1599
 
1600
+ function noncritical_bug ($varname, $var, $line, $file = NULL) {
1601
  if (FEEDWORDPRESS_DEBUG) : // halt only when we are doing debugging
1602
+ FeedWordPress::critical_bug($varname, $var, $line, $file);
1603
  endif;
1604
  }
1605
 
1631
  foreach ($output as $method) :
1632
  switch ($method) :
1633
  case 'echo' :
1634
+ if (!FeedWordPress::update_requested()) :
1635
+ echo "<div><pre><strong>Diag".str_repeat('====', $diagnostic_nesting-1).'|</strong> '.$out."</pre></div>";
1636
+ endif;
1637
  break;
1638
  case 'echo_in_cronjob' :
1639
  if (FeedWordPress::update_requested()) :
feedwordpresssyndicationpage.class.php CHANGED
@@ -93,7 +93,7 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
93
  $update_set[] = $target->link_rss;
94
  endforeach;
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');
93
  $update_set[] = $target->link_rss;
94
  endforeach;
95
  else : // This should never happen
96
+ FeedWordPress::critical_bug('fwp_syndication_manage_page::targets', $targets, __LINE__, __FILE__);
97
  endif;
98
  elseif (!is_null(FeedWordPress::post('update_uri'))) :
99
  $targets = FeedWordPress::post('update_uri');
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.5
7
- Stable tag: 2011.0211.2
8
 
9
  FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
10
 
@@ -93,6 +93,108 @@ outs, see the documentation at the [FeedWordPress project homepage][].
93
 
94
  == Changelog ==
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  = 2010.0905 =
97
 
98
  * BUGFIX: CATEGORIES AND TAGS CORRECTLY ASSIGNED IN AUTOMATIC UPDATES.
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.1.2
7
+ Stable tag: 2011.0512
8
 
9
  FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
10
 
93
 
94
  == Changelog ==
95
 
96
+ = 2011.0512 =
97
+
98
+ * DIAGNOSTICS IMPROVEMENTS; "THERE MAY BE A BUG IN FEEDWORDPRESS" CRITICAL
99
+ ERROR NOTICES ELIMINATED: This version includes some major improvements
100
+ to the Syndication --> Diagnostics section, which should aid in
101
+ troubleshooting difficulties with items failing to be imported, posts
102
+ failing to be properly inserted into the database, or updates failing to
103
+ be recorded. If you have been encountering critical error / bug notices
104
+ with a white screen and the message "THERE MAY BE A BUG IN
105
+ FEEDWORDPRESS," followed by an extraordinarily long dump of mostly
106
+ incomprehensible diagnostic information, you'll be happy to know that
107
+ the condition causing these notices has been eliminated. In the few
108
+ cases where errors may still crop up with database insertions,
109
+ FeedWordPress will now produce a significantly more manageable and more
110
+ useful diagnostic message.
111
+
112
+ * BUGFIX: NEW POSTS FAILING TO APPEAR IN A CLEANLY-INSTALLED FEEDWORDPRESS
113
+ SYSTEM. If you encountered a recurring problem with FeedWordPress
114
+ failing to import new posts, after a clean install of FeedWordPress
115
+ (i.e., not an upgrade from a previous version), this problem may have
116
+ been the result of a bug with author-handling which has now been fixed
117
+ in the 2011.0512 release. (If the problem does *not* go away with the
118
+ upgrade, this version also includes significant improvements to the
119
+ Diagnostics system, which will help track down what *is* causing it
120
+ in your particular case.)
121
+
122
+ * PERFORMANCE: New handling of update hashes allows FeedWordPress to avoid
123
+ a certain kind of infinite loop, caused when two more more different
124
+ syndicated feeds each carried a version of the same item (for example,
125
+ because it appeared on two different aggregator feeds that you're
126
+ syndicating). In previous versions, when this kind of loop cropped up,
127
+ syndicated posts could pile up an indefinitely large number of revisions
128
+ -- each revision alternating between the version from each of the two
129
+ feeds where it appeared -- which would, over time, dramatically inflate
130
+ the size of the database, and kill the performance of queries on the
131
+ post table. This issue has been resolved: revisions of the post that
132
+ have been syndicated once will not be re-syndicated over and over again.
133
+
134
+ * AUTHOR LISTS: Lists of authors presented on the Author settings pages
135
+ should now be easier to scan through, with author names arranged in
136
+ alphabetical order.
137
+
138
+ * FEED ITEM DATE PARSING: More tweaks to make date-time handling more
139
+ resilient when feeds provide broken or weird values for the timestamps
140
+ on syndicated items. FWP will now attempt to work around unparseable
141
+ timezone values.
142
+
143
+ * AUTHOR MATCHING: Now attempts to match author names against the WP login
144
+ name in addition to display_name; when creating user record, also fills
145
+ in some best-guess values for nickname, firstname and lastname. Also
146
+ properly picks up Atom 1.0 author/uri data from feed.
147
+
148
+ * COMPATIBILITY: FeedWordPress has been successfully tested for
149
+ compatibility with recent releases of WordPress, up to version 3.1.2.
150
+
151
+ = 2011.0211 =
152
+
153
+ * BUGFIX: DUPLICATE POSTS WHEN GUIDS ARE TOO LONG: When feeds included
154
+ exceptionally long GUIDs, FeedWordPress could occasionally get into
155
+ a situation where posts with the long GUIDs would be duplicated over
156
+ and over again with each update (because FWP failed to store the full
157
+ GUID, due to length constraints in the relevant database tables).
158
+ Without the full GUID, FWP would not know that the post had already
159
+ been syndicated once. This bug has been fixed, and should no longer
160
+ produce duplicate posts.
161
+
162
+ * HTTP TIMEOUT SETTING: If you are frequently running into timeout
163
+ problems with one or more of the feeds you syndicate, FWP now allows you
164
+ to adjust the timeout for HTTP requests using a global or feed-by-feed
165
+ setting.
166
+
167
+ * HTTP GET PARAMETERS: You can now temporarily or permanently add HTTP
168
+ GET parameters to a subscription using an interface in Syndication -->
169
+ Feeds & Updates. This is especially helpful for making quick, short-term
170
+ changes to a subscription (for example, to pull in all the previous
171
+ items from a web service, before settling down to pulling in only newly
172
+ updated items).
173
+
174
+ * DIAGNOSTICS SYSTEM: Added several new diagnostics which are useful in
175
+ troubleshooting, and established a framework for add-on modules to hook
176
+ in with their own diagnostic messages.
177
+
178
+ * UI: Adjusted some internal coding, which should allow for settings
179
+ pages and add-ons to properly display multiple category pickers on a
180
+ single settings page.
181
+
182
+ * PHP4 COMPATIBILITY TWEAKS: This version makes some tweaks to the handling
183
+ of object references which should improve compatibility with older
184
+ versions of PHP. (Although, I should note, web hosts that still force
185
+ you to run under PHP 4 -- in 2011! -- are *bad web hosts*.)
186
+
187
+ * IMPROVED PERFORMANCE: This version eliminates a *major* performance drag
188
+ that shows up on sites with large numbers of users (due to some poor
189
+ decisions about where to place a user query, which caused the user table
190
+ to be scanned frequently when it did not need to be). If you experienced
191
+ serious problems with CPU load or slow database performance under
192
+ 2010.0905, which kicked in immediately when FWP was loaded and tended
193
+ to disappear immediately if FWP was de-activated, it is likely that
194
+ upgrading away from 2010.0905 to the most recent version will resolve
195
+ your problem.
196
+
197
+
198
  = 2010.0905 =
199
 
200
  * BUGFIX: CATEGORIES AND TAGS CORRECTLY ASSIGNED IN AUTOMATIC UPDATES.
syndicatedpost.class.php CHANGED
@@ -755,6 +755,20 @@ class SyndicatedPost {
755
  return $ts;
756
  } /* SyndicatedPost::updated() */
757
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
758
  function update_hash () {
759
  return md5(serialize($this->item));
760
  } /* SyndicatedPost::update_hash() */
@@ -859,8 +873,12 @@ class SyndicatedPost {
859
  $author['email'] = $this->feed->channel['author_email'];
860
  endif;
861
 
862
- if (isset($this->item['author_url'])):
 
 
863
  $author['uri'] = $this->item['author_url'];
 
 
864
  elseif (isset($this->feed->channel['author_url'])) :
865
  $author['uri'] = $this->item['author_url'];
866
  elseif (isset($this->feed->channel['link'])) :
@@ -1199,10 +1217,10 @@ class SyndicatedPost {
1199
  global $wpdb;
1200
 
1201
  if ($this->filtered()) : // This should never happen.
1202
- FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__);
1203
  endif;
1204
 
1205
- if (is_null($this->_freshness)) :
1206
  $guid = $wpdb->escape($this->guid());
1207
 
1208
  $result = $wpdb->get_row("
@@ -1210,10 +1228,11 @@ class SyndicatedPost {
1210
  FROM $wpdb->posts WHERE guid='$guid'
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]);
@@ -1225,12 +1244,13 @@ class SyndicatedPost {
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;
@@ -1247,9 +1267,19 @@ class SyndicatedPost {
1247
  $updated = ($updated and !$frozen);
1248
 
1249
  if ($updated) :
 
1250
  $this->_freshness = 1; // Updated content
1251
  $this->_wp_id = $result->id;
 
 
 
 
 
 
 
 
1252
  else :
 
1253
  $this->_freshness = 0; // Same old, same old
1254
  $this->_wp_id = $result->id;
1255
  endif;
@@ -1264,7 +1294,7 @@ class SyndicatedPost {
1264
 
1265
  function wp_id () {
1266
  if ($this->filtered()) : // This should never happen.
1267
- FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__);
1268
  endif;
1269
 
1270
  if (is_null($this->_wp_id) and is_null($this->_freshness)) :
@@ -1277,7 +1307,7 @@ class SyndicatedPost {
1277
  global $wpdb;
1278
 
1279
  if ($this->filtered()) : // This should never happen.
1280
- FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__);
1281
  endif;
1282
 
1283
  $freshness = $this->freshness();
@@ -1288,6 +1318,7 @@ class SyndicatedPost {
1288
  );
1289
 
1290
  if (is_null($this->post['post_author'])) :
 
1291
  $this->post = NULL;
1292
  endif;
1293
  endif;
@@ -1436,7 +1467,14 @@ class SyndicatedPost {
1436
  // Kludge to prevent kses filters from stripping the
1437
  // content of posts when updating without a logged in
1438
  // user who has `unfiltered_html` capability.
1439
- add_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
 
 
 
 
 
 
 
1440
 
1441
  if ($update and function_exists('get_post_field')) :
1442
  // Don't munge status fields that the user may
@@ -1470,7 +1508,7 @@ class SyndicatedPost {
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(
1476
  /*hook=*/ 'transition_post_status',
@@ -1488,9 +1526,11 @@ class SyndicatedPost {
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);
1492
-
1493
- $this->validate_post_id($dbpost, array(__CLASS__, __FUNCTION__));
 
 
1494
  endif;
1495
  } /* function SyndicatedPost::insert_post () */
1496
 
@@ -1550,20 +1590,41 @@ class SyndicatedPost {
1550
  * @param array $dbpost An array representing the post we attempted to insert or update
1551
  * @param mixed $ns A string or array representing the namespace (class, method) whence this method was called.
1552
  */
1553
- function validate_post_id ($dbpost, $ns) {
1554
  if (is_array($ns)) : $ns = implode('::', $ns);
1555
  else : $ns = (string) $ns; endif;
1556
-
1557
  // This should never happen.
1558
  if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
1559
- FeedWordPress::critical_bug(
1560
- /*name=*/ $ns.'::_wp_id',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1561
  /*var =*/ array(
1562
  "\$this->_wp_id" => $this->_wp_id,
1563
  "\$dbpost" => $dbpost,
1564
- "\$this" => $this
1565
  ),
1566
- /*line # =*/ __LINE__
1567
  );
1568
  endif;
1569
  } /* SyndicatedPost::validate_post_id() */
@@ -1597,31 +1658,6 @@ class SyndicatedPost {
1597
  WHERE post_type = 'revision' AND ID='$revision_id'
1598
  ");
1599
  } /* SyndicatedPost::fix_revision_meta () */
1600
-
1601
- /**
1602
- * SyndicatedPost::avoid_kses_munge() -- If FeedWordPress is processing
1603
- * an automatic update, that generally means that wp_insert_post() is
1604
- * being called under the user credentials of whoever is viewing the
1605
- * blog at the time -- usually meaning no user at all. But if WordPress
1606
- * gets a wp_insert_post() when current_user_can('unfiltered_html') is
1607
- * false, it will run the content of the post through a kses function
1608
- * that strips out lots of HTML tags -- notably <object> and some others.
1609
- * This causes problems for syndicating (for example) feeds that contain
1610
- * YouTube videos. It also produces an unexpected asymmetry between
1611
- * automatically-initiated updates and updates initiated manually from
1612
- * the WordPress Dashboard (which are usually initiated under the
1613
- * credentials of a logged-in admin, and so don't get run through the
1614
- * kses function). So, to avoid the whole mess, what we do here is
1615
- * just forcibly disable the kses munging for a single syndicated post,
1616
- * by restoring the contents of the `post_content` field.
1617
- *
1618
- * @param string $content The content of the post, after other filters have gotten to it
1619
- * @return string The original content of the post, before other filters had a chance to munge it.
1620
- */
1621
- function avoid_kses_munge ($content) {
1622
- global $wpdb;
1623
- return $wpdb->escape($this->post['post_content']);
1624
- }
1625
 
1626
  /**
1627
  * SyndicatedPost::add_terms() -- if FeedWordPress is processing an
@@ -1641,14 +1677,15 @@ class SyndicatedPost {
1641
  * @param object $post The database record for the post just inserted.
1642
  */
1643
  function add_terms ($new_status, $old_status, $post) {
1644
- if ( is_array($this->post) and isset($this->post['tax_input']) and is_array($this->post['tax_input']) ) :
1645
- foreach ($this->post['tax_input'] as $taxonomy => $terms) :
1646
- if (is_array($terms)) :
1647
- $terms = array_filter($terms); // strip out empties
1648
- endif;
1649
-
1650
- wp_set_post_terms($post->ID, $terms, $taxonomy);
1651
- endforeach;
 
1652
  endif;
1653
  } /* SyndicatedPost::add_terms () */
1654
 
@@ -1669,10 +1706,12 @@ class SyndicatedPost {
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
  /**
@@ -1691,38 +1730,40 @@ class SyndicatedPost {
1691
  * @param object $post The database record for the post just inserted.
1692
  */
1693
  function add_rss_meta ($new_status, $old_status, $post) {
1694
- FeedWordPress::diagnostic('syndicated_posts:meta_data', 'Adding post meta-data: {'.implode(", ", array_keys($this->post['meta'])).'}');
1695
-
1696
  global $wpdb;
1697
- if ( is_array($this->post) and isset($this->post['meta']) and is_array($this->post['meta']) ) :
1698
- $postId = $post->ID;
1699
-
1700
- // Aggregated posts should NOT send out pingbacks.
1701
- // WordPress 2.1-2.2 claim you can tell them not to
1702
- // using $post_pingback, but they don't listen, so we
1703
- // make sure here.
1704
- $result = $wpdb->query("
1705
- DELETE FROM $wpdb->postmeta
1706
- WHERE post_id='$postId' AND meta_key='_pingme'
1707
- ");
1708
-
1709
- foreach ( $this->post['meta'] as $key => $values ) :
1710
- $eKey = $wpdb->escape($key);
1711
 
1712
- // If this is an update, clear out the old
1713
- // values to avoid duplication.
 
 
 
 
 
1714
  $result = $wpdb->query("
1715
  DELETE FROM $wpdb->postmeta
1716
- WHERE post_id='$postId' AND meta_key='$eKey'
1717
  ");
1718
-
1719
- // Allow for either a single value or an array
1720
- if (!is_array($values)) $values = array($values);
1721
- foreach ( $values as $value ) :
1722
- FeedWordPress::diagnostic('syndicated_posts:meta_data', "Adding post meta-datum to post [$postId]: [$key] = ".FeedWordPress::val($value, /*no newlines=*/ true));
1723
- add_post_meta($postId, $key, $value, /*unique=*/ false);
 
 
 
 
 
 
 
 
 
 
 
1724
  endforeach;
1725
- endforeach;
1726
  endif;
1727
  } /* SyndicatedPost::add_rss_meta () */
1728
 
@@ -1739,11 +1780,17 @@ class SyndicatedPost {
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;
@@ -1753,6 +1800,9 @@ class SyndicatedPost {
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'])
@@ -1835,6 +1885,7 @@ class SyndicatedPost {
1835
  $id = $wpdb->get_var(
1836
  "SELECT ID FROM $wpdb->users
1837
  WHERE TRIM(LCASE(display_name)) = TRIM(LCASE('$author'))
 
1838
  OR (
1839
  LENGTH(TRIM(LCASE(user_email))) > 0
1840
  AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
@@ -1878,6 +1929,10 @@ class SyndicatedPost {
1878
  $userdata['user_pass'] = substr(md5(uniqid(microtime())), 0, 6); // just something random to lock it up
1879
  $userdata['user_email'] = $email;
1880
  $userdata['user_url'] = $authorUrl;
 
 
 
 
1881
  $userdata['display_name'] = $author;
1882
  $userdata['role'] = 'contributor';
1883
 
@@ -1924,7 +1979,7 @@ class SyndicatedPost {
1924
  endif;
1925
  endif;
1926
  return $id;
1927
- } // function SyndicatedPost::author_id ()
1928
 
1929
  /**
1930
  * category_ids: look up (and create) category ids from a list of categories
@@ -2007,7 +2062,7 @@ class SyndicatedPost {
2007
  endif;
2008
  $term = wp_insert_term($cat_name, $tax);
2009
  if (is_wp_error($term)) :
2010
- FeedWordPress::noncritical_bug('term insertion problem', array('cat_name' => $cat_name, 'term' => $term, 'this' => $this), __LINE__);
2011
  else :
2012
  if (!isset($terms[$tax])) :
2013
  $terms[$tax] = array();
755
  return $ts;
756
  } /* SyndicatedPost::updated() */
757
 
758
+ var $_hashes = array();
759
+ function stored_hashes ($id = NULL) {
760
+ if (is_null($id)) :
761
+ $id = $this->wp_id();
762
+ endif;
763
+
764
+ if (!isset($this->_hashes[$id])) :
765
+ $this->_hashes[$id] = get_post_custom_values(
766
+ 'syndication_item_hash', $id
767
+ );
768
+ endif;
769
+ return $this->_hashes[$id];
770
+ }
771
+
772
  function update_hash () {
773
  return md5(serialize($this->item));
774
  } /* SyndicatedPost::update_hash() */
873
  $author['email'] = $this->feed->channel['author_email'];
874
  endif;
875
 
876
+ if (isset($this->item['author_uri'])):
877
+ $author['uri'] = $this->item['author_uri'];
878
+ elseif (isset($this->item['author_url'])):
879
  $author['uri'] = $this->item['author_url'];
880
+ elseif (isset($this->feed->channel['author_uri'])) :
881
+ $author['uri'] = $this->item['author_uri'];
882
  elseif (isset($this->feed->channel['author_url'])) :
883
  $author['uri'] = $this->item['author_url'];
884
  elseif (isset($this->feed->channel['link'])) :
1217
  global $wpdb;
1218
 
1219
  if ($this->filtered()) : // This should never happen.
1220
+ FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
1221
  endif;
1222
 
1223
+ if (is_null($this->_freshness)) : // Not yet checked and cached.
1224
  $guid = $wpdb->escape($this->guid());
1225
 
1226
  $result = $wpdb->get_row("
1228
  FROM $wpdb->posts WHERE guid='$guid'
1229
  ");
1230
 
1231
+ if (!$result) : // No post with this guid
1232
+ FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$this->guid().'] "'.$this->entry->get_title().'" is a NEW POST.');
1233
  $this->_wp_id = NULL;
1234
  $this->_freshness = 2; // New content
1235
+ else :
1236
  preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $result->post_modified_gmt, $backref);
1237
 
1238
  $last_rev_ts = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]);
1244
  and ($updated_ts > $last_rev_ts)
1245
  );
1246
 
1247
+
1248
  if (!$updated) :
1249
  // Or the hash...
1250
+ $hash = $this->update_hash();
1251
+ $seen = $this->stored_hashes($result->id);
1252
+ if (count($seen) > 0) :
1253
+ $updated = !in_array($hash, $seen); // Not seen yet?
1254
  else :
1255
  $updated = true; // Can't find syndication meta-data
1256
  endif;
1267
  $updated = ($updated and !$frozen);
1268
 
1269
  if ($updated) :
1270
+ FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$this->guid().'] "'.$this->entry->get_title().'" is an update of an existing post.');
1271
  $this->_freshness = 1; // Updated content
1272
  $this->_wp_id = $result->id;
1273
+
1274
+ // We want this to keep a running list of all the
1275
+ // processed update hashes.
1276
+ $this->post['meta']['syndication_item_hash'] = array_merge(
1277
+ $this->stored_hashes(),
1278
+ array($this->update_hash())
1279
+ );
1280
+
1281
  else :
1282
+ FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$this->guid().'] "'.$this->entry->get_title().'" is a duplicate of an existing post.');
1283
  $this->_freshness = 0; // Same old, same old
1284
  $this->_wp_id = $result->id;
1285
  endif;
1294
 
1295
  function wp_id () {
1296
  if ($this->filtered()) : // This should never happen.
1297
+ FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
1298
  endif;
1299
 
1300
  if (is_null($this->_wp_id) and is_null($this->_freshness)) :
1307
  global $wpdb;
1308
 
1309
  if ($this->filtered()) : // This should never happen.
1310
+ FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
1311
  endif;
1312
 
1313
  $freshness = $this->freshness();
1318
  );
1319
 
1320
  if (is_null($this->post['post_author'])) :
1321
+ FeedWordPress::diagnostic('feed_items:rejected', 'Filtered out item ['.$this->guid().'] without syndication: no author available');
1322
  $this->post = NULL;
1323
  endif;
1324
  endif;
1467
  // Kludge to prevent kses filters from stripping the
1468
  // content of posts when updating without a logged in
1469
  // user who has `unfiltered_html` capability.
1470
+ $mungers = array('wp_filter_kses', 'wp_filter_post_kses');
1471
+ $removed = array();
1472
+ foreach ($mungers as $munger) :
1473
+ if (has_filter('content_save_pre', $munger)) :
1474
+ remove_filter('content_save_pre', $munger);
1475
+ $removed[] = $munger;
1476
+ endif;
1477
+ endforeach;
1478
 
1479
  if ($update and function_exists('get_post_field')) :
1480
  // Don't munge status fields that the user may
1508
  $this->post['ID'] = $this->wp_id();
1509
  $dbpost['ID'] = $this->post['ID'];
1510
  endif;
1511
+ $this->_wp_id = wp_insert_post($dbpost, /*return wp_error=*/ true);
1512
 
1513
  remove_action(
1514
  /*hook=*/ 'transition_post_status',
1526
 
1527
  // Turn off ridiculous fucking kludges #1 and #2
1528
  remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1529
+ foreach ($removed as $filter) :
1530
+ add_filter('content_save_pre', $removed);
1531
+ endforeach;
1532
+
1533
+ $this->validate_post_id($dbpost, $update, array(__CLASS__, __FUNCTION__));
1534
  endif;
1535
  } /* function SyndicatedPost::insert_post () */
1536
 
1590
  * @param array $dbpost An array representing the post we attempted to insert or update
1591
  * @param mixed $ns A string or array representing the namespace (class, method) whence this method was called.
1592
  */
1593
+ function validate_post_id ($dbpost, $is_update, $ns) {
1594
  if (is_array($ns)) : $ns = implode('::', $ns);
1595
  else : $ns = (string) $ns; endif;
1596
+
1597
  // This should never happen.
1598
  if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
1599
+ $verb = ($is_update ? 'update existing' : 'insert new');
1600
+ $guid = $this->guid();
1601
+ $url = $this->permalink();
1602
+ $feed = $this->link->uri(array('add_params' => true));
1603
+
1604
+ // wp_insert_post failed. Diagnostics, or barf up a critical bug
1605
+ // notice if we are in debug mode.
1606
+ $mesg = "Failed to $verb item [$guid]. WordPress API returned no valid post ID.\n"
1607
+ ."\t\tID = ".serialize($this->_wp_id)."\n"
1608
+ ."\t\tURL = ".FeedWordPress::val($url)
1609
+ ."\t\tFeed = ".FeedWordPress::val($feed);
1610
+ FeedWordPress::diagnostic('updated_feeds:errors', "WordPress API error: $mesg");
1611
+ FeedWordPress::diagnostic('feed_items:rejected', $mesg);
1612
+
1613
+ $mesg = <<<EOM
1614
+ The WordPress API returned an invalid post ID
1615
+ when FeedWordPress tried to $verb item $guid
1616
+ [URL: $url]
1617
+ from the feed at $feed
1618
+
1619
+ $ns::_wp_id
1620
+ EOM;
1621
+ FeedWordPress::noncritical_bug(
1622
+ /*message=*/ $mesg,
1623
  /*var =*/ array(
1624
  "\$this->_wp_id" => $this->_wp_id,
1625
  "\$dbpost" => $dbpost,
 
1626
  ),
1627
+ /*line # =*/ __LINE__, /*filename=*/ __FILE__
1628
  );
1629
  endif;
1630
  } /* SyndicatedPost::validate_post_id() */
1658
  WHERE post_type = 'revision' AND ID='$revision_id'
1659
  ");
1660
  } /* SyndicatedPost::fix_revision_meta () */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1661
 
1662
  /**
1663
  * SyndicatedPost::add_terms() -- if FeedWordPress is processing an
1677
  * @param object $post The database record for the post just inserted.
1678
  */
1679
  function add_terms ($new_status, $old_status, $post) {
1680
+ if ($new_status!='inherit') : // Bail if we are creating a revision.
1681
+ if ( is_array($this->post) and isset($this->post['tax_input']) and is_array($this->post['tax_input']) ) :
1682
+ foreach ($this->post['tax_input'] as $taxonomy => $terms) :
1683
+ if (is_array($terms)) :
1684
+ $terms = array_filter($terms); // strip out empties
1685
+ endif;
1686
+ wp_set_post_terms($post->ID, $terms, $taxonomy);
1687
+ endforeach;
1688
+ endif;
1689
  endif;
1690
  } /* SyndicatedPost::add_terms () */
1691
 
1706
  */
1707
  function fix_post_modified_ts ($new_status, $old_status, $post) {
1708
  global $wpdb;
1709
+ if ($new_status!='inherit') : // Bail if we are creating a revision.
1710
+ $wpdb->update( $wpdb->posts, /*data=*/ array(
1711
+ 'post_modified' => $this->post['post_modified'],
1712
+ 'post_modified_gmt' => $this->post['post_modified_gmt'],
1713
+ ), /*where=*/ array('ID' => $post->ID) );
1714
+ endif;
1715
  } /* SyndicatedPost::fix_post_modified_ts () */
1716
 
1717
  /**
1730
  * @param object $post The database record for the post just inserted.
1731
  */
1732
  function add_rss_meta ($new_status, $old_status, $post) {
 
 
1733
  global $wpdb;
1734
+ if ($new_status!='inherit') : // Bail if we are creating a revision.
1735
+ FeedWordPress::diagnostic('syndicated_posts:meta_data', 'Adding post meta-data: {'.implode(", ", array_keys($this->post['meta'])).'}');
 
 
 
 
 
 
 
 
 
 
 
 
1736
 
1737
+ if ( is_array($this->post) and isset($this->post['meta']) and is_array($this->post['meta']) ) :
1738
+ $postId = $post->ID;
1739
+
1740
+ // Aggregated posts should NOT send out pingbacks.
1741
+ // WordPress 2.1-2.2 claim you can tell them not to
1742
+ // using $post_pingback, but they don't listen, so we
1743
+ // make sure here.
1744
  $result = $wpdb->query("
1745
  DELETE FROM $wpdb->postmeta
1746
+ WHERE post_id='$postId' AND meta_key='_pingme'
1747
  ");
1748
+
1749
+ foreach ( $this->post['meta'] as $key => $values ) :
1750
+ $eKey = $wpdb->escape($key);
1751
+
1752
+ // If this is an update, clear out the old
1753
+ // values to avoid duplication.
1754
+ $result = $wpdb->query("
1755
+ DELETE FROM $wpdb->postmeta
1756
+ WHERE post_id='$postId' AND meta_key='$eKey'
1757
+ ");
1758
+
1759
+ // Allow for either a single value or an array
1760
+ if (!is_array($values)) $values = array($values);
1761
+ foreach ( $values as $value ) :
1762
+ FeedWordPress::diagnostic('syndicated_posts:meta_data', "Adding post meta-datum to post [$postId]: [$key] = ".FeedWordPress::val($value, /*no newlines=*/ true));
1763
+ add_post_meta($postId, $key, $value, /*unique=*/ false);
1764
+ endforeach;
1765
  endforeach;
1766
+ endif;
1767
  endif;
1768
  } /* SyndicatedPost::add_rss_meta () */
1769
 
1780
  global $wpdb;
1781
 
1782
  $a = $this->named['author'];
1783
+
1784
  $source = $this->source();
1785
  $forbidden = apply_filters('feedwordpress_forbidden_author_names',
1786
  array('admin', 'administrator', 'www', 'root'));
1787
 
1788
+ // Prepare the list of candidates to try for author name: name from
1789
+ // feed, original source title (if any), immediate source title live
1790
+ // from feed, subscription title, prettied version of feed homepage URL,
1791
+ // prettied version of feed URL, or, failing all, use "unknown author"
1792
+ // as last resort
1793
+
1794
  $candidates = array();
1795
  $candidates[] = $a['name'];
1796
  if (!is_null($source)) : $candidates[] = $source['title']; endif;
1800
  $candidates[] = feedwordpress_display_url($this->link->uri());
1801
  $candidates[] = 'unknown author';
1802
 
1803
+ // Pick the first one that works from the list, screening against empty
1804
+ // or forbidden names.
1805
+
1806
  $author = NULL;
1807
  while (is_null($author) and ($candidate = each($candidates))) :
1808
  if (!is_null($candidate['value'])
1885
  $id = $wpdb->get_var(
1886
  "SELECT ID FROM $wpdb->users
1887
  WHERE TRIM(LCASE(display_name)) = TRIM(LCASE('$author'))
1888
+ OR TRIM(LCASE(user_login)) = TRIM(LCASE('$author'))
1889
  OR (
1890
  LENGTH(TRIM(LCASE(user_email))) > 0
1891
  AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
1929
  $userdata['user_pass'] = substr(md5(uniqid(microtime())), 0, 6); // just something random to lock it up
1930
  $userdata['user_email'] = $email;
1931
  $userdata['user_url'] = $authorUrl;
1932
+ $userdata['nickname'] = $author;
1933
+ $parts = preg_split('/\s+/', trim($author), 2);
1934
+ if (isset($parts[0])) : $userdata['first_name'] = $parts[0]; endif;
1935
+ if (isset($parts[1])) : $userdata['last_name'] = $parts[1]; endif;
1936
  $userdata['display_name'] = $author;
1937
  $userdata['role'] = 'contributor';
1938
 
1979
  endif;
1980
  endif;
1981
  return $id;
1982
+ } /* function SyndicatedPost::author_id () */
1983
 
1984
  /**
1985
  * category_ids: look up (and create) category ids from a list of categories
2062
  endif;
2063
  $term = wp_insert_term($cat_name, $tax);
2064
  if (is_wp_error($term)) :
2065
+ FeedWordPress::noncritical_bug('term insertion problem', array('cat_name' => $cat_name, 'term' => $term, 'this' => $this), __LINE__, __FILE__);
2066
  else :
2067
  if (!isset($terms[$tax])) :
2068
  $terms[$tax] = array();