FeedWordPress - Version 2020.0818

Version Description

  • WORDPRESS 5.5 COMPATIBILITY FIXES, RESOLVES WARNING NOTICES OR WP-ADMIN LOCKOUT. WordPress 5.5 incorporated a newer release of SimplePie, version 1.5.5, which is pretty rad, but FeedWordPress classes that relied on SimplePie 1.3.1's method signatures would then produce PHP warning notices. That should be pretty innocuous, but depending on web server configurations, some users could get locked out of their own wp-admin interface by the display of error notices in the browser at inopportune times. In any case, I have

  • PHP 7.4 COMPATIBILITY FIX: Magic quotes were deprecated and then removed back in PHP 5.x, and in PHP 7.4 the vestigial get_magic_quotes_gpc() function has been deprecated. We don't need to worry about it anymore for versions of PHP still supported by WordPress. The reference to the function in the MyPHP utility class caused PHP warnings in more recent versions of PHP; so it has now been removed.

  • DIVERS BUG FIXES AND PHP WARNING NOTICES RESOLVED, thanks to @oppiansteve's fixes and pull requests. (Thanks!)

  • JQUERY COMPATIBILITY FIXES, RESOLVES MYSTERIOUS VANISHING FEED SELECTOR IN WP-ADMIN. An upgrade to WordPress's packaged jQuery caused the drop-down box for feed settings (in Syndication > Feeds & Updates, Syndication > Posts & Links, etc.) to vanish shortly after pageload. That was awkward, so I disabled the now-incompatible interface chrome that was causing it to vanish.

Download this release

Release Info

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

Code changes from version 2020.0118 to 2020.0818

btc-qr-64px.png CHANGED
Binary file
compatability.php CHANGED
@@ -135,6 +135,34 @@ if (!function_exists('set_post_field')) {
135
 
136
  } /* if */
137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  require_once(dirname(__FILE__).'/feedwordpress-walker-category-checklist.class.php');
139
 
140
  function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selected_cats = false, $params = array()) {
135
 
136
  } /* if */
137
 
138
+ if (!function_exists('is_countable')) {
139
+
140
+ // Copied from WordPress 5.3.2 wp-includes/compat.php pursuant to terms
141
+ // of GPL. Provide support for is_countable() for versions of PHP < 7.3
142
+ // and for versions of WordPress < 4.9.6. -C.J. 2020/01/24
143
+
144
+ /**
145
+ * Polyfill for is_countable() function added in PHP 7.3.
146
+ *
147
+ * Verify that the content of a variable is an array or an object
148
+ * implementing the Countable interface.
149
+ *
150
+ * @since 4.9.6
151
+ *
152
+ * @param mixed $var The value to check.
153
+ *
154
+ * @return bool True if `$var` is countable, false otherwise.
155
+ */
156
+ function is_countable( $var ) {
157
+ return ( is_array( $var )
158
+ || $var instanceof Countable
159
+ || $var instanceof SimpleXMLElement
160
+ || $var instanceof ResourceBundle
161
+ );
162
+ }
163
+
164
+ } /* if */
165
+
166
  require_once(dirname(__FILE__).'/feedwordpress-walker-category-checklist.class.php');
167
 
168
  function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selected_cats = false, $params = array()) {
diagnostics-page.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
  require_once(dirname(__FILE__) . '/admin-ui.php');
 
3
 
4
  class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
5
  public function __construct() {
@@ -41,7 +42,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
41
  $boxes_by_methods = array(
42
  'info_box' => __('Diagnostic Information'),
43
  'diagnostics_box' => __('Display Diagnostics'),
44
- 'updates_box' => __('Updates'),
45
  'tests_box' => __('Diagnostic Tests'),
46
  );
47
 
@@ -135,6 +136,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
135
  <th scope="row">Hosting Environment:</th>
136
  <td><ul style="margin-top: 0; padding-top: 0;">
137
  <li><em>WordPress:</em> version <?php print $wp_version; ?></li>
 
138
  <?php if (function_exists('phpversion')) : ?>
139
  <li><em>PHP:</em> version <?php print phpversion(); ?></li>
140
  <?php endif; ?>
@@ -263,18 +265,21 @@ testing but absolutely inappropriate for a production server.</p>
263
  'Update Diagnostics' => array(
264
  'update_schedule:check' => 'whenever a FeedWordPress checks in on the update schedule',
265
  'updated_feeds' => 'as each feed is checked for updates',
266
- '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',
267
- 'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
268
- 'updated_feeds:http' => "displaying the raw HTTP data passed to and from the feed being checked for updates",
269
  'syndicated_posts' => 'as each syndicated post is added to the database',
270
  'feed_items' => 'as each syndicated item is considered on the feed',
271
  'memory_usage' => 'indicating how much memory was used',
272
  ),
 
 
 
 
 
273
  'Syndicated Post Details' => array(
274
  'feed_items:freshness' => 'as FeedWordPress decides whether to treat an item as a new post, an update, or a duplicate of an existing post',
275
  'feed_items:rejected' => 'when FeedWordPress rejects a post without syndicating it',
276
  'syndicated_posts:categories' => 'as categories, tags, and other terms are added on the post',
277
  'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
 
278
  ),
279
  'Advanced Diagnostics' => array(
280
  'feed_items:freshness:reasons' => 'explaining the reason that a post was treated as an update to an existing post',
@@ -318,6 +323,15 @@ testing but absolutely inappropriate for a production server.</p>
318
  } /* FeedWordPressDiagnosticsPage::updates_box () */
319
 
320
  static function tests_box ($page, $box = NULL) {
 
 
 
 
 
 
 
 
 
321
  ?>
322
  <script type="text/javascript">
323
  function clone_http_test_args_keyvalue_prototype () {
@@ -334,11 +348,20 @@ function clone_http_test_args_keyvalue_prototype () {
334
  <table class="edit-form">
335
  <tr>
336
  <th scope="row">HTTP:</th>
337
- <td><div><input type="url" name="http_test_url" value="" placeholder="http://www.example.com/" size="127" style="width: 80%; max-width: 80.0em;" />
338
  <input type="submit" name="feedwordpress_diagnostics_do[http_test]" value="Test &raquo;" /></div>
339
  <div><select name="http_test_method" size="1">
340
- <option value="wp_remote_request">wp_remote_request</option>
341
- <option value="FeedWordPress_File">FeedWordPress_File</option>
 
 
 
 
 
 
 
 
 
342
  </select></div>
343
  <table>
344
  <tr>
@@ -358,7 +381,7 @@ function clone_http_test_args_keyvalue_prototype () {
358
 
359
  <tr>
360
  <th>XPath:</th>
361
- <td><div><input type="text" name="http_test_xpath" value="" placeholder="xpath-like query" /></div>
362
  <div><p>Leave blank to test HTTP, fill in to test a query.</p></div>
363
  </td>
364
  </tr>
@@ -415,8 +438,37 @@ function clone_http_test_args_keyvalue_prototype () {
415
  case 'wp_remote_request' :
416
  $out = wp_remote_request($url, $args);
417
  break;
418
- case 'FeedWordPress_File' :
419
- $out = new FeedWordPress_File($url);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
  break;
421
  endswitch;
422
 
1
  <?php
2
  require_once(dirname(__FILE__) . '/admin-ui.php');
3
+ require_once(dirname(__FILE__) . '/magpiemocklink.class.php');
4
 
5
  class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
6
  public function __construct() {
42
  $boxes_by_methods = array(
43
  'info_box' => __('Diagnostic Information'),
44
  'diagnostics_box' => __('Display Diagnostics'),
45
+ 'updates_box' => __('Diagnostic Messages'),
46
  'tests_box' => __('Diagnostic Tests'),
47
  );
48
 
136
  <th scope="row">Hosting Environment:</th>
137
  <td><ul style="margin-top: 0; padding-top: 0;">
138
  <li><em>WordPress:</em> version <?php print $wp_version; ?></li>
139
+ <li><em>SimplePie:</em> version <?php print SIMPLEPIE_VERSION; ?></li>
140
  <?php if (function_exists('phpversion')) : ?>
141
  <li><em>PHP:</em> version <?php print phpversion(); ?></li>
142
  <?php endif; ?>
265
  'Update Diagnostics' => array(
266
  'update_schedule:check' => 'whenever a FeedWordPress checks in on the update schedule',
267
  'updated_feeds' => 'as each feed is checked for updates',
 
 
 
268
  'syndicated_posts' => 'as each syndicated post is added to the database',
269
  'feed_items' => 'as each syndicated item is considered on the feed',
270
  'memory_usage' => 'indicating how much memory was used',
271
  ),
272
+ 'Feed Retrieval' => array(
273
+ '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',
274
+ 'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
275
+ 'updated_feeds:http' => "displaying the raw HTTP data passed to and from the feed being checked for updates",
276
+ ),
277
  'Syndicated Post Details' => array(
278
  'feed_items:freshness' => 'as FeedWordPress decides whether to treat an item as a new post, an update, or a duplicate of an existing post',
279
  'feed_items:rejected' => 'when FeedWordPress rejects a post without syndicating it',
280
  'syndicated_posts:categories' => 'as categories, tags, and other terms are added on the post',
281
  'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
282
+ 'syndicated_posts:do_pings' => 'when FeedWordPress holds or releases the pings WordPress sends out when new posts are created',
283
  ),
284
  'Advanced Diagnostics' => array(
285
  'feed_items:freshness:reasons' => 'explaining the reason that a post was treated as an update to an existing post',
323
  } /* FeedWordPressDiagnosticsPage::updates_box () */
324
 
325
  static function tests_box ($page, $box = NULL) {
326
+ $url = MyPHP::request('http_test_url');
327
+ $method = MyPHP::request('http_test_method');
328
+ $xpath = MyPHP::request('http_test_xpath');
329
+
330
+ $aMethods = array(
331
+ 'wp_remote_request',
332
+ 'FeedWordPie_File',
333
+ 'FeedWordPress::fetch',
334
+ );
335
  ?>
336
  <script type="text/javascript">
337
  function clone_http_test_args_keyvalue_prototype () {
348
  <table class="edit-form">
349
  <tr>
350
  <th scope="row">HTTP:</th>
351
+ <td><div><input type="url" name="http_test_url" value="<?php print esc_attr($url);?>" placeholder="http://www.example.com/" size="127" style="width: 80%; max-width: 80.0em;" />
352
  <input type="submit" name="feedwordpress_diagnostics_do[http_test]" value="Test &raquo;" /></div>
353
  <div><select name="http_test_method" size="1">
354
+ <?php foreach ($aMethods as $sMethod) :?>
355
+ <option value="<?php
356
+ print esc_attr($sMethod);
357
+ ?>"<?php
358
+ if ($method==$sMethod) :
359
+ print ' selected="selected"';
360
+ endif;
361
+ ?>><?php
362
+ print $sMethod;
363
+ ?></option>
364
+ <?php endforeach; ?>
365
  </select></div>
366
  <table>
367
  <tr>
381
 
382
  <tr>
383
  <th>XPath:</th>
384
+ <td><div><input type="text" name="http_test_xpath" value="<?php print esc_attr($xpath); ?>" placeholder="xpath-like query" /></div>
385
  <div><p>Leave blank to test HTTP, fill in to test a query.</p></div>
386
  </td>
387
  </tr>
438
  case 'wp_remote_request' :
439
  $out = wp_remote_request($url, $args);
440
  break;
441
+ case 'FeedWordPie_File' :
442
+ $out = new FeedWordPie_File($url);
443
+ break;
444
+ case 'FeedWordPress::fetch' :
445
+ $out = FeedWordPress::fetch($url);
446
+
447
+ if (isset($post['http_test_xpath'])) :
448
+ if (strlen($post['http_test_xpath']) > 0) :
449
+
450
+ $xpath = $post['http_test_xpath'];
451
+
452
+ if ( !is_wp_error($out) ) :
453
+ $expr = new FeedWordPressParsedPostMeta($xpath);
454
+
455
+ $feed = new MagpieMockLink( $out, $url );
456
+ $posts = $feed->live_posts();
457
+
458
+ $post = new SyndicatedPost($posts[0], $feed);
459
+ $meta = $expr->do_substitutions($post);
460
+
461
+ $out = array(
462
+ "post_title" => $post->entry->get_title(),
463
+ "post_link" => $post->permalink(),
464
+ "guid" => $post->guid(),
465
+ "expression" => $xpath,
466
+ "results" => $meta,
467
+ "pie" => $out,
468
+ );
469
+ endif;
470
+ endif;
471
+ endif;
472
  break;
473
  endswitch;
474
 
feedwordpie_item.class.php → extend/SimplePie/1.3.1/feedwordpie_item.class.php RENAMED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  class FeedWordPie_Item extends SimplePie_Item {
3
 
4
  function get_id ($hash = false) {
1
  <?php
2
+
3
  class FeedWordPie_Item extends SimplePie_Item {
4
 
5
  function get_id ($hash = false) {
feedwordpress_parser.class.php → extend/SimplePie/1.3.1/feedwordpie_parser.class.php RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- class FeedWordPress_Parser extends SimplePie_Parser {
3
  function reset_parser (&$xml) {
4
  // reset members
5
  $this->namespace = array('');
@@ -67,7 +67,7 @@ class FeedWordPress_Parser extends SimplePie_Parser {
67
 
68
  if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
69
  {
70
- $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
71
  if ($declaration->parse())
72
  {
73
  $data = substr($data, $pos + 2);
@@ -100,44 +100,21 @@ class FeedWordPress_Parser extends SimplePie_Parser {
100
  xml_set_object($xml, $this);
101
  xml_set_character_data_handler($xml, 'cdata');
102
  xml_set_element_handler($xml, 'tag_open', 'tag_close');
103
- xml_set_start_namespace_decl_handler($xml, 'start_xmlns');
104
-
105
- // Parse!
106
- $parseResults = xml_parse($xml, $data, true);
107
-
108
- $endOfJunk = strpos($data, '<?xml');
109
- if (!$parseResults and $endOfJunk > 0) :
110
- // There is some junk before the feed prolog. Try to get rid of it.
111
- $data = substr($data, $endOfJunk);
112
- $data = trim($data);
113
- $this->reset_parser($xml);
114
 
115
- $parseResults = xml_parse($xml, $data, true);
116
- endif;
 
 
117
 
118
- $badEntity = (xml_get_error_code($xml) == 26);
119
- if (!$parseResults and $badEntity) :
120
- // There was an entity that libxml couldn't understand.
121
- // Chances are, it was a stray HTML entity. So let's try
122
- // converting all the named HTML entities to numeric XML
123
- // entities and starting over.
124
- $data = $this->html_convert_entities($data);
125
- $this->reset_parser($xml);
126
-
127
- $parseResults = xml_parse($xml, $data, true);
128
- endif;
129
-
130
  if (!$parseResults) {
131
  $this->error_code = xml_get_error_code($xml);
132
  $this->error_string = xml_error_string($this->error_code);
133
  $return = false;
134
  }
135
-
136
  $this->current_line = xml_get_current_line_number($xml);
137
  $this->current_column = xml_get_current_column_number($xml);
138
  $this->current_byte = xml_get_current_byte_index($xml);
139
  xml_parser_free($xml);
140
-
141
  return $return;
142
  }
143
  else
@@ -153,7 +130,7 @@ class FeedWordPress_Parser extends SimplePie_Parser {
153
  case constant('XMLReader::END_ELEMENT'):
154
  if ($xml->namespaceURI !== '')
155
  {
156
- $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
157
  }
158
  else
159
  {
@@ -165,7 +142,7 @@ class FeedWordPress_Parser extends SimplePie_Parser {
165
  $empty = $xml->isEmptyElement;
166
  if ($xml->namespaceURI !== '')
167
  {
168
- $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
169
  }
170
  else
171
  {
@@ -176,7 +153,7 @@ class FeedWordPress_Parser extends SimplePie_Parser {
176
  {
177
  if ($xml->namespaceURI !== '')
178
  {
179
- $attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
180
  }
181
  else
182
  {
@@ -184,14 +161,8 @@ class FeedWordPress_Parser extends SimplePie_Parser {
184
  }
185
  $attributes[$attrName] = $xml->value;
186
  }
187
-
188
- foreach ($attributes as $attr => $value) :
189
- list($ns, $local) = $this->split_ns($attr);
190
- if ($ns=='http://www.w3.org/2000/xmlns/') :
191
- if ('xmlns' == $local) : $local = false; endif;
192
- $this->start_xmlns(null, $local, $value);
193
- endif;
194
- endforeach;
195
 
196
  $this->tag_open(null, $tagName, $attributes);
197
  if ($empty)
@@ -219,7 +190,52 @@ class FeedWordPress_Parser extends SimplePie_Parser {
219
  return true;
220
  }
221
  }
222
- } /* FeedWordPress_Parser::parse() */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
 
224
  var $xmlns_stack = array();
225
  var $xmlns_current = array();
@@ -247,8 +263,9 @@ class FeedWordPress_Parser extends SimplePie_Parser {
247
  if ($this->current_xhtml_construct < 0) :
248
  $this->xmlns_current[$prefix] = $uri;
249
  endif;
 
250
  return true;
251
- } /* FeedWordPress_Parser::start_xmlns() */
252
 
253
  /* html_convert_entities($string) -- convert named HTML entities to
254
  * XML-compatible numeric entities. Adapted from code by @inanimatt:
@@ -522,8 +539,8 @@ class FeedWordPress_Parser extends SimplePie_Parser {
522
  );
523
  // Entity not found? Destroy it.
524
  return isset($table[$matches[1]]) ? $table[$matches[1]] : '';
525
- } /* FeedWordPress_Parser::convert_entity() */
526
 
527
- } /* class FeedWordPress_Parser */
528
 
529
 
1
  <?php
2
+ class FeedWordPie_Parser extends SimplePie_Parser {
3
  function reset_parser (&$xml) {
4
  // reset members
5
  $this->namespace = array('');
67
 
68
  if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
69
  {
70
+ $declaration = $this->registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5)));
71
  if ($declaration->parse())
72
  {
73
  $data = substr($data, $pos + 2);
100
  xml_set_object($xml, $this);
101
  xml_set_character_data_handler($xml, 'cdata');
102
  xml_set_element_handler($xml, 'tag_open', 'tag_close');
 
 
 
 
 
 
 
 
 
 
 
103
 
104
+ // Parse!
105
+ $results = $this->do_xml_parse_attempt($xml, $data);
106
+ $parseResults = $results[0];
107
+ $data = $results[1];
108
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  if (!$parseResults) {
110
  $this->error_code = xml_get_error_code($xml);
111
  $this->error_string = xml_error_string($this->error_code);
112
  $return = false;
113
  }
 
114
  $this->current_line = xml_get_current_line_number($xml);
115
  $this->current_column = xml_get_current_column_number($xml);
116
  $this->current_byte = xml_get_current_byte_index($xml);
117
  xml_parser_free($xml);
 
118
  return $return;
119
  }
120
  else
130
  case constant('XMLReader::END_ELEMENT'):
131
  if ($xml->namespaceURI !== '')
132
  {
133
+ $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
134
  }
135
  else
136
  {
142
  $empty = $xml->isEmptyElement;
143
  if ($xml->namespaceURI !== '')
144
  {
145
+ $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
146
  }
147
  else
148
  {
153
  {
154
  if ($xml->namespaceURI !== '')
155
  {
156
+ $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
157
  }
158
  else
159
  {
161
  }
162
  $attributes[$attrName] = $xml->value;
163
  }
164
+
165
+ $this->do_scan_attributes_namespaces($attributes);
 
 
 
 
 
 
166
 
167
  $this->tag_open(null, $tagName, $attributes);
168
  if ($empty)
190
  return true;
191
  }
192
  }
193
+ } /* FeedWordPie_Parser::parse() */
194
+
195
+ public function do_xml_parse_attempt ($xml, $data) {
196
+ xml_set_start_namespace_decl_handler($xml, 'start_xmlns');
197
+
198
+ // Parse!
199
+ $parseResults = xml_parse($xml, $data, true);
200
+ $endOfJunk = strpos($data, '<?xml');
201
+ if (!$parseResults and $endOfJunk > 0) :
202
+ // There is some junk before the feed prolog. Try to get rid of it.
203
+ $data = substr($data, $endOfJunk);
204
+ $data = trim($data);
205
+ $this->reset_parser($xml);
206
+
207
+ $parseResults = xml_parse($xml, $data, true);
208
+ endif;
209
+
210
+ $badEntity = (xml_get_error_code($xml) == 26);
211
+ if (!$parseResults and $badEntity) :
212
+ // There was an entity that libxml couldn't understand.
213
+ // Chances are, it was a stray HTML entity. So let's try
214
+ // converting all the named HTML entities to numeric XML
215
+ // entities and starting over.
216
+ $data = $this->html_convert_entities($data);
217
+ $this->reset_parser($xml);
218
+
219
+ $parseResults = xml_parse($xml, $data, true);
220
+ endif;
221
+
222
+ $result = array(
223
+ $parseResults,
224
+ $data
225
+ );
226
+ return $result;
227
+
228
+ }
229
+
230
+ public function do_scan_attributes_namespaces ($attributes) {
231
+ foreach ($attributes as $attr => $value) :
232
+ list($ns, $local) = $this->split_ns($attr);
233
+ if ($ns=='http://www.w3.org/2000/xmlns/') :
234
+ if ('xmlns' == $local) : $local = false; endif;
235
+ $this->start_xmlns(null, $local, $value);
236
+ endif;
237
+ endforeach;
238
+ }
239
 
240
  var $xmlns_stack = array();
241
  var $xmlns_current = array();
263
  if ($this->current_xhtml_construct < 0) :
264
  $this->xmlns_current[$prefix] = $uri;
265
  endif;
266
+
267
  return true;
268
+ } /* FeedWordPie_Parser::start_xmlns() */
269
 
270
  /* html_convert_entities($string) -- convert named HTML entities to
271
  * XML-compatible numeric entities. Adapted from code by @inanimatt:
539
  );
540
  // Entity not found? Destroy it.
541
  return isset($table[$matches[1]]) ? $table[$matches[1]] : '';
542
+ } /* FeedWordPie_Parser::convert_entity() */
543
 
544
+ } /* class FeedWordPie_Parser */
545
 
546
 
extend/SimplePie/default/feedwordpie_item.class.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FeedWordPie_Item extends SimplePie_Item {
4
+
5
+ function get_id ($hash = false, $fn = 'md5') {
6
+ return apply_filters('feedwordpie_item_get_id', parent::get_id($hash, $fn), $hash, $this, $fn);
7
+ }
8
+
9
+ function get_title () {
10
+ return apply_filters('feedwordpie_item_get_title', parent::get_title(), $this);
11
+ }
12
+
13
+ function get_description ($description_only = false) {
14
+ return apply_filters('feedwordpie_item_get_description', parent::get_description($description_only), $description_only, $this);
15
+ }
16
+
17
+ function get_content ($content_only = false) {
18
+ return apply_filters('feedwordpie_item_get_content', parent::get_content($content_only), $content_only, $this);
19
+ }
20
+
21
+ function get_categories () {
22
+ return apply_filters('feedwordpie_item_get_categories', parent::get_categories(), $this);
23
+ }
24
+
25
+ function get_authors () {
26
+ return apply_filters('feedwordpie_item_get_authors', parent::get_authors(), $this);
27
+ }
28
+ function get_contributors () {
29
+ return apply_filters('feedwordpie_item_get_contributors', parent::get_contributors(), $this);
30
+ }
31
+ function get_copyright () {
32
+ return apply_filters('feedwordpie_item_get_copyright', parent::get_copyright(), $this);
33
+ }
34
+ function get_date ($date_format = 'j F Y, g:i a') {
35
+ return apply_filters('feedwordpie_item_get_date', parent::get_date($date_format), $date_format, $this);
36
+ }
37
+ function get_local_date ($date_format = '%c') {
38
+ return apply_filters('feedwordpie_item_get_local_date', parent::get_local_date($date_format), $date_format, $this);
39
+ }
40
+ function get_links ($rel = 'alternate') {
41
+ return apply_filters('feedwordpie_item_get_links', parent::get_links($rel), $rel, $this);
42
+ }
43
+ function get_enclosures () {
44
+ return apply_filters('feedwordpie_item_get_enclosures', parent::get_enclosures(), $this);
45
+ }
46
+ function get_latitude () {
47
+ return apply_filters('feedwordpie_item_get_lattitude', parent::get_lattitude(), $this);
48
+ }
49
+ function get_longitude () {
50
+ return apply_filters('feedwordpie_item_get_longitude', parent::get_longtidue(), $this);
51
+ }
52
+ function get_source () {
53
+ return apply_filters('feedwordpie_item_get_source', parent::get_source(), $this);
54
+ }
55
+ } /* class FeedWordPie_Item */
56
+
extend/SimplePie/default/feedwordpie_parser.class.php ADDED
@@ -0,0 +1,562 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class FeedWordPie_Parser extends SimplePie_Parser {
3
+ function reset_parser (&$xml) {
4
+ // reset members
5
+ $this->namespace = array('');
6
+ $this->element = array('');
7
+ $this->xml_base = array('');
8
+ $this->xml_base_explicit = array(false);
9
+ $this->xml_lang = array('');
10
+ $this->data = array();
11
+ $this->datas = array(array());
12
+ $this->current_xhtml_construct = -1;
13
+ $this->xmlns_stack = array();
14
+ $this->xmlns_current = array();
15
+
16
+ // reset libxml parser
17
+ xml_parser_free($xml);
18
+
19
+ $xml = xml_parser_create_ns($this->encoding, $this->separator);
20
+ xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
21
+ xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
22
+ xml_set_object($xml, $this);
23
+ xml_set_character_data_handler($xml, 'cdata');
24
+ xml_set_element_handler($xml, 'tag_open', 'tag_close');
25
+ xml_set_start_namespace_decl_handler($xml, 'start_xmlns');
26
+ }
27
+
28
+ public function parse (&$data, $encoding, $url = '')
29
+ {
30
+ $data = apply_filters('feedwordpress_parser_parse', $data, $encoding, $this, $url);
31
+
32
+ if (class_exists('DOMXpath') && function_exists('Mf2\parse')) {
33
+ $doc = new DOMDocument();
34
+ @$doc->loadHTML($data);
35
+ $xpath = new DOMXpath($doc);
36
+ // Check for both h-feed and h-entry, as both a feed with no entries
37
+ // and a list of entries without an h-feed wrapper are both valid.
38
+ $query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '.
39
+ 'contains(concat(" ", @class, " "), " h-entry ")]';
40
+ $result = $xpath->query($query);
41
+ if ($result->length !== 0) {
42
+ return $this->parse_microformats($data, $url);
43
+ }
44
+ }
45
+
46
+ // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
47
+ if (strtoupper($encoding) === 'US-ASCII')
48
+ {
49
+ $this->encoding = 'UTF-8';
50
+ }
51
+ else
52
+ {
53
+ $this->encoding = $encoding;
54
+ }
55
+
56
+ // Strip BOM:
57
+ // UTF-32 Big Endian BOM
58
+ if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
59
+ {
60
+ $data = substr($data, 4);
61
+ }
62
+ // UTF-32 Little Endian BOM
63
+ elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
64
+ {
65
+ $data = substr($data, 4);
66
+ }
67
+ // UTF-16 Big Endian BOM
68
+ elseif (substr($data, 0, 2) === "\xFE\xFF")
69
+ {
70
+ $data = substr($data, 2);
71
+ }
72
+ // UTF-16 Little Endian BOM
73
+ elseif (substr($data, 0, 2) === "\xFF\xFE")
74
+ {
75
+ $data = substr($data, 2);
76
+ }
77
+ // UTF-8 BOM
78
+ elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
79
+ {
80
+ $data = substr($data, 3);
81
+ }
82
+
83
+ if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
84
+ {
85
+ $declaration = $this->registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5)));
86
+ if ($declaration->parse())
87
+ {
88
+ $data = substr($data, $pos + 2);
89
+ $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' ."\n". $this->declare_html_entities() . $data;
90
+ }
91
+ else
92
+ {
93
+ $this->error_string = 'SimplePie bug! Please report this!';
94
+ return false;
95
+ }
96
+ }
97
+
98
+ $return = true;
99
+
100
+ static $xml_is_sane = null;
101
+ if ($xml_is_sane === null)
102
+ {
103
+ $parser_check = xml_parser_create();
104
+ xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
105
+ xml_parser_free($parser_check);
106
+ $xml_is_sane = isset($values[0]['value']);
107
+ }
108
+
109
+ // Create the parser
110
+ if ($xml_is_sane)
111
+ {
112
+ $xml = xml_parser_create_ns($this->encoding, $this->separator);
113
+ xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
114
+ xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
115
+ xml_set_object($xml, $this);
116
+ xml_set_character_data_handler($xml, 'cdata');
117
+ xml_set_element_handler($xml, 'tag_open', 'tag_close');
118
+
119
+ // Parse!
120
+ $results = $this->do_xml_parse_attempt($xml, $data);
121
+ $parseResults = $results[0];
122
+ $data = $results[1];
123
+
124
+ if (!$parseResults) {
125
+ $this->error_code = xml_get_error_code($xml);
126
+ $this->error_string = xml_error_string($this->error_code);
127
+ $return = false;
128
+ }
129
+ $this->current_line = xml_get_current_line_number($xml);
130
+ $this->current_column = xml_get_current_column_number($xml);
131
+ $this->current_byte = xml_get_current_byte_index($xml);
132
+ xml_parser_free($xml);
133
+ return $return;
134
+ }
135
+
136
+ libxml_clear_errors();
137
+ $xml = new XMLReader();
138
+ $xml->xml($data);
139
+ while (@$xml->read())
140
+ {
141
+ switch ($xml->nodeType)
142
+ {
143
+
144
+ case constant('XMLReader::END_ELEMENT'):
145
+ if ($xml->namespaceURI !== '')
146
+ {
147
+ $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
148
+ }
149
+ else
150
+ {
151
+ $tagName = $xml->localName;
152
+ }
153
+ $this->tag_close(null, $tagName);
154
+ break;
155
+ case constant('XMLReader::ELEMENT'):
156
+ $empty = $xml->isEmptyElement;
157
+ if ($xml->namespaceURI !== '')
158
+ {
159
+ $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
160
+ }
161
+ else
162
+ {
163
+ $tagName = $xml->localName;
164
+ }
165
+ $attributes = array();
166
+ while ($xml->moveToNextAttribute())
167
+ {
168
+ if ($xml->namespaceURI !== '')
169
+ {
170
+ $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
171
+ }
172
+ else
173
+ {
174
+ $attrName = $xml->localName;
175
+ }
176
+ $attributes[$attrName] = $xml->value;
177
+ }
178
+
179
+ $this->do_scan_attributes_namespaces($attributes);
180
+
181
+ $this->tag_open(null, $tagName, $attributes);
182
+ if ($empty)
183
+ {
184
+ $this->tag_close(null, $tagName);
185
+ }
186
+ break;
187
+ case constant('XMLReader::TEXT'):
188
+
189
+ case constant('XMLReader::CDATA'):
190
+ $this->cdata(null, $xml->value);
191
+ break;
192
+ }
193
+ }
194
+ if ($error = libxml_get_last_error())
195
+ {
196
+ $this->error_code = $error->code;
197
+ $this->error_string = $error->message;
198
+ $this->current_line = $error->line;
199
+ $this->current_column = $error->column;
200
+ return false;
201
+ }
202
+
203
+ return true;
204
+ } /* FeedWordPie_Parser::parse() */
205
+
206
+ public function do_xml_parse_attempt ($xml, $data) {
207
+ xml_set_start_namespace_decl_handler($xml, 'start_xmlns');
208
+
209
+ // Parse!
210
+ $parseResults = xml_parse($xml, $data, true);
211
+ $endOfJunk = strpos($data, '<?xml');
212
+ if (!$parseResults and $endOfJunk > 0) :
213
+ // There is some junk before the feed prolog. Try to get rid of it.
214
+ $data = substr($data, $endOfJunk);
215
+ $data = trim($data);
216
+ $this->reset_parser($xml);
217
+
218
+ $parseResults = xml_parse($xml, $data, true);
219
+ endif;
220
+
221
+ $badEntity = (xml_get_error_code($xml) == 26);
222
+ if (!$parseResults and $badEntity) :
223
+ // There was an entity that libxml couldn't understand.
224
+ // Chances are, it was a stray HTML entity. So let's try
225
+ // converting all the named HTML entities to numeric XML
226
+ // entities and starting over.
227
+ $data = $this->html_convert_entities($data);
228
+ $this->reset_parser($xml);
229
+
230
+ $parseResults = xml_parse($xml, $data, true);
231
+ endif;
232
+
233
+ $result = array(
234
+ $parseResults,
235
+ $data
236
+ );
237
+ return $result;
238
+
239
+ }
240
+
241
+ public function do_scan_attributes_namespaces ($attributes) {
242
+ foreach ($attributes as $attr => $value) :
243
+ list($ns, $local) = $this->split_ns($attr);
244
+ if ($ns=='http://www.w3.org/2000/xmlns/') :
245
+ if ('xmlns' == $local) : $local = false; endif;
246
+ $this->start_xmlns(null, $local, $value);
247
+ endif;
248
+ endforeach;
249
+ }
250
+
251
+ var $xmlns_stack = array();
252
+ var $xmlns_current = array();
253
+ function tag_open ($parser, $tag, $attributes) {
254
+ $ret = parent::tag_open($parser, $tag, $attributes);
255
+ if ($this->current_xhtml_construct < 0) :
256
+ $this->data['xmlns'] = $this->xmlns_current;
257
+ $this->xmlns_stack[] = $this->xmlns_current;
258
+ endif;
259
+ return $ret;
260
+ }
261
+
262
+ function tag_close($parser, $tag) {
263
+ if ($this->current_xhtml_construct < 0) :
264
+ $this->xmlns_current = array_pop($this->xmlns_stack);
265
+ endif;
266
+ $ret = parent::tag_close($parser, $tag);
267
+ return $ret;
268
+ }
269
+
270
+ function start_xmlns ($parser, $prefix, $uri) {
271
+ if (!$prefix) :
272
+ $prefix = '';
273
+ endif;
274
+ if ($this->current_xhtml_construct < 0) :
275
+ $this->xmlns_current[$prefix] = $uri;
276
+ endif;
277
+
278
+ return true;
279
+ } /* FeedWordPie_Parser::start_xmlns() */
280
+
281
+ /* html_convert_entities($string) -- convert named HTML entities to
282
+ * XML-compatible numeric entities. Adapted from code by @inanimatt:
283
+ * https://gist.github.com/inanimatt/879249
284
+ */
285
+ public function html_convert_entities($string) {
286
+ return preg_replace_callback('/&([a-zA-Z][a-zA-Z0-9]+);/S',
287
+ array($this, 'convert_entity'), $string);
288
+ }
289
+
290
+ /* Swap HTML named entity with its numeric equivalent. If the entity
291
+ * isn't in the lookup table, this function returns a blank, which
292
+ * destroys the character in the output - this is probably the
293
+ * desired behaviour when producing XML. Adapted from code by @inanimatt:
294
+ * https://gist.github.com/inanimatt/879249
295
+ */
296
+ public function convert_entity($matches) {
297
+ static $table = array(
298
+ 'quot' => '&#34;',
299
+ 'amp' => '&#38;',
300
+ 'lt' => '&#60;',
301
+ 'gt' => '&#62;',
302
+ 'OElig' => '&#338;',
303
+ 'oelig' => '&#339;',
304
+ 'Scaron' => '&#352;',
305
+ 'scaron' => '&#353;',
306
+ 'Yuml' => '&#376;',
307
+ 'circ' => '&#710;',
308
+ 'tilde' => '&#732;',
309
+ 'ensp' => '&#8194;',
310
+ 'emsp' => '&#8195;',
311
+ 'thinsp' => '&#8201;',
312
+ 'zwnj' => '&#8204;',
313
+ 'zwj' => '&#8205;',
314
+ 'lrm' => '&#8206;',
315
+ 'rlm' => '&#8207;',
316
+ 'ndash' => '&#8211;',
317
+ 'mdash' => '&#8212;',
318
+ 'lsquo' => '&#8216;',
319
+ 'rsquo' => '&#8217;',
320
+ 'sbquo' => '&#8218;',
321
+ 'ldquo' => '&#8220;',
322
+ 'rdquo' => '&#8221;',
323
+ 'bdquo' => '&#8222;',
324
+ 'dagger' => '&#8224;',
325
+ 'Dagger' => '&#8225;',
326
+ 'permil' => '&#8240;',
327
+ 'lsaquo' => '&#8249;',
328
+ 'rsaquo' => '&#8250;',
329
+ 'euro' => '&#8364;',
330
+ 'fnof' => '&#402;',
331
+ 'Alpha' => '&#913;',
332
+ 'Beta' => '&#914;',
333
+ 'Gamma' => '&#915;',
334
+ 'Delta' => '&#916;',
335
+ 'Epsilon' => '&#917;',
336
+ 'Zeta' => '&#918;',
337
+ 'Eta' => '&#919;',
338
+ 'Theta' => '&#920;',
339
+ 'Iota' => '&#921;',
340
+ 'Kappa' => '&#922;',
341
+ 'Lambda' => '&#923;',
342
+ 'Mu' => '&#924;',
343
+ 'Nu' => '&#925;',
344
+ 'Xi' => '&#926;',
345
+ 'Omicron' => '&#927;',
346
+ 'Pi' => '&#928;',
347
+ 'Rho' => '&#929;',
348
+ 'Sigma' => '&#931;',
349
+ 'Tau' => '&#932;',
350
+ 'Upsilon' => '&#933;',
351
+ 'Phi' => '&#934;',
352
+ 'Chi' => '&#935;',
353
+ 'Psi' => '&#936;',
354
+ 'Omega' => '&#937;',
355
+ 'alpha' => '&#945;',
356
+ 'beta' => '&#946;',
357
+ 'gamma' => '&#947;',
358
+ 'delta' => '&#948;',
359
+ 'epsilon' => '&#949;',
360
+ 'zeta' => '&#950;',
361
+ 'eta' => '&#951;',
362
+ 'theta' => '&#952;',
363
+ 'iota' => '&#953;',
364
+ 'kappa' => '&#954;',
365
+ 'lambda' => '&#955;',
366
+ 'mu' => '&#956;',
367
+ 'nu' => '&#957;',
368
+ 'xi' => '&#958;',
369
+ 'omicron' => '&#959;',
370
+ 'pi' => '&#960;',
371
+ 'rho' => '&#961;',
372
+ 'sigmaf' => '&#962;',
373
+ 'sigma' => '&#963;',
374
+ 'tau' => '&#964;',
375
+ 'upsilon' => '&#965;',
376
+ 'phi' => '&#966;',
377
+ 'chi' => '&#967;',
378
+ 'psi' => '&#968;',
379
+ 'omega' => '&#969;',
380
+ 'thetasym' => '&#977;',
381
+ 'upsih' => '&#978;',
382
+ 'piv' => '&#982;',
383
+ 'bull' => '&#8226;',
384
+ 'hellip' => '&#8230;',
385
+ 'prime' => '&#8242;',
386
+ 'Prime' => '&#8243;',
387
+ 'oline' => '&#8254;',
388
+ 'frasl' => '&#8260;',
389
+ 'weierp' => '&#8472;',
390
+ 'image' => '&#8465;',
391
+ 'real' => '&#8476;',
392
+ 'trade' => '&#8482;',
393
+ 'alefsym' => '&#8501;',
394
+ 'larr' => '&#8592;',
395
+ 'uarr' => '&#8593;',
396
+ 'rarr' => '&#8594;',
397
+ 'darr' => '&#8595;',
398
+ 'harr' => '&#8596;',
399
+ 'crarr' => '&#8629;',
400
+ 'lArr' => '&#8656;',
401
+ 'uArr' => '&#8657;',
402
+ 'rArr' => '&#8658;',
403
+ 'dArr' => '&#8659;',
404
+ 'hArr' => '&#8660;',
405
+ 'forall' => '&#8704;',
406
+ 'part' => '&#8706;',
407
+ 'exist' => '&#8707;',
408
+ 'empty' => '&#8709;',
409
+ 'nabla' => '&#8711;',
410
+ 'isin' => '&#8712;',
411
+ 'notin' => '&#8713;',
412
+ 'ni' => '&#8715;',
413
+ 'prod' => '&#8719;',
414
+ 'sum' => '&#8721;',
415
+ 'minus' => '&#8722;',
416
+ 'lowast' => '&#8727;',
417
+ 'radic' => '&#8730;',
418
+ 'prop' => '&#8733;',
419
+ 'infin' => '&#8734;',
420
+ 'ang' => '&#8736;',
421
+ 'and' => '&#8743;',
422
+ 'or' => '&#8744;',
423
+ 'cap' => '&#8745;',
424
+ 'cup' => '&#8746;',
425
+ 'int' => '&#8747;',
426
+ 'there4' => '&#8756;',
427
+ 'sim' => '&#8764;',
428
+ 'cong' => '&#8773;',
429
+ 'asymp' => '&#8776;',
430
+ 'ne' => '&#8800;',
431
+ 'equiv' => '&#8801;',
432
+ 'le' => '&#8804;',
433
+ 'ge' => '&#8805;',
434
+ 'sub' => '&#8834;',
435
+ 'sup' => '&#8835;',
436
+ 'nsub' => '&#8836;',
437
+ 'sube' => '&#8838;',
438
+ 'supe' => '&#8839;',
439
+ 'oplus' => '&#8853;',
440
+ 'otimes' => '&#8855;',
441
+ 'perp' => '&#8869;',
442
+ 'sdot' => '&#8901;',
443
+ 'lceil' => '&#8968;',
444
+ 'rceil' => '&#8969;',
445
+ 'lfloor' => '&#8970;',
446
+ 'rfloor' => '&#8971;',
447
+ 'lang' => '&#9001;',
448
+ 'rang' => '&#9002;',
449
+ 'loz' => '&#9674;',
450
+ 'spades' => '&#9824;',
451
+ 'clubs' => '&#9827;',
452
+ 'hearts' => '&#9829;',
453
+ 'diams' => '&#9830;',
454
+ 'nbsp' => '&#160;',
455
+ 'iexcl' => '&#161;',
456
+ 'cent' => '&#162;',
457
+ 'pound' => '&#163;',
458
+ 'curren' => '&#164;',
459
+ 'yen' => '&#165;',
460
+ 'brvbar' => '&#166;',
461
+ 'sect' => '&#167;',
462
+ 'uml' => '&#168;',
463
+ 'copy' => '&#169;',
464
+ 'ordf' => '&#170;',
465
+ 'laquo' => '&#171;',
466
+ 'not' => '&#172;',
467
+ 'shy' => '&#173;',
468
+ 'reg' => '&#174;',
469
+ 'macr' => '&#175;',
470
+ 'deg' => '&#176;',
471
+ 'plusmn' => '&#177;',
472
+ 'sup2' => '&#178;',
473
+ 'sup3' => '&#179;',
474
+ 'acute' => '&#180;',
475
+ 'micro' => '&#181;',
476
+ 'para' => '&#182;',
477
+ 'middot' => '&#183;',
478
+ 'cedil' => '&#184;',
479
+ 'sup1' => '&#185;',
480
+ 'ordm' => '&#186;',
481
+ 'raquo' => '&#187;',
482
+ 'frac14' => '&#188;',
483
+ 'frac12' => '&#189;',
484
+ 'frac34' => '&#190;',
485
+ 'iquest' => '&#191;',
486
+ 'Agrave' => '&#192;',
487
+ 'Aacute' => '&#193;',
488
+ 'Acirc' => '&#194;',
489
+ 'Atilde' => '&#195;',
490
+ 'Auml' => '&#196;',
491
+ 'Aring' => '&#197;',
492
+ 'AElig' => '&#198;',
493
+ 'Ccedil' => '&#199;',
494
+ 'Egrave' => '&#200;',
495
+ 'Eacute' => '&#201;',
496
+ 'Ecirc' => '&#202;',
497
+ 'Euml' => '&#203;',
498
+ 'Igrave' => '&#204;',
499
+ 'Iacute' => '&#205;',
500
+ 'Icirc' => '&#206;',
501
+ 'Iuml' => '&#207;',
502
+ 'ETH' => '&#208;',
503
+ 'Ntilde' => '&#209;',
504
+ 'Ograve' => '&#210;',
505
+ 'Oacute' => '&#211;',
506
+ 'Ocirc' => '&#212;',
507
+ 'Otilde' => '&#213;',
508
+ 'Ouml' => '&#214;',
509
+ 'times' => '&#215;',
510
+ 'Oslash' => '&#216;',
511
+ 'Ugrave' => '&#217;',
512
+ 'Uacute' => '&#218;',
513
+ 'Ucirc' => '&#219;',
514
+ 'Uuml' => '&#220;',
515
+ 'Yacute' => '&#221;',
516
+ 'THORN' => '&#222;',
517
+ 'szlig' => '&#223;',
518
+ 'agrave' => '&#224;',
519
+ 'aacute' => '&#225;',
520
+ 'acirc' => '&#226;',
521
+ 'atilde' => '&#227;',
522
+ 'auml' => '&#228;',
523
+ 'aring' => '&#229;',
524
+ 'aelig' => '&#230;',
525
+ 'ccedil' => '&#231;',
526
+ 'egrave' => '&#232;',
527
+ 'eacute' => '&#233;',
528
+ 'ecirc' => '&#234;',
529
+ 'euml' => '&#235;',
530
+ 'igrave' => '&#236;',
531
+ 'iacute' => '&#237;',
532
+ 'icirc' => '&#238;',
533
+ 'iuml' => '&#239;',
534
+ 'eth' => '&#240;',
535
+ 'ntilde' => '&#241;',
536
+ 'ograve' => '&#242;',
537
+ 'oacute' => '&#243;',
538
+ 'ocirc' => '&#244;',
539
+ 'otilde' => '&#245;',
540
+ 'ouml' => '&#246;',
541
+ 'divide' => '&#247;',
542
+ 'oslash' => '&#248;',
543
+ 'ugrave' => '&#249;',
544
+ 'uacute' => '&#250;',
545
+ 'ucirc' => '&#251;',
546
+ 'uuml' => '&#252;',
547
+ 'yacute' => '&#253;',
548
+ 'thorn' => '&#254;',
549
+ 'yuml' => '&#255;'
550
+ );
551
+ // Entity not found? Destroy it.
552
+ return isset($table[$matches[1]]) ? $table[$matches[1]] : '';
553
+ } /* FeedWordPie_Parser::convert_entity() */
554
+
555
+ private function declare_html_entities() {
556
+ // This is required because the RSS specification says that entity-encoded
557
+ // html is allowed, but the xml specification says they must be declared.
558
+ return '<!DOCTYPE html [ <!ENTITY nbsp "&#x00A0;"> <!ENTITY iexcl "&#x00A1;"> <!ENTITY cent "&#x00A2;"> <!ENTITY pound "&#x00A3;"> <!ENTITY curren "&#x00A4;"> <!ENTITY yen "&#x00A5;"> <!ENTITY brvbar "&#x00A6;"> <!ENTITY sect "&#x00A7;"> <!ENTITY uml "&#x00A8;"> <!ENTITY copy "&#x00A9;"> <!ENTITY ordf "&#x00AA;"> <!ENTITY laquo "&#x00AB;"> <!ENTITY not "&#x00AC;"> <!ENTITY shy "&#x00AD;"> <!ENTITY reg "&#x00AE;"> <!ENTITY macr "&#x00AF;"> <!ENTITY deg "&#x00B0;"> <!ENTITY plusmn "&#x00B1;"> <!ENTITY sup2 "&#x00B2;"> <!ENTITY sup3 "&#x00B3;"> <!ENTITY acute "&#x00B4;"> <!ENTITY micro "&#x00B5;"> <!ENTITY para "&#x00B6;"> <!ENTITY middot "&#x00B7;"> <!ENTITY cedil "&#x00B8;"> <!ENTITY sup1 "&#x00B9;"> <!ENTITY ordm "&#x00BA;"> <!ENTITY raquo "&#x00BB;"> <!ENTITY frac14 "&#x00BC;"> <!ENTITY frac12 "&#x00BD;"> <!ENTITY frac34 "&#x00BE;"> <!ENTITY iquest "&#x00BF;"> <!ENTITY Agrave "&#x00C0;"> <!ENTITY Aacute "&#x00C1;"> <!ENTITY Acirc "&#x00C2;"> <!ENTITY Atilde "&#x00C3;"> <!ENTITY Auml "&#x00C4;"> <!ENTITY Aring "&#x00C5;"> <!ENTITY AElig "&#x00C6;"> <!ENTITY Ccedil "&#x00C7;"> <!ENTITY Egrave "&#x00C8;"> <!ENTITY Eacute "&#x00C9;"> <!ENTITY Ecirc "&#x00CA;"> <!ENTITY Euml "&#x00CB;"> <!ENTITY Igrave "&#x00CC;"> <!ENTITY Iacute "&#x00CD;"> <!ENTITY Icirc "&#x00CE;"> <!ENTITY Iuml "&#x00CF;"> <!ENTITY ETH "&#x00D0;"> <!ENTITY Ntilde "&#x00D1;"> <!ENTITY Ograve "&#x00D2;"> <!ENTITY Oacute "&#x00D3;"> <!ENTITY Ocirc "&#x00D4;"> <!ENTITY Otilde "&#x00D5;"> <!ENTITY Ouml "&#x00D6;"> <!ENTITY times "&#x00D7;"> <!ENTITY Oslash "&#x00D8;"> <!ENTITY Ugrave "&#x00D9;"> <!ENTITY Uacute "&#x00DA;"> <!ENTITY Ucirc "&#x00DB;"> <!ENTITY Uuml "&#x00DC;"> <!ENTITY Yacute "&#x00DD;"> <!ENTITY THORN "&#x00DE;"> <!ENTITY szlig "&#x00DF;"> <!ENTITY agrave "&#x00E0;"> <!ENTITY aacute "&#x00E1;"> <!ENTITY acirc "&#x00E2;"> <!ENTITY atilde "&#x00E3;"> <!ENTITY auml "&#x00E4;"> <!ENTITY aring "&#x00E5;"> <!ENTITY aelig "&#x00E6;"> <!ENTITY ccedil "&#x00E7;"> <!ENTITY egrave "&#x00E8;"> <!ENTITY eacute "&#x00E9;"> <!ENTITY ecirc "&#x00EA;"> <!ENTITY euml "&#x00EB;"> <!ENTITY igrave "&#x00EC;"> <!ENTITY iacute "&#x00ED;"> <!ENTITY icirc "&#x00EE;"> <!ENTITY iuml "&#x00EF;"> <!ENTITY eth "&#x00F0;"> <!ENTITY ntilde "&#x00F1;"> <!ENTITY ograve "&#x00F2;"> <!ENTITY oacute "&#x00F3;"> <!ENTITY ocirc "&#x00F4;"> <!ENTITY otilde "&#x00F5;"> <!ENTITY ouml "&#x00F6;"> <!ENTITY divide "&#x00F7;"> <!ENTITY oslash "&#x00F8;"> <!ENTITY ugrave "&#x00F9;"> <!ENTITY uacute "&#x00FA;"> <!ENTITY ucirc "&#x00FB;"> <!ENTITY uuml "&#x00FC;"> <!ENTITY yacute "&#x00FD;"> <!ENTITY thorn "&#x00FE;"> <!ENTITY yuml "&#x00FF;"> <!ENTITY OElig "&#x0152;"> <!ENTITY oelig "&#x0153;"> <!ENTITY Scaron "&#x0160;"> <!ENTITY scaron "&#x0161;"> <!ENTITY Yuml "&#x0178;"> <!ENTITY fnof "&#x0192;"> <!ENTITY circ "&#x02C6;"> <!ENTITY tilde "&#x02DC;"> <!ENTITY Alpha "&#x0391;"> <!ENTITY Beta "&#x0392;"> <!ENTITY Gamma "&#x0393;"> <!ENTITY Epsilon "&#x0395;"> <!ENTITY Zeta "&#x0396;"> <!ENTITY Eta "&#x0397;"> <!ENTITY Theta "&#x0398;"> <!ENTITY Iota "&#x0399;"> <!ENTITY Kappa "&#x039A;"> <!ENTITY Lambda "&#x039B;"> <!ENTITY Mu "&#x039C;"> <!ENTITY Nu "&#x039D;"> <!ENTITY Xi "&#x039E;"> <!ENTITY Omicron "&#x039F;"> <!ENTITY Pi "&#x03A0;"> <!ENTITY Rho "&#x03A1;"> <!ENTITY Sigma "&#x03A3;"> <!ENTITY Tau "&#x03A4;"> <!ENTITY Upsilon "&#x03A5;"> <!ENTITY Phi "&#x03A6;"> <!ENTITY Chi "&#x03A7;"> <!ENTITY Psi "&#x03A8;"> <!ENTITY Omega "&#x03A9;"> <!ENTITY alpha "&#x03B1;"> <!ENTITY beta "&#x03B2;"> <!ENTITY gamma "&#x03B3;"> <!ENTITY delta "&#x03B4;"> <!ENTITY epsilon "&#x03B5;"> <!ENTITY zeta "&#x03B6;"> <!ENTITY eta "&#x03B7;"> <!ENTITY theta "&#x03B8;"> <!ENTITY iota "&#x03B9;"> <!ENTITY kappa "&#x03BA;"> <!ENTITY lambda "&#x03BB;"> <!ENTITY mu "&#x03BC;"> <!ENTITY nu "&#x03BD;"> <!ENTITY xi "&#x03BE;"> <!ENTITY omicron "&#x03BF;"> <!ENTITY pi "&#x03C0;"> <!ENTITY rho "&#x03C1;"> <!ENTITY sigmaf "&#x03C2;"> <!ENTITY sigma "&#x03C3;"> <!ENTITY tau "&#x03C4;"> <!ENTITY upsilon "&#x03C5;"> <!ENTITY phi "&#x03C6;"> <!ENTITY chi "&#x03C7;"> <!ENTITY psi "&#x03C8;"> <!ENTITY omega "&#x03C9;"> <!ENTITY thetasym "&#x03D1;"> <!ENTITY upsih "&#x03D2;"> <!ENTITY piv "&#x03D6;"> <!ENTITY ensp "&#x2002;"> <!ENTITY emsp "&#x2003;"> <!ENTITY thinsp "&#x2009;"> <!ENTITY zwnj "&#x200C;"> <!ENTITY zwj "&#x200D;"> <!ENTITY lrm "&#x200E;"> <!ENTITY rlm "&#x200F;"> <!ENTITY ndash "&#x2013;"> <!ENTITY mdash "&#x2014;"> <!ENTITY lsquo "&#x2018;"> <!ENTITY rsquo "&#x2019;"> <!ENTITY sbquo "&#x201A;"> <!ENTITY ldquo "&#x201C;"> <!ENTITY rdquo "&#x201D;"> <!ENTITY bdquo "&#x201E;"> <!ENTITY dagger "&#x2020;"> <!ENTITY Dagger "&#x2021;"> <!ENTITY bull "&#x2022;"> <!ENTITY hellip "&#x2026;"> <!ENTITY permil "&#x2030;"> <!ENTITY prime "&#x2032;"> <!ENTITY Prime "&#x2033;"> <!ENTITY lsaquo "&#x2039;"> <!ENTITY rsaquo "&#x203A;"> <!ENTITY oline "&#x203E;"> <!ENTITY frasl "&#x2044;"> <!ENTITY euro "&#x20AC;"> <!ENTITY image "&#x2111;"> <!ENTITY weierp "&#x2118;"> <!ENTITY real "&#x211C;"> <!ENTITY trade "&#x2122;"> <!ENTITY alefsym "&#x2135;"> <!ENTITY larr "&#x2190;"> <!ENTITY uarr "&#x2191;"> <!ENTITY rarr "&#x2192;"> <!ENTITY darr "&#x2193;"> <!ENTITY harr "&#x2194;"> <!ENTITY crarr "&#x21B5;"> <!ENTITY lArr "&#x21D0;"> <!ENTITY uArr "&#x21D1;"> <!ENTITY rArr "&#x21D2;"> <!ENTITY dArr "&#x21D3;"> <!ENTITY hArr "&#x21D4;"> <!ENTITY forall "&#x2200;"> <!ENTITY part "&#x2202;"> <!ENTITY exist "&#x2203;"> <!ENTITY empty "&#x2205;"> <!ENTITY nabla "&#x2207;"> <!ENTITY isin "&#x2208;"> <!ENTITY notin "&#x2209;"> <!ENTITY ni "&#x220B;"> <!ENTITY prod "&#x220F;"> <!ENTITY sum "&#x2211;"> <!ENTITY minus "&#x2212;"> <!ENTITY lowast "&#x2217;"> <!ENTITY radic "&#x221A;"> <!ENTITY prop "&#x221D;"> <!ENTITY infin "&#x221E;"> <!ENTITY ang "&#x2220;"> <!ENTITY and "&#x2227;"> <!ENTITY or "&#x2228;"> <!ENTITY cap "&#x2229;"> <!ENTITY cup "&#x222A;"> <!ENTITY int "&#x222B;"> <!ENTITY there4 "&#x2234;"> <!ENTITY sim "&#x223C;"> <!ENTITY cong "&#x2245;"> <!ENTITY asymp "&#x2248;"> <!ENTITY ne "&#x2260;"> <!ENTITY equiv "&#x2261;"> <!ENTITY le "&#x2264;"> <!ENTITY ge "&#x2265;"> <!ENTITY sub "&#x2282;"> <!ENTITY sup "&#x2283;"> <!ENTITY nsub "&#x2284;"> <!ENTITY sube "&#x2286;"> <!ENTITY supe "&#x2287;"> <!ENTITY oplus "&#x2295;"> <!ENTITY otimes "&#x2297;"> <!ENTITY perp "&#x22A5;"> <!ENTITY sdot "&#x22C5;"> <!ENTITY lceil "&#x2308;"> <!ENTITY rceil "&#x2309;"> <!ENTITY lfloor "&#x230A;"> <!ENTITY rfloor "&#x230B;"> <!ENTITY lang "&#x2329;"> <!ENTITY rang "&#x232A;"> <!ENTITY loz "&#x25CA;"> <!ENTITY spades "&#x2660;"> <!ENTITY clubs "&#x2663;"> <!ENTITY hearts "&#x2665;"> <!ENTITY diams "&#x2666;"> ]>';
559
+ }
560
+ } /* class FeedWordPie_Parser */
561
+
562
+
feedwordpie.class.php → extend/SimplePie/feedwordpie.class.php RENAMED
File without changes
feedwordpress-content-type-sniffer.class.php → extend/SimplePie/feedwordpie_content_type_sniffer.class.php RENAMED
@@ -3,7 +3,7 @@ if (!class_exists('SimplePie_Content_Type_Sniffer')) :
3
  require_once(ABSPATH . WPINC . '/class-simplepie.php');
4
  endif;
5
 
6
- class FeedWordPress_Content_Type_Sniffer extends SimplePie_Content_Type_Sniffer {
7
  /**
8
  * Get the Content-Type of the specified file
9
  *
@@ -55,6 +55,6 @@ class FeedWordPress_Content_Type_Sniffer extends SimplePie_Content_Type_Sniffer
55
  $this->file->headers['content-type'] = 'text/xml'; // Generic
56
  endif;
57
  return parent::get_type();
58
- } /* FeedWordPress_Content_Type_Sniffer::get_type() */
59
- } /* class FeedWordPress_Content_Type_Sniffer */
60
 
3
  require_once(ABSPATH . WPINC . '/class-simplepie.php');
4
  endif;
5
 
6
+ class FeedWordPie_Content_Type_Sniffer extends SimplePie_Content_Type_Sniffer {
7
  /**
8
  * Get the Content-Type of the specified file
9
  *
55
  $this->file->headers['content-type'] = 'text/xml'; // Generic
56
  endif;
57
  return parent::get_type();
58
+ } /* FeedWordPie_Content_Type_Sniffer::get_type() */
59
+ } /* class FeedWordPie_Content_Type_Sniffer */
60
 
feedwordpress_file.class.php → extend/SimplePie/feedwordpie_file.class.php RENAMED
@@ -3,7 +3,7 @@ global $fwp_credentials;
3
 
4
  $fwp_credentials = NULL;
5
 
6
- class FeedWordPress_File extends WP_SimplePie_File {
7
  public function __construct ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
8
  global $feedwordpress;
9
  global $wp_version;
@@ -95,6 +95,6 @@ class FeedWordPress_File extends WP_SimplePie_File {
95
  // to break and fall on its ass when SimplePie is getting a 304,
96
  // but doesn't realize it because this member is "304" instead.
97
  $this->status_code = (int) $this->status_code;
98
- }
99
- } /* class FeedWordPress_File () */
100
 
3
 
4
  $fwp_credentials = NULL;
5
 
6
+ class FeedWordPie_File extends WP_SimplePie_File {
7
  public function __construct ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
8
  global $feedwordpress;
9
  global $wp_version;
95
  // to break and fall on its ass when SimplePie is getting a 304,
96
  // but doesn't realize it because this member is "304" instead.
97
  $this->status_code = (int) $this->status_code;
98
+ } /* FeedWordPie_File::__construct () */
99
+ } /* class FeedWordPie_File () */
100
 
extend/SimplePie/feedwordpie_item.class.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $subdir = dirname(__FILE__);
3
+ $ver = SIMPLEPIE_VERSION;;
4
+ $mod = basename(__FILE__);
5
+
6
+ if ( is_readable("${subdir}/${ver}/${mod}") ) :
7
+ $modClassPath = "${subdir}/${ver}/${mod}";
8
+ else :
9
+ $modClassPath = "${subdir}/default/${mod}";
10
+ endif;
11
+
12
+ require_once("${modClassPath}");
extend/SimplePie/feedwordpie_parser.class.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $subdir = dirname(__FILE__);
3
+ $ver = SIMPLEPIE_VERSION;
4
+ $mod = basename(__FILE__);
5
+
6
+ if ( is_readable("${subdir}/${ver}/${mod}") ) :
7
+ $modClassPath = "${subdir}/${ver}/${mod}";
8
+ else :
9
+ $modClassPath = "${subdir}/default/${mod}";
10
+ endif;
11
+
12
+ require_once("${modClassPath}");
externals/myphp/myphp.class.php CHANGED
@@ -30,12 +30,12 @@ if (!class_exists('MyPHP')) :
30
  if (isset($GLOBALS[$where]) and is_array($GLOBALS[$where])) :
31
  if (isset($GLOBALS[$where][$key])) :
32
  $ret = $GLOBALS[$where][$key];
33
-
34
- // Magic quotes are like the stupidest
35
- // thing ever.
36
- if (get_magic_quotes_gpc()) :
37
- $ret = self::stripslashes_deep($ret);
38
- endif;
39
  endif;
40
  endif;
41
 
30
  if (isset($GLOBALS[$where]) and is_array($GLOBALS[$where])) :
31
  if (isset($GLOBALS[$where][$key])) :
32
  $ret = $GLOBALS[$where][$key];
33
+
34
+ // Magic quotes were just like the stupidest
35
+ // thing ever. (<http://php.net/manual/en/security.magicquotes.php>)
36
+ // Happily they were DEPRECATED as of PHP 5.3.0,
37
+ // and REMOVED as of PHP 5.4.0, so we don't need
38
+ // to worry about them anymore.
39
  endif;
40
  endif;
41
 
feedwordpress-elements.js CHANGED
@@ -736,10 +736,10 @@ jQuery(document).ready(function($){
736
  tagBox.init();
737
  }
738
 
739
- $('.fwpfs').toggle(
740
  function(){$('.fwpfs').removeClass('slideUp').addClass('slideDown'); setTimeout(function(){if ( $('.fwpfs').hasClass('slideDown') ) { $('.fwpfs').addClass('slide-down'); }}, 10) },
741
  function(){$('.fwpfs').removeClass('slideDown').addClass('slideUp'); setTimeout(function(){if ( $('.fwpfs').hasClass('slideUp') ) { $('.fwpfs').removeClass('slide-down'); }}, 10) }
742
- );
743
  $('.fwpfs').bind(
744
  'change',
745
  function () { this.form.submit(); }
736
  tagBox.init();
737
  }
738
 
739
+ /*$('.fwpfs').toggle(
740
  function(){$('.fwpfs').removeClass('slideUp').addClass('slideDown'); setTimeout(function(){if ( $('.fwpfs').hasClass('slideDown') ) { $('.fwpfs').addClass('slide-down'); }}, 10) },
741
  function(){$('.fwpfs').removeClass('slideDown').addClass('slideUp'); setTimeout(function(){if ( $('.fwpfs').hasClass('slideUp') ) { $('.fwpfs').removeClass('slide-down'); }}, 10) }
742
+ );*/
743
  $('.fwpfs').bind(
744
  'change',
745
  function () { this.form.submit(); }
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: 2020.0118
7
  Author: C. Johnson
8
  Author URI: https://feedwordpress.radgeek.com/contact/
9
  License: GPL
@@ -11,7 +11,7 @@ License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
- * @version 2020.0118
15
  */
16
 
17
  # This plugin uses code derived from:
@@ -22,20 +22,24 @@ License: GPL
22
  # - WordPress Blog Tool and Publishing Platform <http://wordpress.org/>
23
  # - Github contributors @Flynsarmy, @BandonRandon, @david-robinson-practiceweb,
24
  # @daidais, @thegreatmichael, @stedaniels, @alexiskulash, @quassy, @zoul0813,
25
- # @timmmmyboy, @vobornik, and @inanimatt
 
26
  # according to the terms of the GNU General Public License.
27
 
28
  ####################################################################################
29
  ## CONSTANTS & DEFAULTS ############################################################
30
  ####################################################################################
31
 
32
- define ('FEEDWORDPRESS_VERSION', '2020.0118');
33
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://feedwordpress.radgeek.com/contact');
34
 
35
  if (!defined('FEEDWORDPRESS_BLEG')) :
36
  define ('FEEDWORDPRESS_BLEG', true);
37
  endif;
38
- define('FEEDWORDPRESS_BLEG_BTC', '15EsQ9QMZtLytsaVYZUaUCmrkSMaxZBTso');
 
 
 
39
  define('FEEDWORDPRESS_BLEG_PAYPAL', '22PAJZZCK5Z3W');
40
 
41
  // Defaults
@@ -134,13 +138,13 @@ require_once("${dir}/compatability.php"); // Legacy API
134
  require_once("${dir}/syndicatedpost.class.php");
135
  require_once("${dir}/syndicatedlink.class.php");
136
  require_once("${dir}/feedwordpresshtml.class.php");
137
- require_once("${dir}/feedwordpress-content-type-sniffer.class.php");
138
  require_once("${dir}/inspectpostmeta.class.php");
139
  require_once("${dir}/syndicationdataqueries.class.php");
140
- require_once("${dir}/feedwordpie.class.php");
141
- require_once("${dir}/feedwordpie_item.class.php");
142
- require_once("${dir}/feedwordpress_file.class.php");
143
- require_once("${dir}/feedwordpress_parser.class.php");
 
144
  require_once("${dir}/feedwordpressrpc.class.php");
145
  require_once("${dir}/feedwordpresshttpauthenticator.class.php");
146
  require_once("${dir}/feedwordpresslocalpost.class.php");
@@ -181,79 +185,7 @@ endif;
181
 
182
  $feedwordpress = new FeedWordPress;
183
  if (!$feedwordpress->needs_upgrade()) : // only work if the conditions are safe!
184
-
185
- # Syndicated items are generally received in output-ready (X)HTML and
186
- # should not be folded, crumpled, mutilated, or spindled by WordPress
187
- # formatting filters. But we don't want to interfere with filters for
188
- # any locally-authored posts, either.
189
- #
190
- # What WordPress should really have is a way for upstream filters to
191
- # stop downstream filters from running at all. Since it doesn't, and
192
- # since a downstream filter can't access the original copy of the text
193
- # that is being filtered, what we will do here is (1) save a copy of the
194
- # original text upstream, before any other filters run, and then (2)
195
- # retrieve that copy downstream, after all the other filters run, *if*
196
- # this is a syndicated post
197
-
198
- add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
199
- add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
200
-
201
- add_action('atom_entry', 'feedwordpress_item_feed_data');
202
-
203
- # Filter in original permalinks if the user wants that
204
- add_filter('post_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 3);
205
- add_filter('post_type_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 4);
206
-
207
- # When foreign URLs are used for permalinks in feeds or display
208
- # contexts, they need to be escaped properly.
209
- add_filter('the_permalink', 'syndication_permalink_escaped');
210
- add_filter('the_permalink_rss', 'syndication_permalink_escaped');
211
-
212
- add_filter('post_comments_feed_link', 'syndication_comments_feed_link');
213
-
214
- # WTF? By default, wp_insert_link runs incoming link_url and link_rss
215
- # URIs through default filters that include `wp_kses()`. But `wp_kses()`
216
- # just happens to escape any occurrence of & to &amp; -- which just
217
- # happens to fuck up any URI with a & to separate GET parameters.
218
- remove_filter('pre_link_rss', 'wp_filter_kses');
219
- remove_filter('pre_link_url', 'wp_filter_kses');
220
-
221
- # Boilerplate functionality: hook in to title, excerpt, and content to add boilerplate text
222
- $hookOrder = get_option('feedwordpress_boilerplate_hook_order', FEEDWORDPRESS_BOILERPLATE_DEFAULT_HOOK_ORDER);
223
- add_filter(
224
- /*hook=*/ 'the_title',
225
- /*function=*/ 'add_boilerplate_title',
226
- /*priority=*/ $hookOrder,
227
- /*arguments=*/ 2
228
- );
229
- add_filter(
230
- /*hook=*/ 'get_the_excerpt',
231
- /*function=*/ 'add_boilerplate_excerpt',
232
- /*priority=*/ $hookOrder,
233
- /*arguments=*/ 1
234
- );
235
- add_filter(
236
- /*hook=*/ 'the_content',
237
- /*function=*/ 'add_boilerplate_content',
238
- /*priority=*/ $hookOrder,
239
- /*arguments=*/ 1
240
- );
241
- add_filter(
242
- /*hook=*/ 'the_content_rss',
243
- /*function=*/ 'add_boilerplate_content',
244
- /*priority=*/ $hookOrder,
245
- /*arguments=*/ 1
246
- );
247
-
248
- # Admin menu
249
- add_action('admin_init', array($feedwordpress, 'admin_init'));
250
- add_action('admin_menu', 'fwp_add_pages');
251
- add_action('admin_notices', 'fwp_check_debug');
252
-
253
- add_action('admin_menu', 'feedwordpress_add_post_edit_controls');
254
- add_action('save_post', 'feedwordpress_save_post_edit_controls');
255
-
256
- add_action('admin_footer', array($feedwordpress, 'admin_footer'));
257
 
258
  # Inbound XML-RPC update methods
259
  $feedwordpressRPC = new FeedWordPressRPC;
@@ -268,38 +200,9 @@ if (!$feedwordpress->needs_upgrade()) : // only work if the conditions are safe!
268
  add_action('feedwordpress_update', 'fwp_hold_pings');
269
  add_action('feedwordpress_update_complete', 'fwp_release_pings');
270
 
271
- add_action('syndicated_feed_error', array('FeedWordPressDiagnostic', 'feed_error'), 100, 3);
272
-
273
- add_action('wp_footer', 'debug_out_feedwordpress_footer', -100);
274
- add_action('admin_footer', 'debug_out_feedwordpress_footer', -100);
275
-
276
- # Cron-less auto-update. Hooray!
277
- $autoUpdateHook = $feedwordpress->automatic_update_hook();
278
- if (!is_null($autoUpdateHook)) :
279
- add_action($autoUpdateHook, array($feedwordpress, 'auto_update'));
280
- endif;
281
-
282
- add_action('init', array($feedwordpress, 'init'));
283
- add_action('wp_loaded', array($feedwordpress, 'wp_loaded'));
284
-
285
- add_action('shutdown', array($feedwordpress, 'email_diagnostic_log'));
286
- add_action('shutdown', array($feedwordpress, 'feedwordpress_cleanup'));
287
- add_action('wp_dashboard_setup', array($feedwordpress, 'dashboard_setup'));
288
-
289
- # Default sanitizers
290
- add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
291
- add_filter('syndicated_item_content', array('SyndicatedPost', 'sanitize_content'), 0, 2);
292
-
293
- add_action('plugins_loaded', array($feedwordpress, 'admin_api'));
294
- add_action('all_admin_notices', array($feedwordpress, 'all_admin_notices'));
295
-
296
- // Use our the cache settings that we want.
297
- add_filter('wp_feed_cache_transient_lifetime', array('FeedWordPress', 'cache_lifetime'));
298
-
299
-
300
  else :
301
  # Hook in the menus, which will just point to the upgrade interface
302
- add_action('admin_menu', 'fwp_add_pages');
303
  endif; // if (!FeedWordPress::needs_upgrade())
304
 
305
  register_deactivation_hook(__FILE__, 'feedwordpress_deactivate');
@@ -526,433 +429,16 @@ function syndication_comments_feed_link ($link) {
526
  return $link;
527
  } /* function syndication_comments_feed_link() */
528
 
529
- ################################################################################
530
- ## ADMIN MENU ADD-ONS: register Dashboard management pages #####################
531
- ################################################################################
532
-
533
- function fwp_add_pages () {
534
- global $feedwordpress;
535
-
536
- $menu_cap = FeedWordPress::menu_cap();
537
- $settings_cap = FeedWordPress::menu_cap(/*sub=*/ true);
538
- $syndicationMenu = FeedWordPress::path('syndication.php');
539
-
540
- add_menu_page(
541
- 'Syndicated Sites', 'Syndication',
542
- $menu_cap,
543
- $syndicationMenu,
544
- NULL,
545
- plugins_url( '/'.FeedWordPress::path('feedwordpress-tiny.png') )
546
- );
547
-
548
- do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
549
- add_submenu_page(
550
- $syndicationMenu, 'Syndicated Sites', 'Syndicated Sites',
551
- $settings_cap, $syndicationMenu
552
- );
553
-
554
- do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
555
- add_submenu_page(
556
- $syndicationMenu, 'Syndicated Feeds & Updates', 'Feeds & Updates',
557
- $settings_cap, FeedWordPress::path('feeds-page.php')
558
- );
559
-
560
- do_action('feedwordpress_admin_menu_pre_posts', $menu_cap, $settings_cap);
561
- add_submenu_page(
562
- $syndicationMenu, 'Syndicated Posts & Links', 'Posts & Links',
563
- $settings_cap, FeedWordPress::path('posts-page.php')
564
- );
565
-
566
- do_action('feedwordpress_admin_menu_pre_authors', $menu_cap, $settings_cap);
567
- add_submenu_page(
568
- $syndicationMenu, 'Syndicated Authors', 'Authors',
569
- $settings_cap, FeedWordPress::path('authors-page.php')
570
- );
571
-
572
- do_action('feedwordpress_admin_menu_pre_categories', $menu_cap, $settings_cap);
573
- add_submenu_page(
574
- $syndicationMenu, 'Categories & Tags', 'Categories & Tags',
575
- $settings_cap, FeedWordPress::path('categories-page.php')
576
- );
577
-
578
- do_action('feedwordpress_admin_menu_pre_performance', $menu_cap, $settings_cap);
579
- add_submenu_page(
580
- $syndicationMenu, 'FeedWordPress Performance', 'Performance',
581
- $settings_cap, FeedWordPress::path('performance-page.php')
582
- );
583
-
584
- do_action('feedwordpress_admin_menu_pre_diagnostics', $menu_cap, $settings_cap);
585
- add_submenu_page(
586
- $syndicationMenu, 'FeedWordPress Diagnostics', 'Diagnostics',
587
- $settings_cap, FeedWordPress::path('diagnostics-page.php')
588
- );
589
-
590
- add_filter('page_row_actions', array($feedwordpress, 'row_actions'), 10, 2);
591
- add_filter('post_row_actions', array($feedwordpress, 'row_actions'), 10, 2);
592
- } /* function fwp_add_pages () */
593
-
594
- function fwp_check_debug () {
595
- // This is a horrible fucking kludge that I have to do because the
596
- // admin notice code is triggered before the code that updates the
597
- // setting.
598
- if (isset($_POST['feedwordpress_debug'])) :
599
- $feedwordpress_debug = $_POST['feedwordpress_debug'];
600
- else :
601
- $feedwordpress_debug = get_option('feedwordpress_debug');
602
- endif;
603
- if ($feedwordpress_debug==='yes') :
604
- ?>
605
- <div class="error">
606
- <p><strong>FeedWordPress warning.</strong> Debugging mode is <strong>ON</strong>.
607
- While it remains on, FeedWordPress displays many diagnostic error messages,
608
- warnings, and notices that are ordinarily suppressed, and also turns off all
609
- caching of feeds. Use with caution: this setting is absolutely inappropriate
610
- for a production server.</p>
611
- </div>
612
- <?php
613
- endif;
614
- } /* function fwp_check_debug () */
615
-
616
- ################################################################################
617
- ## fwp_hold_pings() and fwp_release_pings(): Outbound XML-RPC ping reform ####
618
- ## ... 'coz it's rude to send 500 pings the first time your aggregator runs ####
619
- ################################################################################
620
-
621
- $fwp_held_ping = NULL; // NULL: not holding pings yet
622
-
623
- function fwp_hold_pings () {
624
- global $fwp_held_ping;
625
- if (is_null($fwp_held_ping)):
626
- $fwp_held_ping = 0; // 0: ready to hold pings; none yet received
627
- endif;
628
- }
629
-
630
- function fwp_release_pings () {
631
- global $fwp_held_ping;
632
- if ($fwp_held_ping):
633
- if (function_exists('wp_schedule_single_event')) :
634
- wp_schedule_single_event(time(), 'do_pings');
635
- else :
636
- generic_ping($fwp_held_ping);
637
- endif;
638
- endif;
639
- $fwp_held_ping = NULL; // NULL: not holding pings anymore
640
- }
641
-
642
- function fwp_do_pings () {
643
- if (!is_null($fwp_held_ping) and $post_id) : // Defer until we're done updating
644
- $fwp_held_ping = $post_id;
645
- elseif (function_exists('do_all_pings')) :
646
- do_all_pings();
647
- else :
648
- generic_ping($fwp_held_ping);
649
- endif;
650
- }
651
-
652
- function fwp_publish_post_hook ($post_id) {
653
- global $fwp_held_ping;
654
-
655
- if (!is_null($fwp_held_ping)) : // Syndicated post. Don't mark with _pingme
656
- if ( defined('XMLRPC_REQUEST') )
657
- do_action('xmlrpc_publish_post', $post_id);
658
- if ( defined('APP_REQUEST') )
659
- do_action('app_publish_post', $post_id);
660
-
661
- if ( defined('WP_IMPORTING') )
662
- return;
663
-
664
- // Defer sending out pings until we finish updating
665
- $fwp_held_ping = $post_id;
666
- else :
667
- if (function_exists('_publish_post_hook')) : // WordPress 2.3
668
- _publish_post_hook($post_id);
669
- endif;
670
- endif;
671
- }
672
-
673
- function feedwordpress_add_post_edit_controls () {
674
- global $feedwordpress;
675
- global $inspectPostMeta;
676
-
677
- // Put in Manual Editing checkbox
678
- add_action('add_meta_boxes', 'feedwordpress_post_add_meta_boxes', 10, 2);
679
-
680
- add_filter('user_can_richedit', array($feedwordpress, 'user_can_richedit'), 1000, 1);
681
-
682
- if (FeedWordPressDiagnostic::is_on('syndicated_posts:static_meta_data')) :
683
- $inspectPostMeta = new InspectPostMeta;
684
- endif;
685
- } // function feedwordpress_add_post_edit_controls ()
686
-
687
- function feedwordpress_post_add_meta_boxes ($post_type, $post) {
688
- add_meta_box(
689
- 'feedwordpress-post-controls',
690
- __('Syndication'),
691
- 'feedwordpress_post_edit_controls',
692
- $post_type,
693
- 'side',
694
- 'high'
695
- );
696
- }
697
-
698
- function feedwordpress_post_edit_controls () {
699
- global $post;
700
-
701
- $frozen_values = get_post_custom_values('_syndication_freeze_updates', $post->ID);
702
- $frozen_post = ($frozen_values !== null and count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
703
-
704
- if (is_syndicated($post->ID)) :
705
- ?>
706
- <p>This is a syndicated post, which originally appeared at
707
- <cite><?php print esc_html(get_syndication_source(NULL, $post->ID)); ?></cite>.
708
- <a href="<?php print esc_html(get_syndication_permalink($post->ID)); ?>">View original post</a>.</p>
709
-
710
- <?php do_action('feedwordpress_post_edit_controls_pre', $post); ?>
711
-
712
- <p><input type="hidden" name="feedwordpress_noncename" id="feedwordpress_noncename" value="<?php print wp_create_nonce(plugin_basename(__FILE__)); ?>" />
713
- <label><input type="checkbox" name="freeze_updates" value="yes" <?php if ($frozen_post) : ?>checked="checked"<?php endif; ?> /> <strong>Manual editing.</strong>
714
- If set, FeedWordPress will not overwrite the changes you make manually
715
- to this post, if the syndicated content is updated on the
716
- feed.</label></p>
717
-
718
- <?php do_action('feedwordpress_post_edit_controls', $post); ?>
719
-
720
- <?php
721
- else :
722
- ?>
723
- <p>This post was created locally at this website.</p>
724
- <?php
725
- endif;
726
- } /* function feedwordpress_post_edit_controls () */
727
-
728
- function feedwordpress_save_post_edit_controls ( $post_id ) {
729
- global $post;
730
- if (!isset($_POST['feedwordpress_noncename']) or !wp_verify_nonce($_POST['feedwordpress_noncename'], plugin_basename(__FILE__))) :
731
- return $post_id;
732
- endif;
733
-
734
- // Verify if this is an auto save routine. If it is our form has
735
- // not been submitted, so we don't want to do anything.
736
- if ( defined('DOING_AUTOSAVE') and DOING_AUTOSAVE ) :
737
- return $post_id;
738
- endif;
739
-
740
- // The data in $_POST is for applying only to the post actually
741
- // in the edit window, i.e. $post
742
- if ($post_id != $post->ID) :
743
- return $post_id;
744
- endif;
745
-
746
- // Check permissions
747
- $cap[0] = 'edit_post';
748
- $cap[1] = 'edit_' . $_POST['post_type'];
749
- if (
750
- !current_user_can( $cap[0], $post_id )
751
- and !current_user_can( $cap[1], $post_id )
752
- ) :
753
- return $post_id;
754
- endif;
755
-
756
- // OK, we're golden. Now let's save some data.
757
- if (isset($_POST['freeze_updates'])) :
758
-
759
- update_post_meta($post_id, '_syndication_freeze_updates', $_POST['freeze_updates']);
760
- $ret = $_POST['freeze_updates'];
761
-
762
- // If you make manual edits through the WordPress editing
763
- // UI then they should be run through normal WP formatting
764
- // filters.
765
- update_post_meta($post_id, '_feedwordpress_formatting_filters', 'yes');
766
-
767
- else :
768
- delete_post_meta($post_id, '_syndication_freeze_updates');
769
- $ret = NULL;
770
- endif;
771
 
772
- do_action('feedwordpress_save_edit_controls', $post_id);
773
-
774
- return $ret;
775
- } // function feedwordpress_save_edit_controls
776
 
777
  ################################################################################
778
  ## class FeedWordPressBoilerplateReformatter ###################################
779
  ################################################################################
780
 
781
- class FeedWordPressBoilerplateReformatter {
782
- var $id, $element;
783
-
784
- public function __construct ($id = NULL, $element = 'post') {
785
- $this->id = $id;
786
- $this->element = $element;
787
- }
788
-
789
- function shortcode_methods () {
790
- return array(
791
- 'source' => 'source_link',
792
- 'source-name' => 'source_name',
793
- 'source-url' => 'source_url',
794
- 'original-link' => 'original_link',
795
- 'original-url' => 'original_url',
796
- 'author' => 'source_author_link',
797
- 'author-name' => 'source_author',
798
- 'feed-setting' => 'source_setting',
799
- );
800
- }
801
- function do_shortcode ($template) {
802
- $codes = $this->shortcode_methods();
803
-
804
- // Register shortcodes relative to this object/post ID/element.
805
- foreach ($codes as $code => $method) :
806
- add_shortcode($code, array($this, $method));
807
- endforeach;
808
-
809
- $template = do_shortcode($template);
810
-
811
- // Unregister shortcodes.
812
- foreach ($codes as $code => $method) :
813
- remove_shortcode($code);
814
- endforeach;
815
-
816
- return $template;
817
- }
818
-
819
- function source_name ($atts) {
820
- $param = shortcode_atts(array(
821
- 'original' => NULL,
822
- ), $atts);
823
- return get_syndication_source($param['original'], $this->id);
824
- }
825
- function source_url ($atts) {
826
- $param = shortcode_atts(array(
827
- 'original' => NULL,
828
- ), $atts);
829
- return get_syndication_source_link($param['original'], $this->id);
830
- }
831
- function source_link ($atts) {
832
- switch (strtolower($atts[0])) :
833
- case '-name' :
834
- $ret = $this->source_name($atts);
835
- break;
836
- case '-url' :
837
- $ret = $this->source_url($atts);
838
- break;
839
- default :
840
- $param = shortcode_atts(array(
841
- 'original' => NULL,
842
- ), $atts);
843
- if ('title' == $this->element) :
844
- $ret = $this->source_name($atts);
845
- else :
846
- $ret = '<a href="'.htmlspecialchars($this->source_url($atts)).'">'.htmlspecialchars($this->source_name($atts)).'</a>';
847
- endif;
848
- endswitch;
849
- return $ret;
850
- }
851
- function source_setting ($atts) {
852
- $param = shortcode_atts(array(
853
- 'key' => NULL,
854
- ), $atts);
855
- return get_feed_meta($param['key'], $this->id);
856
- }
857
- function original_link ($atts, $text) {
858
- $url = $this->original_url($atts);
859
- return '<a href="'.esc_url($url).'">'.do_shortcode($text).'</a>';
860
- }
861
- function original_url ($atts) {
862
- return get_syndication_permalink($this->id);
863
- }
864
- function source_author ($atts) {
865
- return get_the_author();
866
- }
867
- function source_author_link ($atts) {
868
- switch (strtolower($atts[0])) :
869
- case '-name' :
870
- $ret = $this->source_author($atts);
871
- break;
872
- default :
873
- global $authordata; // Janky.
874
- if ('title' == $this->element) :
875
- $ret = $this->source_author($atts);
876
- else :
877
- $ret = get_the_author();
878
- $url = get_author_posts_url((int) $authordata->ID, (int) $authordata->user_nicename);
879
- if ($url) :
880
- $ret = '<a href="'.$url.'" '
881
- .'title="Read other posts by '.esc_html($authordata->display_name).'">'
882
- .$ret
883
- .'</a>';
884
- endif;
885
- endif;
886
- endswitch;
887
- return $ret;
888
- }
889
- }
890
-
891
- function add_boilerplate_reformat ($template, $element, $id = NULL) {
892
- if ('post' == $element and !preg_match('/< (p|div) ( \s [^>]+ )? >/xi', $template)) :
893
- $template = '<p class="syndicated-attribution">'.$template.'</p>';
894
- endif;
895
-
896
- $ref = new FeedWordPressBoilerplateReformatter($id, $element);
897
- return $ref->do_shortcode($template);
898
- }
899
-
900
- function add_boilerplate_simple ($element, $title, $id = NULL) {
901
- if (is_syndicated($id)) :
902
- $meta = get_feed_meta('boilerplate rules', $id);
903
- if ($meta and !is_array($meta)) : $meta = unserialize($meta); endif;
904
-
905
- if (!is_array($meta) or empty($meta)) :
906
- $meta = get_option('feedwordpress_boilerplate');
907
- endif;
908
-
909
- if (is_array($meta) and !empty($meta)) :
910
- foreach ($meta as $rule) :
911
- if ($element==$rule['element']) :
912
- $rule['template'] = add_boilerplate_reformat($rule['template'], $element, $id);
913
-
914
- if ('before'==$rule['placement']) :
915
- $title = $rule['template'] . ' ' . $title;
916
- else :
917
- $title = $title . ' ' . $rule['template'];
918
- endif;
919
- endif;
920
- endforeach;
921
- endif;
922
- endif;
923
- return $title;
924
- }
925
- function add_boilerplate_title ($title, $id = NULL) {
926
- return add_boilerplate_simple('title', $title, $id);
927
- }
928
- function add_boilerplate_excerpt ($title, $id = NULL) {
929
- return add_boilerplate_simple('excerpt', $title, $id);
930
- }
931
- function add_boilerplate_content ($content) {
932
- if (is_syndicated()) :
933
- $meta = get_feed_meta('boilerplate rules');
934
- if ($meta and !is_array($meta)) : $meta = unserialize($meta); endif;
935
-
936
- if (!is_array($meta) or empty($meta)) :
937
- $meta = get_option('feedwordpress_boilerplate');
938
- endif;
939
-
940
- if (is_array($meta) and !empty($meta)) :
941
- foreach ($meta as $rule) :
942
- if ('post'==$rule['element']) :
943
- $rule['template'] = add_boilerplate_reformat($rule['template'], 'post');
944
-
945
- if ('before'==$rule['placement']) :
946
- $content = $rule['template'] . "\n" . $content;
947
- else :
948
- $content = $content . "\n" . $rule['template'];
949
- endif;
950
- endif;
951
- endforeach;
952
- endif;
953
- endif;
954
- return $content;
955
- }
956
 
957
  ################################################################################
958
  ## class FeedWordPress #########################################################
@@ -1025,6 +511,216 @@ class FeedWordPress {
1025
  $this->httpauth = new FeedWordPressHTTPAuthenticator;
1026
  } /* FeedWordPress::__construct () */
1027
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1028
  /**
1029
  * FeedWordPress::subscribed (): Check whether a feed is currently in the
1030
  * subscription list for FeedWordPress.
@@ -2243,10 +1939,10 @@ class FeedWordPress {
2243
 
2244
  $pie_class = apply_filters('feedwordpress_simplepie_class', 'FeedWordPie');
2245
  $cache_class = apply_filters('feedwordpress_cache_class', 'WP_Feed_Cache');
2246
- $file_class = apply_filters('feedwordpress_file_class', 'FeedWordPress_File');
2247
- $parser_class = apply_filters('feedwordpress_parser_class', 'FeedWordPress_Parser');
2248
  $item_class = apply_filters('feedwordpress_item_class', 'FeedWordPie_Item');
2249
- $sniffer_class = apply_filters('feedwordpress_sniffer_class', 'FeedWordPress_Content_Type_Sniffer');
2250
 
2251
  $feed = new $pie_class;
2252
  $feed->set_feed_url($url);
3
  Plugin Name: FeedWordPress
4
  Plugin URI: http://feedwordpress.radgeek.com/
5
  Description: simple and flexible Atom/RSS syndication for WordPress
6
+ Version: 2020.0818
7
  Author: C. Johnson
8
  Author URI: https://feedwordpress.radgeek.com/contact/
9
  License: GPL
11
 
12
  /**
13
  * @package FeedWordPress
14
+ * @version 2020.0818
15
  */
16
 
17
  # This plugin uses code derived from:
22
  # - WordPress Blog Tool and Publishing Platform <http://wordpress.org/>
23
  # - Github contributors @Flynsarmy, @BandonRandon, @david-robinson-practiceweb,
24
  # @daidais, @thegreatmichael, @stedaniels, @alexiskulash, @quassy, @zoul0813,
25
+ # @timmmmyboy, @vobornik, @inanimatt, @tristanleboss, @martinburchell,
26
+ # @bigalownz, and @oppiansteve
27
  # according to the terms of the GNU General Public License.
28
 
29
  ####################################################################################
30
  ## CONSTANTS & DEFAULTS ############################################################
31
  ####################################################################################
32
 
33
+ define ('FEEDWORDPRESS_VERSION', '2020.0818');
34
  define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://feedwordpress.radgeek.com/contact');
35
 
36
  if (!defined('FEEDWORDPRESS_BLEG')) :
37
  define ('FEEDWORDPRESS_BLEG', true);
38
  endif;
39
+
40
+ define('FEEDWORDPRESS_BLEG_BTC_pre_2020', '15EsQ9QMZtLytsaVYZUaUCmrkSMaxZBTso');
41
+ define('FEEDWORDPRESS_BLEG_BTC', '1NB1ebYVb68Har4WijmE8gKnZ47NptCqtB'); // 2020.0201
42
+
43
  define('FEEDWORDPRESS_BLEG_PAYPAL', '22PAJZZCK5Z3W');
44
 
45
  // Defaults
138
  require_once("${dir}/syndicatedpost.class.php");
139
  require_once("${dir}/syndicatedlink.class.php");
140
  require_once("${dir}/feedwordpresshtml.class.php");
 
141
  require_once("${dir}/inspectpostmeta.class.php");
142
  require_once("${dir}/syndicationdataqueries.class.php");
143
+ require_once("${dir}/extend/SimplePie/feedwordpie.class.php");
144
+ require_once("${dir}/extend/SimplePie/feedwordpie_item.class.php");
145
+ require_once("${dir}/extend/SimplePie/feedwordpie_file.class.php");
146
+ require_once("${dir}/extend/SimplePie/feedwordpie_parser.class.php");
147
+ require_once("${dir}/extend/SimplePie/feedwordpie_content_type_sniffer.class.php");
148
  require_once("${dir}/feedwordpressrpc.class.php");
149
  require_once("${dir}/feedwordpresshttpauthenticator.class.php");
150
  require_once("${dir}/feedwordpresslocalpost.class.php");
185
 
186
  $feedwordpress = new FeedWordPress;
187
  if (!$feedwordpress->needs_upgrade()) : // only work if the conditions are safe!
188
+ $feedwordpress->add_filters();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
  # Inbound XML-RPC update methods
191
  $feedwordpressRPC = new FeedWordPressRPC;
200
  add_action('feedwordpress_update', 'fwp_hold_pings');
201
  add_action('feedwordpress_update_complete', 'fwp_release_pings');
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  else :
204
  # Hook in the menus, which will just point to the upgrade interface
205
+ add_action('admin_menu', array($feedwordpress, 'add_pages'));
206
  endif; // if (!FeedWordPress::needs_upgrade())
207
 
208
  register_deactivation_hook(__FILE__, 'feedwordpress_deactivate');
429
  return $link;
430
  } /* function syndication_comments_feed_link() */
431
 
432
+ require_once("${dir}/feedwordpress.pings.functions.php");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
433
 
434
+ require_once("${dir}/feedwordpress.wp-admin.post-edit.functions.php");
 
 
 
435
 
436
  ################################################################################
437
  ## class FeedWordPressBoilerplateReformatter ###################################
438
  ################################################################################
439
 
440
+ require_once("${dir}/feedwordpressboilerplatereformatter.class.php");
441
+ require_once("${dir}/feedwordpressboilerplatereformatter.shortcode.functions.php");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
442
 
443
  ################################################################################
444
  ## class FeedWordPress #########################################################
511
  $this->httpauth = new FeedWordPressHTTPAuthenticator;
512
  } /* FeedWordPress::__construct () */
513
 
514
+ /**
515
+ * FeedWordPress::add_filters() connects FeedWordPress to WordPress lifecycle
516
+ * events by setting up action and filter hooks.
517
+ *
518
+ * @uses get_option()
519
+ * @uses add_filter()
520
+ * @uses add_action()
521
+ * @uses remove_filter()
522
+ */
523
+ public function add_filters () {
524
+ # Syndicated items are generally received in output-ready (X)HTML and
525
+ # should not be folded, crumpled, mutilated, or spindled by WordPress
526
+ # formatting filters. But we don't want to interfere with filters for
527
+ # any locally-authored posts, either.
528
+ #
529
+ # What WordPress should really have is a way for upstream filters to
530
+ # stop downstream filters from running at all. Since it doesn't, and
531
+ # since a downstream filter can't access the original copy of the text
532
+ # that is being filtered, what we will do here is (1) save a copy of the
533
+ # original text upstream, before any other filters run, and then (2)
534
+ # retrieve that copy downstream, after all the other filters run, *if*
535
+ # this is a syndicated post
536
+
537
+ add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
538
+ add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
539
+
540
+ add_action('atom_entry', 'feedwordpress_item_feed_data');
541
+
542
+ # Filter in original permalinks if the user wants that
543
+ add_filter('post_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 3);
544
+ add_filter('post_type_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 4);
545
+
546
+ # When foreign URLs are used for permalinks in feeds or display
547
+ # contexts, they need to be escaped properly.
548
+ add_filter('the_permalink', 'syndication_permalink_escaped');
549
+ add_filter('the_permalink_rss', 'syndication_permalink_escaped');
550
+
551
+ add_filter('post_comments_feed_link', 'syndication_comments_feed_link');
552
+
553
+ # WTF? By default, wp_insert_link runs incoming link_url and link_rss
554
+ # URIs through default filters that include `wp_kses()`. But `wp_kses()`
555
+ # just happens to escape any occurrence of & to &amp; -- which just
556
+ # happens to fuck up any URI with a & to separate GET parameters.
557
+ remove_filter('pre_link_rss', 'wp_filter_kses');
558
+ remove_filter('pre_link_url', 'wp_filter_kses');
559
+
560
+ # Boilerplate functionality: hook in to title, excerpt, and content to add boilerplate text
561
+ $hookOrder = get_option('feedwordpress_boilerplate_hook_order', FEEDWORDPRESS_BOILERPLATE_DEFAULT_HOOK_ORDER);
562
+ add_filter(
563
+ /*hook=*/ 'the_title',
564
+ /*function=*/ 'add_boilerplate_title',
565
+ /*priority=*/ $hookOrder,
566
+ /*arguments=*/ 2
567
+ );
568
+ add_filter(
569
+ /*hook=*/ 'get_the_excerpt',
570
+ /*function=*/ 'add_boilerplate_excerpt',
571
+ /*priority=*/ $hookOrder,
572
+ /*arguments=*/ 1
573
+ );
574
+ add_filter(
575
+ /*hook=*/ 'the_content',
576
+ /*function=*/ 'add_boilerplate_content',
577
+ /*priority=*/ $hookOrder,
578
+ /*arguments=*/ 1
579
+ );
580
+ add_filter(
581
+ /*hook=*/ 'the_content_rss',
582
+ /*function=*/ 'add_boilerplate_content',
583
+ /*priority=*/ $hookOrder,
584
+ /*arguments=*/ 1
585
+ );
586
+
587
+ # Admin menu
588
+ add_action('admin_init', array($this, 'admin_init'));
589
+ add_action('admin_menu', array($this, 'add_pages'));
590
+ add_action('admin_notices', array($this, 'check_debug'));
591
+
592
+ add_action('admin_menu', 'feedwordpress_add_post_edit_controls');
593
+ add_action('save_post', 'feedwordpress_save_post_edit_controls');
594
+
595
+ add_action('admin_footer', array($this, 'admin_footer'));
596
+
597
+ add_action('syndicated_feed_error', array('FeedWordPressDiagnostic', 'feed_error'), 100, 3);
598
+
599
+ add_action('wp_footer', 'debug_out_feedwordpress_footer', -100);
600
+ add_action('admin_footer', 'debug_out_feedwordpress_footer', -100);
601
+
602
+ # Cron-less auto-update. Hooray!
603
+ $autoUpdateHook = $this->automatic_update_hook();
604
+ if (!is_null($autoUpdateHook)) :
605
+ add_action($autoUpdateHook, array($this, 'auto_update'));
606
+ endif;
607
+
608
+ add_action('init', array($this, 'init'));
609
+ add_action('wp_loaded', array($this, 'wp_loaded'));
610
+
611
+ add_action('shutdown', array($this, 'email_diagnostic_log'));
612
+ add_action('shutdown', array($this, 'feedwordpress_cleanup'));
613
+ add_action('wp_dashboard_setup', array($this, 'dashboard_setup'));
614
+
615
+ # Default sanitizers
616
+ add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
617
+ add_filter('syndicated_item_content', array('SyndicatedPost', 'sanitize_content'), 0, 2);
618
+
619
+ add_action('plugins_loaded', array($this, 'admin_api'));
620
+ add_action('all_admin_notices', array($this, 'all_admin_notices'));
621
+
622
+ // Use the cache settings that we want, from a static method
623
+ add_filter('wp_feed_cache_transient_lifetime', array(get_class($this), 'cache_lifetime'));
624
+
625
+ } /* FeedWordPress::add_filters () */
626
+
627
+ ################################################################################
628
+ ## ADMIN MENU ADD-ONS: register Dashboard management pages #####################
629
+ ################################################################################
630
+
631
+ /**
632
+ * FeedWordPress::add_pages(): set up WordPress admin interface pages thru
633
+ * hooking in Syndication menu and submenus
634
+ *
635
+ * @uses FeedWordPress::menu_cap()
636
+ * @uses FeedWordPress::path()
637
+ * @uses add_menu_page()
638
+ * @uses add_submenu_page()
639
+ * @uses do_action()
640
+ * @uses add_filter()
641
+ */
642
+ public function add_pages () {
643
+
644
+ $menu_cap = FeedWordPress::menu_cap();
645
+ $settings_cap = FeedWordPress::menu_cap(/*sub=*/ true);
646
+ $syndicationMenu = FeedWordPress::path('syndication.php');
647
+
648
+ add_menu_page(
649
+ 'Syndicated Sites', 'Syndication',
650
+ $menu_cap,
651
+ $syndicationMenu,
652
+ NULL,
653
+ plugins_url( '/'.FeedWordPress::path('feedwordpress-tiny.png') )
654
+ );
655
+
656
+ do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
657
+ add_submenu_page(
658
+ $syndicationMenu, 'Syndicated Sites', 'Syndicated Sites',
659
+ $settings_cap, $syndicationMenu
660
+ );
661
+
662
+ do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
663
+ add_submenu_page(
664
+ $syndicationMenu, 'Syndicated Feeds & Updates', 'Feeds & Updates',
665
+ $settings_cap, FeedWordPress::path('feeds-page.php')
666
+ );
667
+
668
+ do_action('feedwordpress_admin_menu_pre_posts', $menu_cap, $settings_cap);
669
+ add_submenu_page(
670
+ $syndicationMenu, 'Syndicated Posts & Links', 'Posts & Links',
671
+ $settings_cap, FeedWordPress::path('posts-page.php')
672
+ );
673
+
674
+ do_action('feedwordpress_admin_menu_pre_authors', $menu_cap, $settings_cap);
675
+ add_submenu_page(
676
+ $syndicationMenu, 'Syndicated Authors', 'Authors',
677
+ $settings_cap, FeedWordPress::path('authors-page.php')
678
+ );
679
+
680
+ do_action('feedwordpress_admin_menu_pre_categories', $menu_cap, $settings_cap);
681
+ add_submenu_page(
682
+ $syndicationMenu, 'Categories & Tags', 'Categories & Tags',
683
+ $settings_cap, FeedWordPress::path('categories-page.php')
684
+ );
685
+
686
+ do_action('feedwordpress_admin_menu_pre_performance', $menu_cap, $settings_cap);
687
+ add_submenu_page(
688
+ $syndicationMenu, 'FeedWordPress Performance', 'Performance',
689
+ $settings_cap, FeedWordPress::path('performance-page.php')
690
+ );
691
+
692
+ do_action('feedwordpress_admin_menu_pre_diagnostics', $menu_cap, $settings_cap);
693
+ add_submenu_page(
694
+ $syndicationMenu, 'FeedWordPress Diagnostics', 'Diagnostics',
695
+ $settings_cap, FeedWordPress::path('diagnostics-page.php')
696
+ );
697
+
698
+ add_filter('page_row_actions', array($this, 'row_actions'), 10, 2);
699
+ add_filter('post_row_actions', array($this, 'row_actions'), 10, 2);
700
+ } /* function FeedWordPress::add_pages () */
701
+
702
+ public function check_debug () {
703
+ // This is a horrible fucking kludge that I have to do because the
704
+ // admin notice code is triggered before the code that updates the
705
+ // setting.
706
+ if (isset($_POST['feedwordpress_debug'])) :
707
+ $feedwordpress_debug = $_POST['feedwordpress_debug'];
708
+ else :
709
+ $feedwordpress_debug = get_option('feedwordpress_debug');
710
+ endif;
711
+ if ($feedwordpress_debug==='yes') :
712
+ ?>
713
+ <div class="error">
714
+ <p><strong>FeedWordPress warning.</strong> Debugging mode is <strong>ON</strong>.
715
+ While it remains on, FeedWordPress displays many diagnostic error messages,
716
+ warnings, and notices that are ordinarily suppressed, and also turns off all
717
+ caching of feeds. Use with caution: this setting is absolutely inappropriate
718
+ for a production server.</p>
719
+ </div>
720
+ <?php
721
+ endif;
722
+ } /* function FeedWordPress::check_debug () */
723
+
724
  /**
725
  * FeedWordPress::subscribed (): Check whether a feed is currently in the
726
  * subscription list for FeedWordPress.
1939
 
1940
  $pie_class = apply_filters('feedwordpress_simplepie_class', 'FeedWordPie');
1941
  $cache_class = apply_filters('feedwordpress_cache_class', 'WP_Feed_Cache');
1942
+ $file_class = apply_filters('feedwordpress_file_class', 'FeedWordPie_File');
1943
+ $parser_class = apply_filters('feedwordpress_parser_class', 'FeedWordPie_Parser');
1944
  $item_class = apply_filters('feedwordpress_item_class', 'FeedWordPie_Item');
1945
+ $sniffer_class = apply_filters('feedwordpress_sniffer_class', 'FeedWordPie_Content_Type_Sniffer');
1946
 
1947
  $feed = new $pie_class;
1948
  $feed->set_feed_url($url);
feedwordpress.pings.functions.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ ################################################################################
3
+ ## fwp_hold_pings() and fwp_release_pings(): Outbound XML-RPC ping reform ####
4
+ ## ... 'coz it's rude to send 500 pings the first time your aggregator runs ####
5
+ ################################################################################
6
+
7
+ global $fwp_held_ping;
8
+
9
+ $fwp_held_ping = NULL; // NULL: not holding pings yet
10
+
11
+ function fwp_hold_pings () {
12
+ global $fwp_held_ping;
13
+ if (is_null($fwp_held_ping)):
14
+ $fwp_held_ping = 0; // 0: ready to hold pings; none yet received
15
+ FeedWordPress::diagnostic(
16
+ 'syndicated_posts:do_pings',
17
+ 'FeedWordPress is set up to hold pings, fwp_held_ping='.json_encode($fwp_held_ping)
18
+ );
19
+ endif;
20
+ }
21
+
22
+ function fwp_release_pings () {
23
+ global $fwp_held_ping;
24
+
25
+ $diag_message = null;
26
+ if ($fwp_held_ping):
27
+ if (function_exists('wp_schedule_single_event')) :
28
+ wp_schedule_single_event(time(), 'do_pings');
29
+ $diag_message = 'scheduled release of pings';
30
+ else :
31
+ generic_ping($fwp_held_ping);
32
+ $diag_message = 'released pings';
33
+ endif;
34
+ endif;
35
+
36
+ $fwp_held_ping = NULL; // NULL: not holding pings anymore
37
+
38
+ if (!is_null($diag_message)) :
39
+ FeedWordPress::diagnostic(
40
+ 'syndicated_posts:do_pings',
41
+ "FeedWordPress ${diag_message}, fwp_held_ping=".json_encode($fwp_held_ping)
42
+ );
43
+ endif;
44
+ }
45
+
46
+ function fwp_do_pings () {
47
+ if (!is_null($fwp_held_ping) and $post_id) : // Defer until we're done updating
48
+ $fwp_held_ping = $post_id;
49
+
50
+ FeedWordPress::diagnostic(
51
+ 'syndicated_posts:do_pings',
52
+ "FeedWordPress intercepted a ping event, fwp_held_ping=".json_encode($fwp_held_ping)
53
+ );
54
+
55
+ elseif (function_exists('do_all_pings')) :
56
+ do_all_pings();
57
+ else :
58
+ generic_ping($fwp_held_ping);
59
+ endif;
60
+ }
61
+
62
+ function fwp_publish_post_hook ($post_id) {
63
+ global $fwp_held_ping;
64
+
65
+ if (!is_null($fwp_held_ping)) : // Syndicated post. Don't mark with _pingme
66
+ if ( defined('XMLRPC_REQUEST') )
67
+ do_action('xmlrpc_publish_post', $post_id);
68
+ if ( defined('APP_REQUEST') )
69
+ do_action('app_publish_post', $post_id);
70
+
71
+ if ( defined('WP_IMPORTING') )
72
+ return;
73
+
74
+ // Defer sending out pings until we finish updating
75
+ $fwp_held_ping = $post_id;
76
+
77
+ FeedWordPress::diagnostic(
78
+ 'syndicated_posts:do_pings',
79
+ "FeedWordPress intercepted a post event, fwp_held_ping=".json_encode($fwp_held_ping)
80
+ );
81
+ else :
82
+ if (function_exists('_publish_post_hook')) : // WordPress 2.3
83
+ _publish_post_hook($post_id);
84
+ endif;
85
+ endif;
86
+ }
feedwordpress.wp-admin.post-edit.functions.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function feedwordpress_add_post_edit_controls () {
3
+ global $feedwordpress;
4
+ global $inspectPostMeta;
5
+
6
+ // Put in Manual Editing checkbox
7
+ add_action('add_meta_boxes', 'feedwordpress_post_add_meta_boxes', 10, 2);
8
+
9
+ add_filter('user_can_richedit', array($feedwordpress, 'user_can_richedit'), 1000, 1);
10
+
11
+ if (FeedWordPressDiagnostic::is_on('syndicated_posts:static_meta_data')) :
12
+ $inspectPostMeta = new InspectPostMeta;
13
+ endif;
14
+ } // function feedwordpress_add_post_edit_controls ()
15
+
16
+ function feedwordpress_post_add_meta_boxes ($post_type, $post) {
17
+ add_meta_box(
18
+ 'feedwordpress-post-controls',
19
+ __('Syndication'),
20
+ 'feedwordpress_post_edit_controls',
21
+ $post_type,
22
+ 'side',
23
+ 'high'
24
+ );
25
+ }
26
+
27
+ function feedwordpress_post_edit_controls () {
28
+ global $post;
29
+
30
+ $frozen_values = get_post_custom_values('_syndication_freeze_updates', $post->ID);
31
+ $frozen_post = ($frozen_values !== null and count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
32
+
33
+ if (is_syndicated($post->ID)) :
34
+ ?>
35
+ <p>This is a syndicated post, which originally appeared at
36
+ <cite><?php print esc_html(get_syndication_source(NULL, $post->ID)); ?></cite>.
37
+ <a href="<?php print esc_html(get_syndication_permalink($post->ID)); ?>">View original post</a>.</p>
38
+
39
+ <?php do_action('feedwordpress_post_edit_controls_pre', $post); ?>
40
+
41
+ <p><input type="hidden" name="feedwordpress_noncename" id="feedwordpress_noncename" value="<?php print wp_create_nonce(plugin_basename(__FILE__)); ?>" />
42
+ <label><input type="checkbox" name="freeze_updates" value="yes" <?php if ($frozen_post) : ?>checked="checked"<?php endif; ?> /> <strong>Manual editing.</strong>
43
+ If set, FeedWordPress will not overwrite the changes you make manually
44
+ to this post, if the syndicated content is updated on the
45
+ feed.</label></p>
46
+
47
+ <?php do_action('feedwordpress_post_edit_controls', $post); ?>
48
+
49
+ <?php
50
+ else :
51
+ ?>
52
+ <p>This post was created locally at this website.</p>
53
+ <?php
54
+ endif;
55
+ } /* function feedwordpress_post_edit_controls () */
56
+
57
+ function feedwordpress_save_post_edit_controls ( $post_id ) {
58
+ global $post;
59
+ if (!isset($_POST['feedwordpress_noncename']) or !wp_verify_nonce($_POST['feedwordpress_noncename'], plugin_basename(__FILE__))) :
60
+ return $post_id;
61
+ endif;
62
+
63
+ // Verify if this is an auto save routine. If it is our form has
64
+ // not been submitted, so we don't want to do anything.
65
+ if ( defined('DOING_AUTOSAVE') and DOING_AUTOSAVE ) :
66
+ return $post_id;
67
+ endif;
68
+
69
+ // The data in $_POST is for applying only to the post actually
70
+ // in the edit window, i.e. $post
71
+ if ($post_id != $post->ID) :
72
+ return $post_id;
73
+ endif;
74
+
75
+ // Check permissions
76
+ $cap[0] = 'edit_post';
77
+ $cap[1] = 'edit_' . $_POST['post_type'];
78
+ if (
79
+ !current_user_can( $cap[0], $post_id )
80
+ and !current_user_can( $cap[1], $post_id )
81
+ ) :
82
+ return $post_id;
83
+ endif;
84
+
85
+ // OK, we're golden. Now let's save some data.
86
+ if (isset($_POST['freeze_updates'])) :
87
+
88
+ update_post_meta($post_id, '_syndication_freeze_updates', $_POST['freeze_updates']);
89
+ $ret = $_POST['freeze_updates'];
90
+
91
+ // If you make manual edits through the WordPress editing
92
+ // UI then they should be run through normal WP formatting
93
+ // filters.
94
+ update_post_meta($post_id, '_feedwordpress_formatting_filters', 'yes');
95
+
96
+ else :
97
+ delete_post_meta($post_id, '_syndication_freeze_updates');
98
+ $ret = NULL;
99
+ endif;
100
+
101
+ do_action('feedwordpress_save_edit_controls', $post_id);
102
+
103
+ return $ret;
104
+ } // function feedwordpress_save_edit_controls
feedwordpressboilerplatereformatter.class.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * class FeedWordPressBoilerplateReformatter: processes shortcodes in Boilerplate / Credits
4
+ * settings text from Syndication > Posts & Links > Boilerplate / Credits
5
+ *
6
+ * @author C. Johnson <development@fwpplugin.com>
7
+ *
8
+ * @see feedwordpressboilerplatereformatter.shortcode.functions.php
9
+ *
10
+ * @version 2020.0120
11
+ */
12
+
13
+ class FeedWordPressBoilerplateReformatter {
14
+ var $id, $element;
15
+
16
+ public function __construct ($id = NULL, $element = 'post') {
17
+ $this->id = $id;
18
+ $this->element = $element;
19
+ }
20
+
21
+ function shortcode_methods () {
22
+ return array(
23
+ 'source' => 'source_link',
24
+ 'source-name' => 'source_name',
25
+ 'source-url' => 'source_url',
26
+ 'original-link' => 'original_link',
27
+ 'original-url' => 'original_url',
28
+ 'author' => 'source_author_link',
29
+ 'author-name' => 'source_author',
30
+ 'feed-setting' => 'source_setting',
31
+ );
32
+ }
33
+ function do_shortcode ($template) {
34
+ $codes = $this->shortcode_methods();
35
+
36
+ // Register shortcodes relative to this object/post ID/element.
37
+ foreach ($codes as $code => $method) :
38
+ add_shortcode($code, array($this, $method));
39
+ endforeach;
40
+
41
+ $template = do_shortcode($template);
42
+
43
+ // Unregister shortcodes.
44
+ foreach ($codes as $code => $method) :
45
+ remove_shortcode($code);
46
+ endforeach;
47
+
48
+ return $template;
49
+ }
50
+
51
+ function source_name ($atts) {
52
+ $param = shortcode_atts(array(
53
+ 'original' => NULL,
54
+ ), $atts);
55
+ return get_syndication_source($param['original'], $this->id);
56
+ }
57
+ function source_url ($atts) {
58
+ $param = shortcode_atts(array(
59
+ 'original' => NULL,
60
+ ), $atts);
61
+ return get_syndication_source_link($param['original'], $this->id);
62
+ }
63
+ function source_link ($atts) {
64
+ switch (strtolower($atts[0])) :
65
+ case '-name' :
66
+ $ret = $this->source_name($atts);
67
+ break;
68
+ case '-url' :
69
+ $ret = $this->source_url($atts);
70
+ break;
71
+ default :
72
+ $param = shortcode_atts(array(
73
+ 'original' => NULL,
74
+ ), $atts);
75
+ if ('title' == $this->element) :
76
+ $ret = $this->source_name($atts);
77
+ else :
78
+ $ret = '<a href="'.htmlspecialchars($this->source_url($atts)).'">'.htmlspecialchars($this->source_name($atts)).'</a>';
79
+ endif;
80
+ endswitch;
81
+ return $ret;
82
+ }
83
+ function source_setting ($atts) {
84
+ $param = shortcode_atts(array(
85
+ 'key' => NULL,
86
+ ), $atts);
87
+ return get_feed_meta($param['key'], $this->id);
88
+ }
89
+ function original_link ($atts, $text) {
90
+ $url = $this->original_url($atts);
91
+ return '<a href="'.esc_url($url).'">'.do_shortcode($text).'</a>';
92
+ }
93
+ function original_url ($atts) {
94
+ return get_syndication_permalink($this->id);
95
+ }
96
+ function source_author ($atts) {
97
+ return get_the_author();
98
+ }
99
+ function source_author_link ($atts) {
100
+ switch (strtolower($atts[0])) :
101
+ case '-name' :
102
+ $ret = $this->source_author($atts);
103
+ break;
104
+ default :
105
+ global $authordata; // Janky.
106
+ if ('title' == $this->element) :
107
+ $ret = $this->source_author($atts);
108
+ else :
109
+ $ret = get_the_author();
110
+ $url = get_author_posts_url((int) $authordata->ID, (int) $authordata->user_nicename);
111
+ if ($url) :
112
+ $ret = '<a href="'.$url.'" '
113
+ .'title="Read other posts by '.esc_html($authordata->display_name).'">'
114
+ .$ret
115
+ .'</a>';
116
+ endif;
117
+ endif;
118
+ endswitch;
119
+ return $ret;
120
+ }
121
+ }
122
+
feedwordpressboilerplatereformatter.shortcode.functions.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * function add_boilerplate_reformat: reformat boilerplate template to fit into post elements; return reformatted text
4
+ *
5
+ * @uses FeedWordPressBoilerplateReformatter
6
+ * @uses FeedWordPressBoilerplateReformatter::do_shortcode()
7
+ *
8
+ * @param string $template The boilerplate template text, mostly in text/html, with any inline [shortcode] elements
9
+ * @param string $element the wp_post element being processed, e.g. 'post' (= post_content), 'excerpt', 'title'
10
+ * @param int|null $id the numeric id of the post to be reformatted, or NULL for the current post in the WP loop
11
+ * @return string The reformatted text, in text/html format.
12
+ */
13
+ function add_boilerplate_reformat ($template, $element, $id = NULL) {
14
+ if ('post' == $element and !preg_match('/< (p|div) ( \s [^>]+ )? >/xi', $template)) :
15
+ $template = '<p class="syndicated-attribution">'.$template.'</p>';
16
+ endif;
17
+
18
+ $ref = new FeedWordPressBoilerplateReformatter($id, $element);
19
+ return $ref->do_shortcode($template);
20
+ } /* add_boilerplate_reformat() */
21
+
22
+ /**
23
+ * function add_boilerplate_simple: look for any relevant Boilerplate / Credits template text to add
24
+ * to elements (post body, excerpt, title...) of a post being displayed in WordPress theme code.
25
+ *
26
+ * @uses is_syndicated()
27
+ * @uses get_feed_meta()
28
+ * @uses get_option()
29
+ * @uses add_boilerplate_reformat()
30
+ *
31
+ * @param string $element indicates the element of the post 'post' (= main body), 'excerpt', or 'title'
32
+ * @param string $title provides the text of the element waiting for boilerplate to be inserted
33
+ * @param int|null $id provides the numeric ID of the post being displayed (null = current post in WP loop)
34
+ * @return string provides the reformatted text, including any boilerplate text that has been inserted
35
+ */
36
+ function add_boilerplate_simple ($element, $title, $id = NULL) {
37
+ if (is_syndicated($id)) :
38
+ $meta = get_feed_meta('boilerplate rules', $id);
39
+ if ($meta and !is_array($meta)) : $meta = unserialize($meta); endif;
40
+
41
+ if (!is_array($meta) or empty($meta)) :
42
+ $meta = get_option('feedwordpress_boilerplate');
43
+ endif;
44
+
45
+ if (is_array($meta) and !empty($meta)) :
46
+ foreach ($meta as $rule) :
47
+ if ($element==$rule['element']) :
48
+ $rule['template'] = add_boilerplate_reformat($rule['template'], $element, $id);
49
+
50
+ if ('before'==$rule['placement']) :
51
+ $title = $rule['template'] . ' ' . $title;
52
+ else :
53
+ $title = $title . ' ' . $rule['template'];
54
+ endif;
55
+ endif;
56
+ endforeach;
57
+ endif;
58
+ endif;
59
+ return $title;
60
+ } /* function add_boilerplate_simple() */
61
+
62
+ /**
63
+ * function add_boilerplate_title: filter hook for the_title to add Boilerplate / Credit text,
64
+ * if any is set, for the title of syndicated posts
65
+ *
66
+ * @uses add_boilerplate_simple()
67
+ *
68
+ * @param string $title contains the text of the title of the post being displayed
69
+ * @param int|null $id provides the numeric ID of the post being displayed (null = current post in WP loop)
70
+ * @return string provides the text of the title, reformatted to include any relevant boilerplate text
71
+ */
72
+ function add_boilerplate_title ($title, $id = NULL) {
73
+ return add_boilerplate_simple('title', $title, $id);
74
+ } /* function add_boilerplate_title () */
75
+
76
+ /**
77
+ * function add_boilerplate_excerpt: filter hook for the_excerpt to add Boilerplate / Credit text,
78
+ * if any is set, for the excerpt of syndicated posts
79
+ *
80
+ * @uses add_boilerplate_simple()
81
+ *
82
+ * @param string $excerpt contains the text of the excerpt of the post being displayed
83
+ * @param int|null $id provides the numeric ID of the post being displayed (null = current post in WP loop)
84
+ * @return string provides the text of the excerpt, reformatted to include any relevant boilerplate text
85
+ */
86
+ function add_boilerplate_excerpt ($title, $id = NULL) {
87
+ return add_boilerplate_simple('excerpt', $title, $id);
88
+ } /* function add_boilerplate_excerpt () */
89
+
90
+ /**
91
+ * function add_boilerplate_content: filter hook for the_content to add Boilerplate / Credit text,
92
+ * if any is set, for the excerpt of syndicated posts
93
+ *
94
+ * @uses is_syndicated()
95
+ * @uses get_feed_meta()
96
+ * @uses get_option()
97
+ * @uses add_boilerplate_reformat()
98
+ *
99
+ * @param string $content contains the text content of the post being displayed
100
+ * @return string provides the text content, reformatted to include any relevant boilerplate text
101
+ */
102
+ function add_boilerplate_content ($content) {
103
+ if (is_syndicated()) :
104
+ $meta = get_feed_meta('boilerplate rules');
105
+ if ($meta and !is_array($meta)) : $meta = unserialize($meta); endif;
106
+
107
+ if (!is_array($meta) or empty($meta)) :
108
+ $meta = get_option('feedwordpress_boilerplate');
109
+ endif;
110
+
111
+ if (is_array($meta) and !empty($meta)) :
112
+ foreach ($meta as $rule) :
113
+ if ('post'==$rule['element']) :
114
+ $rule['template'] = add_boilerplate_reformat($rule['template'], 'post');
115
+
116
+ if ('before'==$rule['placement']) :
117
+ $content = $rule['template'] . "\n" . $content;
118
+ else :
119
+ $content = $content . "\n" . $rule['template'];
120
+ endif;
121
+ endif;
122
+ endforeach;
123
+ endif;
124
+ endif;
125
+ return $content;
126
+ } /* add_boilerplate_content () */
performance-page.php CHANGED
@@ -62,6 +62,8 @@ class FeedWordPressPerformancePage extends FeedWordPressAdminPage {
62
  } /* FeedWordPressPerformancePage::display () */
63
 
64
  function accept_POST ($post) {
 
 
65
  if (isset($post['create_index'])) :
66
  FeedWordPress::create_guid_index();
67
  $this->updated = __('guid column index created on database table.');
@@ -72,7 +74,7 @@ class FeedWordPressPerformancePage extends FeedWordPressAdminPage {
72
  endif;
73
 
74
  if (isset($post['clear_cache'])) :
75
- $N = FeedWordPress::clear_cache();
76
  $feeds = (($N == 1) ? __("feed") : __("feeds"));
77
  $this->updated = sprintf(__("Cleared %d cached %s from WordPress database."), $N, $feeds);
78
  endif;
62
  } /* FeedWordPressPerformancePage::display () */
63
 
64
  function accept_POST ($post) {
65
+ global $feedwordpress;
66
+
67
  if (isset($post['create_index'])) :
68
  FeedWordPress::create_guid_index();
69
  $this->updated = __('guid column index created on database table.');
74
  endif;
75
 
76
  if (isset($post['clear_cache'])) :
77
+ $N = $feedwordpress->clear_cache();
78
  $feeds = (($N == 1) ? __("feed") : __("feeds"));
79
  $this->updated = sprintf(__("Cleared %d cached %s from WordPress database."), $N, $feeds);
80
  endif;
posts-page.php CHANGED
@@ -525,7 +525,9 @@ class FeedWordPressPostsPage extends FeedWordPressAdminPage {
525
 
526
  public function boilerplate_box ($page, $box = NULL) {
527
  if ($page->for_feed_settings()) :
528
- $attrib = unserialize($page->link->settings['boilerplate rules']);
 
 
529
  $syndicatedPosts = 'this feed\'s posts';
530
  else :
531
  $attrib = get_option('feedwordpress_boilerplate');
525
 
526
  public function boilerplate_box ($page, $box = NULL) {
527
  if ($page->for_feed_settings()) :
528
+ $attrib = isset($page->link->settings['boilerplate rules'])
529
+ ? unserialize($page->link->settings['boilerplate rules'])
530
+ : [];
531
  $syndicatedPosts = 'this feed\'s posts';
532
  else :
533
  $attrib = get_option('feedwordpress_boilerplate');
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: C. Johnson
3
  Donate link: http://feedwordpress.radgeek.com/donate/
4
  Tags: syndication, aggregation, feed, atom, rss
5
  Requires at least: 4.5
6
- Tested up to: 5.3.2
7
- Stable tag: 2020.0118
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -65,6 +65,26 @@ FeedWordPress has many options which can be accessed through the WordPress Dashb
65
 
66
  == Changelog ==
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  = 2017.1020 =
69
 
70
  * ADD BOILERPLATE / CREDITS FEATURE AVAILABLE IN POSTS & LINKS SETTINGS PANEL. I have added a new settings panel to the off-the-shelf features of FeedWordPress, under Syndication > Posts & Links (or under the Posts settings page for any individual feed), which allows you to define boilerplate text that should appear in connection with every syndicated post, or with every post syndicated from a particular feed. So, for example, if you want each syndicated post to include a byline reading "This is a syndicated post, reprinted from (LINK TO ORIGINAL SOURCE WEBSITE).", you could set up this byline from within the FeedWordPress settings interface, by going to the Boilerplate / Credits panel, and adding a line to appear BEFORE the CONTENT of each syndicated post, using the text and shortcode "This is a syndicated post, reprinted from [source]." For those of you who have corresponded with me about this feature before, you may be familiar with it from the long-standing "experimental" add-on, FWP+: Add Attribution; I've decided that it's been enough years, and I've had enough requests, that the Add Attribution feature may as well be included in the main FeedWordPress code.
3
  Donate link: http://feedwordpress.radgeek.com/donate/
4
  Tags: syndication, aggregation, feed, atom, rss
5
  Requires at least: 4.5
6
+ Tested up to: 5.5
7
+ Stable tag: 2020.0818
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
65
 
66
  == Changelog ==
67
 
68
+ = 2020.0818 =
69
+
70
+ * WORDPRESS 5.5 COMPATIBILITY FIXES, RESOLVES WARNING NOTICES OR WP-ADMIN LOCKOUT. WordPress 5.5 incorporated a newer release of SimplePie, version 1.5.5, which is pretty rad, but FeedWordPress classes that relied on SimplePie 1.3.1's method signatures would then produce PHP warning notices. That should be pretty innocuous, but depending on web server configurations, some users could get locked out of their own wp-admin interface by the display of error notices in the browser at inopportune times. In any case, I have
71
+
72
+ * PHP 7.4 COMPATIBILITY FIX: Magic quotes were deprecated and then removed back in PHP 5.x, and in PHP 7.4 the vestigial `get_magic_quotes_gpc()` function has been deprecated. We don't need to worry about it anymore for versions of PHP still supported by WordPress. The reference to the function in the MyPHP utility class caused PHP warnings in more recent versions of PHP; so it has now been removed.
73
+
74
+ * DIVERS BUG FIXES AND PHP WARNING NOTICES RESOLVED, thanks to @oppiansteve's fixes and pull requests. (Thanks!)
75
+
76
+ * JQUERY COMPATIBILITY FIXES, RESOLVES MYSTERIOUS VANISHING FEED SELECTOR IN WP-ADMIN. An upgrade to WordPress's packaged jQuery caused the drop-down box for feed settings (in Syndication > Feeds & Updates, Syndication > Posts & Links, etc.) to vanish shortly after pageload. That was awkward, so I disabled the now-incompatible interface chrome that was causing it to vanish.
77
+
78
+ = 2020.0118 =
79
+
80
+ * WORDPRESS COMPATIBILITY TESTING. It's been some time since a public release of FeedWordPress; so I have tested the plugin functionality with recent versions of WordPress and incorporated a number of PHP 7-compatibility related tweaks.
81
+
82
+ * FEED PARSING FAULT TOLERANCE. If FeedWordPress fails to parse a feed using normal XML functions, it will attempt to convert any named entities that may be causing a problem, and then try to parse again. Props to @inanimatt for utility functions that help make the code go.
83
+
84
+ * PAUSING UPDATES. In Syndication > Feeds & Updates, you can now instruct FeedWordPress to temporarily pause or resume updating feeds -- whatever update method you are using, you can put new updates on hold for a while so that you can fiddle with setings, run tests, or do whatever you need to do before allowing updates to resume.
85
+
86
+ * CODE MODERNIZATION, PHP 7.x COMPATIBILITY AND CLEANUP AND REORGANIZATION. I have been dusting out nooks and crannies in the code and hiving more functionality off into discrete modules. A number of FeedWordPress users have also offered pull requests to eliminate bothersome PHP notices and warnings related to PHP 7.x compatibility -- in particular removing uses of deprecated `each()` functions, and avoiding use of `count()` on null values -- which I have rolled into the main branch release. Props to @manzoorwanijk, @tristanleboss, @martinburchell and @oppiansteve
87
+
88
  = 2017.1020 =
89
 
90
  * ADD BOILERPLATE / CREDITS FEATURE AVAILABLE IN POSTS & LINKS SETTINGS PANEL. I have added a new settings panel to the off-the-shelf features of FeedWordPress, under Syndication > Posts & Links (or under the Posts settings page for any individual feed), which allows you to define boilerplate text that should appear in connection with every syndicated post, or with every post syndicated from a particular feed. So, for example, if you want each syndicated post to include a byline reading "This is a syndicated post, reprinted from (LINK TO ORIGINAL SOURCE WEBSITE).", you could set up this byline from within the FeedWordPress settings interface, by going to the Boilerplate / Credits panel, and adding a line to appear BEFORE the CONTENT of each syndicated post, using the text and shortcode "This is a syndicated post, reprinted from [source]." For those of you who have corresponded with me about this feature before, you may be familiar with it from the long-standing "experimental" add-on, FWP+: Add Attribution; I've decided that it's been enough years, and I've had enough requests, that the Add Attribution feature may as well be included in the main FeedWordPress code.
syndicatedlink.class.php CHANGED
@@ -175,7 +175,7 @@ class SyndicatedLink {
175
  $ttl = $this->automatic_ttl();
176
  $ttl = apply_filters('syndicated_feed_ttl', $ttl, $this);
177
  $ttl = apply_filters('syndicated_feed_ttl_from_error', $ttl, $this);
178
- $this->update_setting('update/ttl', $ttl, $this);
179
  $this->update_setting('update/timed', 'automatically');
180
  endif;
181
 
@@ -189,7 +189,7 @@ class SyndicatedLink {
189
  // Success; clear out error setting, if any.
190
  $this->update_setting('update/error', NULL);
191
 
192
- $new_count = array('new' => 0, 'updated' => 0);
193
 
194
  # -- Update Link metadata live from feed
195
  $channel = $this->magpie->channel;
@@ -220,24 +220,7 @@ class SyndicatedLink {
220
  $this->merge_settings($channel, 'feed/');
221
 
222
  $this->update_setting('update/last', time());
223
- list($ttl, $xml) = $this->ttl(/*return element=*/ true);
224
-
225
- if (!is_null($ttl)) :
226
- $this->update_setting('update/ttl', $ttl);
227
- $this->update_setting('update/xml', $xml);
228
- $this->update_setting('update/timed', 'feed');
229
- else :
230
- $ttl = $this->automatic_ttl();
231
- $this->update_setting('update/ttl', $ttl);
232
- $this->update_setting('update/xml', NULL);
233
- $this->update_setting('update/timed', 'automatically');
234
- endif;
235
- $this->update_setting('update/fudge', rand(0, ($ttl/3))*60);
236
- $this->update_setting('update/ttl', apply_filters(
237
- 'syndicated_feed_ttl',
238
- $this->setting('update/ttl'),
239
- $this
240
- ));
241
 
242
  if (!$this->setting('update/hold') != 'ping') :
243
  $this->update_setting('update/hold', 'scheduled');
@@ -371,6 +354,30 @@ class SyndicatedLink {
371
  return $new_count;
372
  } /* SyndicatedLink::poll() */
373
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
  public function process_retirements ($delta) {
375
  global $post;
376
 
@@ -1018,7 +1025,7 @@ class SyndicatedLink {
1018
  // channel format is updated. Acceptable values are:
1019
  // hourly, daily, weekly, monthly, yearly. If omitted,
1020
  // daily is assumed." <http://web.resource.org/rss/1.0/modules/syndication/>
1021
- if (isset($channel['sy']['updateperiod'])) : $period = $channel['sy']['updateperiod'];
1022
  else : $period = 'daily';
1023
  endif;
1024
 
@@ -1031,8 +1038,16 @@ class SyndicatedLink {
1031
  else : $freq = 1;
1032
  endif;
1033
 
 
 
 
 
 
 
 
1034
  $xml = 'sy:updateFrequency';
1035
- $ret = (int) ($period_minutes[$period] / $freq);
 
1036
  else :
1037
  $xml = NULL;
1038
  $ret = NULL;
175
  $ttl = $this->automatic_ttl();
176
  $ttl = apply_filters('syndicated_feed_ttl', $ttl, $this);
177
  $ttl = apply_filters('syndicated_feed_ttl_from_error', $ttl, $this);
178
+ $this->update_setting('update/ttl', $ttl);
179
  $this->update_setting('update/timed', 'automatically');
180
  endif;
181
 
189
  // Success; clear out error setting, if any.
190
  $this->update_setting('update/error', NULL);
191
 
192
+ $new_count = array('new' => 0, 'updated' => 0, 'stored' => 0);
193
 
194
  # -- Update Link metadata live from feed
195
  $channel = $this->magpie->channel;
220
  $this->merge_settings($channel, 'feed/');
221
 
222
  $this->update_setting('update/last', time());
223
+ $this->do_update_ttl();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
225
  if (!$this->setting('update/hold') != 'ping') :
226
  $this->update_setting('update/hold', 'scheduled');
354
  return $new_count;
355
  } /* SyndicatedLink::poll() */
356
 
357
+ public function do_update_ttl () {
358
+ list($ttl, $xml) = $this->ttl(/*return element=*/ true);
359
+
360
+ if (!is_null($ttl)) :
361
+ $this->update_setting('update/ttl', $ttl);
362
+ $this->update_setting('update/xml', $xml);
363
+ $this->update_setting('update/timed', 'feed');
364
+ else :
365
+ $ttl = $this->automatic_ttl();
366
+ $this->update_setting('update/ttl', $ttl);
367
+ $this->update_setting('update/xml', NULL);
368
+ $this->update_setting('update/timed', 'automatically');
369
+ endif;
370
+
371
+ $this->update_setting('update/fudge', rand(0, ($ttl/3))*60);
372
+
373
+ $this->update_setting('update/ttl', apply_filters(
374
+ 'syndicated_feed_ttl',
375
+ $this->setting('update/ttl'),
376
+ $this
377
+ ));
378
+
379
+ } /* SyndicatedLink::do_update_ttl () */
380
+
381
  public function process_retirements ($delta) {
382
  global $post;
383
 
1025
  // channel format is updated. Acceptable values are:
1026
  // hourly, daily, weekly, monthly, yearly. If omitted,
1027
  // daily is assumed." <http://web.resource.org/rss/1.0/modules/syndication/>
1028
+ if (isset($channel['sy']['updateperiod'])) : $period = trim($channel['sy']['updateperiod']);
1029
  else : $period = 'daily';
1030
  endif;
1031
 
1038
  else : $freq = 1;
1039
  endif;
1040
 
1041
+ // normalize the period name...
1042
+ $period = strtolower(trim($period));
1043
+
1044
+ // do we recognize the alphanumeric period name? if not, then guess
1045
+ // a responsible default, e.g. roughly hourly
1046
+ $mins = (isset($period_minutes[$period]) ? $period_minutes[$period] : 67);
1047
+
1048
  $xml = 'sy:updateFrequency';
1049
+ $ret = (int) ($mins / $freq);
1050
+
1051
  else :
1052
  $xml = NULL;
1053
  $ret = NULL;
syndicatedpost.class.php CHANGED
@@ -163,6 +163,9 @@ class SyndicatedPost {
163
  endforeach;
164
 
165
  foreach ($postMetaOut as $key => $values) :
 
 
 
166
  $this->post['meta'][$key] = array();
167
  foreach ($values as $value) :
168
  $this->post['meta'][$key][] = apply_filters("syndicated_post_meta_{$key}", $value, $this);
@@ -557,7 +560,7 @@ class SyndicatedPost {
557
  endif;
558
 
559
  if (!$unfiltered) :
560
- apply_filters('syndicated_item_updated', $ts, $this);
561
  endif;
562
  return $ts;
563
  } /* SyndicatedPost::updated() */
@@ -705,7 +708,7 @@ class SyndicatedPost {
705
  $author = array ();
706
 
707
  $aa = $this->entry->get_authors();
708
- if (count($aa) > 0) :
709
  $a = reset($aa);
710
 
711
  $author = array(
@@ -903,7 +906,7 @@ class SyndicatedPost {
903
  $content = $this->content();
904
  $pattern = FeedWordPressHTML::tagWithAttributeRegex('a', 'rel', 'tag');
905
  preg_match_all($pattern, $content, $refs, PREG_SET_ORDER);
906
- if (count($refs) > 0) :
907
  foreach ($refs as $ref) :
908
  $tag = FeedWordPressHTML::tagWithAttributeMatch($ref);
909
  $tags[] = $tag['content'];
@@ -1301,7 +1304,7 @@ class SyndicatedPost {
1301
  // Or the hash...
1302
  $hash = $this->update_hash();
1303
  $seen = $this->stored_hashes($old_post->ID);
1304
- if (count($seen) > 0) :
1305
  $updated = !in_array($hash, $seen); // Not seen yet?
1306
  else :
1307
  $updated = true; // Can't find syndication meta-data
163
  endforeach;
164
 
165
  foreach ($postMetaOut as $key => $values) :
166
+ if (is_null($values)) { // have chosen to replace value with empty string
167
+ $values = [''];
168
+ }
169
  $this->post['meta'][$key] = array();
170
  foreach ($values as $value) :
171
  $this->post['meta'][$key][] = apply_filters("syndicated_post_meta_{$key}", $value, $this);
560
  endif;
561
 
562
  if (!$unfiltered) :
563
+ $ts = apply_filters('syndicated_item_updated', $ts, $this);
564
  endif;
565
  return $ts;
566
  } /* SyndicatedPost::updated() */
708
  $author = array ();
709
 
710
  $aa = $this->entry->get_authors();
711
+ if (is_countable($aa) and count($aa) > 0) :
712
  $a = reset($aa);
713
 
714
  $author = array(
906
  $content = $this->content();
907
  $pattern = FeedWordPressHTML::tagWithAttributeRegex('a', 'rel', 'tag');
908
  preg_match_all($pattern, $content, $refs, PREG_SET_ORDER);
909
+ if (is_countable($refs) and count($refs) > 0) :
910
  foreach ($refs as $ref) :
911
  $tag = FeedWordPressHTML::tagWithAttributeMatch($ref);
912
  $tags[] = $tag['content'];
1304
  // Or the hash...
1305
  $hash = $this->update_hash();
1306
  $seen = $this->stored_hashes($old_post->ID);
1307
+ if (is_countable($seen) and count($seen) > 0) :
1308
  $updated = !in_array($hash, $seen); // Not seen yet?
1309
  else :
1310
  $updated = true; // Can't find syndication meta-data
template-functions.php CHANGED
@@ -17,6 +17,17 @@ function is_syndicated ($id = NULL) {
17
  return $p->is_syndicated();
18
  } /* function is_syndicated() */
19
 
 
 
 
 
 
 
 
 
 
 
 
20
  function feedwordpress_display_url ($url, $before = 60, $after = 0) {
21
  $bits = parse_url($url);
22
 
17
  return $p->is_syndicated();
18
  } /* function is_syndicated() */
19
 
20
+ /**
21
+ * feedwordpress_display_url: format a fully-formed URL for display in the
22
+ * FeedWordPress admin interface, abbreviating it (e.g.: input of
23
+ * `http://feedwordpress.radgeek.com/feed/` will be shortened to
24
+ * `feedwordpress.radgeek.com/feed/`)
25
+ *
26
+ * @param string $url provides the URL to display
27
+ * @param int $before a number of characters to preserve from the beginning of the URL if it must be shortened
28
+ * @param int $after a number of characters to preserve from the end of the URL if it must be shortened
29
+ * @return string containing an abbreviated display form of the URL (e.g.: `feedwordpress.radgeek.net/feed`)
30
+ */
31
  function feedwordpress_display_url ($url, $before = 60, $after = 0) {
32
  $bits = parse_url($url);
33