WP RSS Aggregator - Version 4.8.2

Version Description

(2016-02-22) = * Fixed bug: Interface methods used to conflict, causing fatal error on activation. * Fixed bug: Empty feed response used to cause misleading error message in log. * Enhanced: Users can now override useragent sent with feed requests. * Enhanced: Improvements to plugin updating system. * Enhanced: Readme updated. * Enhanced: "Open link behaviour" option's internal handling has been improved.

Download this release

Release Info

Developer jeangalea
Plugin Icon 128x128 WP RSS Aggregator
Version 4.8.2
Comparing to
See all releases

Code changes from version 4.8.1 to 4.8.2

includes/Aventura/Wprss/Core/Plugin/PluginAbstract.php CHANGED
@@ -188,7 +188,7 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
188
  /**
189
  * Translates some text.
190
  *
191
- * @since [*next-version*]s
192
  * @param string $text The text to translate.
193
  * @param string|null The text domain to use for translation.
194
  * Defaults to this plugin's text domain.
188
  /**
189
  * Translates some text.
190
  *
191
+ * @since 4.8.1
192
  * @param string $text The text to translate.
193
  * @param string|null The text domain to use for translation.
194
  * Defaults to this plugin's text domain.
includes/Aventura/Wprss/Core/Plugin/PluginInterface.php CHANGED
@@ -130,9 +130,13 @@ interface PluginInterface
130
  * The event prefix is by default the plugin code followed by an underscore "_", unless the code is
131
  * not set, in which case the prefix is empty.
132
  *
 
 
 
 
133
  * @since 4.8.1
134
  * @param string|null $name An event name to prefix.
135
  * @return string This instance's event prefix, or a prefixed name.
136
  */
137
- public function getEventPrefix($name = null);
138
  }
130
  * The event prefix is by default the plugin code followed by an underscore "_", unless the code is
131
  * not set, in which case the prefix is empty.
132
  *
133
+ * Note: this method had to be commented out due to a conflict with `Aventura\Wprss\Core\Model\ModelInterface#getEventPrefix()`.
134
+ * This conflicting behaviour can be observed when using PHP version less than 5.3.9.
135
+ *
136
+ * @todo Uncomment when minimum PHP version requirement is raised above 5.3.9
137
  * @since 4.8.1
138
  * @param string|null $name An event name to prefix.
139
  * @return string This instance's event prefix, or a prefixed name.
140
  */
141
+ // public function getEventPrefix($name = null);
142
  }
includes/admin-ajax-notice.php CHANGED
@@ -959,7 +959,7 @@ class WPRSS_Admin_Notices {
959
  /**
960
  * Normalize a single notice's data that was returned from the database.
961
  *
962
- * @since[*next-version*]
963
  * @uses-filter admin_notice_normalize_notice_data_from_db To modify the return value.
964
  * @param null|mixed|array $data The individual notice's data to normalize.
965
  * @return array The notice data returned from the database.
@@ -981,7 +981,7 @@ class WPRSS_Admin_Notices {
981
  * Is responsible for preserving only allowed fields, and adding some
982
  * required ones, if necessary and possible.
983
  *
984
- * @since[*next-version*]
985
  * @uses-filter admin_notice_prepare_notice_data_for_db To modify the resulting prepared data.
986
  * @param array $data The data to prepare.
987
  * @return array The data that should be saved to the database.
959
  /**
960
  * Normalize a single notice's data that was returned from the database.
961
  *
962
+ * @since4.8.2
963
  * @uses-filter admin_notice_normalize_notice_data_from_db To modify the return value.
964
  * @param null|mixed|array $data The individual notice's data to normalize.
965
  * @return array The notice data returned from the database.
981
  * Is responsible for preserving only allowed fields, and adding some
982
  * required ones, if necessary and possible.
983
  *
984
+ * @since4.8.2
985
  * @uses-filter admin_notice_prepare_notice_data_for_db To modify the resulting prepared data.
986
  * @param array $data The data to prepare.
987
  * @return array The data that should be saved to the database.
includes/admin-help-settings.php CHANGED
@@ -131,7 +131,16 @@ function wprss_settings_add_tooltips() {
131
 
132
  '. 'Relative path will be relative to the WordPress root.
133
 
134
- '. '<strong>Default:</strong> path to certificate file bundled with WordPress.', WPRSS_TEXT_DOMAIN )
 
 
 
 
 
 
 
 
 
135
 
136
  );
137
  $help->add_tooltips( $tooltips, $prefix );
131
 
132
  '. 'Relative path will be relative to the WordPress root.
133
 
134
+ '. '<strong>Default:</strong> path to certificate file bundled with WordPress.', WPRSS_TEXT_DOMAIN ),
135
+
136
+ /** @since 4.8.2 */
137
+ 'feed_request_useragent' => __( 'The string to be used as the useragent for feed requests.
138
+
139
+ '. 'If non-empty, this exact string will be sent with every request made by WP RSS Aggregator for a feed source XML document.
140
+
141
+ '. 'Some servers react in unexpected ways to the default value. In such cases, try changing this to something else.
142
+
143
+ '. 'The default value is determined by the SimplePie library, and reflects its name, version and build numbers, and some other information.'),
144
 
145
  );
146
  $help->add_tooltips( $tooltips, $prefix );
includes/admin-metaboxes.php CHANGED
@@ -45,7 +45,7 @@
45
  if ( !defined('WPRSS_FTP_VERSION') && !defined('WPRSS_ET_VERSION') && !defined('WPRSS_C_VERSION') ) {
46
  add_meta_box(
47
  'wprss-like-meta',
48
- __( 'Like This Plugin?', WPRSS_TEXT_DOMAIN ),
49
  'wprss_like_meta_box_callback',
50
  'wprss_feed',
51
  'side',
@@ -630,25 +630,23 @@
630
  * @since 2.0
631
  *
632
  */
633
- function wprss_like_meta_box_callback() { ?>
634
-
 
635
  <ul>
636
- <li><a href="http://wordpress.org/extend/plugins/wp-rss-aggregator/"><?php _e( 'Give it a 5 star rating on WordPress.org', WPRSS_TEXT_DOMAIN ) ?></a></li>
637
- <li class="donate_link"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=X9GP6BL4BLXBJ"><?php _e( 'Donate a token of your appreciation', WPRSS_TEXT_DOMAIN ); ?></a></li>
638
  </ul>
639
- <?php
640
- echo '<p><strong>';
641
- _e( 'Check out the Premium Extensions:', WPRSS_TEXT_DOMAIN );
642
- echo '</strong>'; ?>
643
- <ul>
644
- <li><a href="http://www.wprssaggregator.com/extension/widget/"><?php echo 'Widget'; ?></a></li>
645
- <li><a href="http://www.wprssaggregator.com/extension/feed-to-post/"><?php echo 'Feed to Post'; ?></a></li>
646
- <li><a href="http://www.wprssaggregator.com/extension/excerpts-thumbnails/"><?php echo 'Excerpts & Thumbnails'; ?></a></li>
647
- <li><a href="http://www.wprssaggregator.com/extension/categories/"><?php echo 'Categories'; ?></a></li>
648
- <li><a href="http://www.wprssaggregator.com/extension/keyword-filtering/"><?php echo 'Keyword Filtering'; ?></a></li>
649
  </ul>
650
- </p>
651
- <?php }
 
652
 
653
 
654
  /**
45
  if ( !defined('WPRSS_FTP_VERSION') && !defined('WPRSS_ET_VERSION') && !defined('WPRSS_C_VERSION') ) {
46
  add_meta_box(
47
  'wprss-like-meta',
48
+ __( 'Share The Love', WPRSS_TEXT_DOMAIN ),
49
  'wprss_like_meta_box_callback',
50
  'wprss_feed',
51
  'side',
630
  * @since 2.0
631
  *
632
  */
633
+ function wprss_like_meta_box_callback()
634
+ {
635
+ ?>
636
  <ul>
637
+ <li><a href="https://wordpress.org/support/view/plugin-reviews/wp-rss-aggregator?rate=5#postform" target="_blank"><?php _e( 'Give it a 5 star rating on WordPress.org', WPRSS_TEXT_DOMAIN ) ?></a></li>
 
638
  </ul>
639
+ <p><strong><?php _e( 'Add functionality with our premium extensions:', WPRSS_TEXT_DOMAIN ) ?></strong></p>
640
+ <?php $addons = wprss_addons_get_extra() ?>
641
+ <?php if (count($addons)): ?>
642
+ <ul class="add-on-list">
643
+ <?php foreach ($addons as $_code => $_addon): ?>
644
+ <li class="add-on <?php echo sprintf('add-on-code-%1$s', $_code) ?>"><a href="<?php echo $_addon['url'] ?>"><?php echo $_addon['title'] ?></a></li>
645
+ <?php endforeach ?>
 
 
 
646
  </ul>
647
+ <?php endif ?>
648
+ <?php
649
+ }
650
 
651
 
652
  /**
includes/feed-access.php CHANGED
@@ -13,6 +13,7 @@ class WPRSS_Feed_Access {
13
  protected $_certificate_file_path;
14
 
15
  const SETTING_KEY_CERTIFICATE_PATH = 'certificate-path';
 
16
 
17
  /**
18
  * @since 4.7
@@ -91,6 +92,34 @@ class WPRSS_Feed_Access {
91
 
92
  return $path;
93
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
 
96
  /**
@@ -103,6 +132,7 @@ class WPRSS_Feed_Access {
103
  */
104
  public function set_feed_options( $feed ) {
105
  $feed->set_file_class( 'WPRSS_SimplePie_File' );
 
106
  WPRSS_SimplePie_File::set_default_certificate_file_path( $this->get_certificate_file_path() );
107
  }
108
 
@@ -119,6 +149,11 @@ class WPRSS_Feed_Access {
119
  'label' => __( 'Certificate Path', WPRSS_TEXT_DOMAIN ),
120
  'callback' => array( $this, 'render_certificate_path_setting' )
121
  );
 
 
 
 
 
122
 
123
  return $settings;
124
  }
@@ -131,6 +166,8 @@ class WPRSS_Feed_Access {
131
  */
132
  public function add_default_settings( $settings ) {
133
  $settings[ self::SETTING_KEY_CERTIFICATE_PATH ] = implode( '/', array( WPINC, 'certificates', 'ca-bundle.crt' ) );
 
 
134
 
135
  return $settings;
136
  }
@@ -149,6 +186,21 @@ class WPRSS_Feed_Access {
149
  <input id="<?php echo $field['field_id'] ?>" name="wprss_settings_general[<?php echo $field['field_id'] ?>]" type="text" value="<?php echo $feed_limit ?>" />
150
  <?php echo wprss_settings_inline_help( $field['field_id'], $field['tooltip'] );
151
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  }
153
 
154
  // Initialize
@@ -236,6 +288,8 @@ class WPRSS_SimplePie_File extends SimplePie_File {
236
  $location = SimplePie_Misc::absolutize_url( $this->headers['location'], $url );
237
  return $this->__construct( $location, $timeout, $redirects, $headers, $useragent, $force_fsockopen );
238
  }
 
 
239
  }
240
  }
241
  } else {
@@ -405,4 +459,31 @@ class WPRSS_SimplePie_File extends SimplePie_File {
405
  self::$_default_certificate_file_path = $path;
406
  }
407
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
408
  }
13
  protected $_certificate_file_path;
14
 
15
  const SETTING_KEY_CERTIFICATE_PATH = 'certificate-path';
16
+ const SETTING_KEY_FEED_REQUEST_USERAGENT = 'feed_request_useragent';
17
 
18
  /**
19
  * @since 4.7
92
 
93
  return $path;
94
  }
95
+
96
+ /**
97
+ * Return the value of the useragent setting.
98
+ *
99
+ * The setting key is determined by the SETTING_KEY_FEED_REQUEST_USERAGENT class constant.
100
+ *
101
+ * @since 4.8.2
102
+ * @return string The value of the useragent setting.
103
+ */
104
+ public function get_useragent_setting()
105
+ {
106
+ return wprss_get_general_setting( self::SETTING_KEY_FEED_REQUEST_USERAGENT );
107
+ }
108
+
109
+ /**
110
+ * Get the useragent string that will be sent with feed requests.
111
+ *
112
+ * @since 4.8.2
113
+ * @return string The useragent string that will be sent together with feed requests.
114
+ * If empty, the value of SIMPLEPIE_USERAGENT will be used.
115
+ */
116
+ public function get_useragent()
117
+ {
118
+ $useragent = $this->get_useragent_setting();
119
+ return !strlen(trim($useragent))
120
+ ? SIMPLEPIE_USERAGENT
121
+ : $useragent;
122
+ }
123
 
124
 
125
  /**
132
  */
133
  public function set_feed_options( $feed ) {
134
  $feed->set_file_class( 'WPRSS_SimplePie_File' );
135
+ $feed->set_useragent($this->get_useragent());
136
  WPRSS_SimplePie_File::set_default_certificate_file_path( $this->get_certificate_file_path() );
137
  }
138
 
149
  'label' => __( 'Certificate Path', WPRSS_TEXT_DOMAIN ),
150
  'callback' => array( $this, 'render_certificate_path_setting' )
151
  );
152
+ /** @since 4.8.2 */
153
+ $settings['general'][ self::SETTING_KEY_FEED_REQUEST_USERAGENT ] = array(
154
+ 'label' => __( 'Feed Request Useragent', WPRSS_TEXT_DOMAIN ),
155
+ 'callback' => array( $this, 'render_feed_request_useragent_setting' )
156
+ );
157
 
158
  return $settings;
159
  }
166
  */
167
  public function add_default_settings( $settings ) {
168
  $settings[ self::SETTING_KEY_CERTIFICATE_PATH ] = implode( '/', array( WPINC, 'certificates', 'ca-bundle.crt' ) );
169
+ /** @since 4.8.2 */
170
+ $settings[ self::SETTING_KEY_FEED_REQUEST_USERAGENT ] = '';
171
 
172
  return $settings;
173
  }
186
  <input id="<?php echo $field['field_id'] ?>" name="wprss_settings_general[<?php echo $field['field_id'] ?>]" type="text" value="<?php echo $feed_limit ?>" />
187
  <?php echo wprss_settings_inline_help( $field['field_id'], $field['tooltip'] );
188
  }
189
+
190
+ /**
191
+ * Renders the setting field for the feed request useragent.
192
+ *
193
+ * @since 4.8.2
194
+ * @see wprss_admin_init
195
+ * @param array $field Data of this field.
196
+ */
197
+ public function render_feed_request_useragent_setting( $field )
198
+ {
199
+ $value = wprss_get_general_setting( $field['field_id'] );
200
+ ?>
201
+ <input id="<?php echo $field['field_id'] ?>" name="wprss_settings_general[<?php echo $field['field_id'] ?>]" type="text" value="<?php echo $value ?>" placeholder="<?php echo __('Default', WPRSS_TEXT_DOMAIN) ?>" />
202
+ <?php echo wprss_settings_inline_help( $field['field_id'], $field['tooltip'] );
203
+ }
204
  }
205
 
206
  // Initialize
288
  $location = SimplePie_Misc::absolutize_url( $this->headers['location'], $url );
289
  return $this->__construct( $location, $timeout, $redirects, $headers, $useragent, $force_fsockopen );
290
  }
291
+
292
+ $this->_afterCurlHeadersParsed($info);
293
  }
294
  }
295
  } else {
459
  self::$_default_certificate_file_path = $path;
460
  }
461
 
462
+ /**
463
+ * Called right after a cURL request returns, and headers are parsed.
464
+ *
465
+ * This method will not be called if a cURL error is encountered.
466
+ *
467
+ * @param $curlInfo Result of a call to {@see curl_getinfo()} on the cURL resource.
468
+ * @since 4.8.2
469
+ */
470
+ protected function _afterCurlHeadersParsed($curlInfo)
471
+ {
472
+ $error = implode("\n", array(
473
+ 'The resource could not be retrieved because of a %1$s error with code %2$d',
474
+ 'Server returned %3$d characters:',
475
+ '%4$s'
476
+ ));
477
+
478
+ $code = $this->status_code;
479
+ $body = $this->body;
480
+ if ($code >= 400 && $code < 500 ) { // Client error
481
+ $this->error = sprintf($error, 'client', $code, strlen($body), $body);
482
+ $this->success = false;
483
+ }
484
+ if ($code >= 500 && $code < 600 ) { // Server error
485
+ $this->error = sprintf($error, 'server', $code, strlen($body), $body);
486
+ $this->success = false;
487
+ }
488
+ }
489
  }
includes/libraries/EDD_licensing/EDD_SL_Plugin_Updater.php CHANGED
@@ -3,335 +3,376 @@
3
  // uncomment this line for testing
4
  //set_site_transient( 'update_plugins', null );
5
 
 
 
 
6
  /**
7
  * Allows plugins to use their own update API.
8
  *
9
  * @author Pippin Williamson
10
- * @version 1.6
11
  */
12
  class EDD_SL_Plugin_Updater {
13
- private $api_url = '';
14
- private $api_data = array();
15
- private $name = '';
16
- private $slug = '';
17
-
18
- /**
19
- * Class constructor.
20
- *
21
- * @uses plugin_basename()
22
- * @uses hook()
23
- *
24
- * @param string $_api_url The URL pointing to the custom API endpoint.
25
- * @param string $_plugin_file Path to the plugin file.
26
- * @param array $_api_data Optional data to send with API calls.
27
- * @return void
28
- */
29
- function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
30
- $this->api_url = trailingslashit( $_api_url );
31
- $this->api_data = $_api_data;
32
- $this->name = plugin_basename( $_plugin_file );
33
- $this->slug = basename( $_plugin_file, '.php' );
34
- $this->version = $_api_data['version'];
35
-
36
- // Set up hooks.
37
- $this->init();
38
- add_action( 'admin_init', array( $this, 'show_changelog' ) );
39
- }
40
-
41
- /**
42
- * Set up WordPress filters to hook into WP's update process.
43
- *
44
- * @uses add_filter()
45
- *
46
- * @return void
47
- */
48
- public function init() {
49
-
50
- add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
51
- add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
52
-
53
- add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );
54
- }
55
 
56
- /**
57
- * Check for Updates at the defined API endpoint and modify the update array.
58
- *
59
- * This function dives into the update API just when WordPress creates its update array,
60
- * then adds a custom API call and injects the custom plugin data retrieved from the API.
61
- * It is reassembled from parts of the native WordPress plugin update code.
62
- * See wp-includes/update.php line 121 for the original wp_update_plugins() function.
63
- *
64
- * @uses api_request()
65
- *
66
- * @param array $_transient_data Update array build by WordPress.
67
- * @return array Modified update array with custom plugin data.
68
- */
69
- function check_update( $_transient_data ) {
70
 
71
- global $pagenow;
 
72
 
73
- if( ! is_object( $_transient_data ) ) {
74
- $_transient_data = new stdClass;
75
- }
76
 
77
- if( 'plugins.php' == $pagenow && is_multisite() ) {
78
- return $_transient_data;
79
- }
 
 
 
 
 
80
 
81
- if ( empty( $_transient_data->response ) || empty( $_transient_data->response[ $this->name ] ) ) {
 
 
 
 
82
 
83
- $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
84
 
85
- if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
- $this->did_check = true;
88
 
89
- if( version_compare( $this->version, $version_info->new_version, '<' ) ) {
 
 
90
 
91
- $_transient_data->response[ $this->name ] = $version_info;
 
 
92
 
93
- }
94
 
95
- $_transient_data->last_checked = time();
96
- $_transient_data->checked[ $this->name ] = $this->version;
97
 
98
- }
99
 
100
- }
101
 
102
- return $_transient_data;
103
- }
104
 
105
- /**
106
- * show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
107
- *
108
- * @param string $file
109
- * @param array $plugin
110
- */
111
- public function show_update_notification( $file, $plugin ) {
112
 
113
- if( ! current_user_can( 'update_plugins' ) ) {
114
- return;
115
- }
116
 
117
- if( ! is_multisite() ) {
118
- return;
119
- }
120
 
121
- if ( $this->name != $file ) {
122
- return;
123
- }
124
 
125
- // Remove our filter on the site transient
126
- remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );
127
 
128
- $update_cache = get_site_transient( 'update_plugins' );
 
 
 
 
 
 
129
 
130
- if ( ! is_object( $update_cache ) || empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
 
 
131
 
132
- $cache_key = md5( 'edd_plugin_' .sanitize_key( $this->name ) . '_version_info' );
133
- $version_info = get_transient( $cache_key );
 
134
 
135
- if( false === $version_info ) {
 
 
136
 
137
- $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
 
138
 
139
- set_transient( $cache_key, $version_info, 3600 );
140
- }
141
 
 
142
 
143
- if( ! is_object( $version_info ) ) {
144
- return;
145
- }
146
 
147
- if( version_compare( $this->version, $version_info->new_version, '<' ) ) {
 
148
 
149
- $update_cache->response[ $this->name ] = $version_info;
150
 
151
- }
152
 
153
- $update_cache->last_checked = time();
154
- $update_cache->checked[ $this->name ] = $this->version;
155
 
156
- set_site_transient( 'update_plugins', $update_cache );
 
 
157
 
158
- } else {
159
 
160
- $version_info = $update_cache->response[ $this->name ];
161
 
162
- }
163
 
164
- // Restore our filter
165
- add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
166
 
167
- if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) {
168
 
169
- // build a plugin list row, with update notification
170
- $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
171
- echo '<tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"><div class="update-message">';
172
 
173
- $changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
174
 
175
- if ( empty( $version_info->download_link ) ) {
176
- printf(
177
- __( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a>.', 'edd' ),
178
- esc_html( $version_info->name ),
179
- esc_url( $changelog_link ),
180
- esc_html( $version_info->new_version )
181
- );
182
- } else {
183
- printf(
184
- __( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a> or <a href="%4$s">update now</a>.', 'edd' ),
185
- esc_html( $version_info->name ),
186
- esc_url( $changelog_link ),
187
- esc_html( $version_info->new_version ),
188
- esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) )
189
- );
190
- }
191
 
192
- echo '</div></td></tr>';
193
- }
194
- }
195
 
 
196
 
197
- /**
198
- * Updates information on the "View version x.x details" page with custom data.
199
- *
200
- * @uses api_request()
201
- *
202
- * @param mixed $_data
203
- * @param string $_action
204
- * @param object $_args
205
- * @return object $_data
206
- */
207
- function plugins_api_filter( $_data, $_action = '', $_args = null ) {
208
 
 
209
 
210
- if ( $_action != 'plugin_information' ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
 
212
- return $_data;
213
 
214
- }
 
 
215
 
216
- if ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) {
217
 
218
- return $_data;
 
 
 
 
 
 
 
 
 
 
219
 
220
- }
221
 
222
- $to_send = array(
223
- 'slug' => $this->slug,
224
- 'is_ssl' => is_ssl(),
225
- 'fields' => array(
226
- 'banners' => false, // These will be supported soon hopefully
227
- 'reviews' => false
228
- )
229
- );
230
 
231
- $api_response = $this->api_request( 'plugin_information', $to_send );
232
 
233
- if ( false !== $api_response ) {
234
- $_data = $api_response;
235
- }
236
 
237
- return $_data;
238
- }
239
 
 
240
 
241
- /**
242
- * Disable SSL verification in order to prevent download update failures
243
- *
244
- * @param array $args
245
- * @param string $url
246
- * @return object $array
247
- */
248
- function http_request_args( $args, $url ) {
249
- // If it is an https request and we are performing a package download, disable ssl verification
250
- if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
251
- $args['sslverify'] = false;
252
- }
253
- return $args;
254
- }
255
 
256
- /**
257
- * Calls the API and, if successfull, returns the object delivered by the API.
258
- *
259
- * @uses get_bloginfo()
260
- * @uses wp_remote_post()
261
- * @uses is_wp_error()
262
- *
263
- * @param string $_action The requested action.
264
- * @param array $_data Parameters for the API action.
265
- * @return false||object
266
- */
267
- private function api_request( $_action, $_data ) {
268
-
269
- global $wp_version;
270
-
271
- $data = array_merge( $this->api_data, $_data );
272
-
273
- if ( $data['slug'] != $this->slug )
274
- return;
275
-
276
- if ( empty( $data['license'] ) )
277
- return;
278
-
279
- if( $this->api_url == home_url() ) {
280
- return false; // Don't allow a plugin to ping itself
281
- }
282
-
283
- $api_params = array(
284
- 'edd_action' => 'get_version',
285
- 'license' => $data['license'],
286
- 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
287
- 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
288
- 'slug' => $data['slug'],
289
- 'author' => $data['author'],
290
- 'url' => home_url()
291
- );
292
 
293
- $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
294
 
295
- if ( ! is_wp_error( $request ) ) {
296
- $request = json_decode( wp_remote_retrieve_body( $request ) );
297
- }
 
 
 
298
 
299
- if ( $request && isset( $request->sections ) ) {
300
- $request->sections = maybe_unserialize( $request->sections );
301
- } else {
302
- $request = false;
303
- }
304
 
305
- return $request;
306
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
 
308
- public function show_changelog() {
309
 
 
310
 
311
- if( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
312
- return;
313
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
 
315
- if( empty( $_REQUEST['plugin'] ) ) {
316
- return;
317
- }
318
-
319
- if( empty( $_REQUEST['slug'] ) ) {
320
- return;
321
- }
322
-
323
- if( ! current_user_can( 'update_plugins' ) ) {
324
- wp_die( __( 'You do not have permission to install plugin updates', 'edd' ), __( 'Error', 'edd' ), array( 'response' => 403 ) );
325
- }
326
-
327
- $response = $this->api_request( 'plugin_latest_version', array( 'slug' => $_REQUEST['slug'] ) );
328
-
329
- if( $response && isset( $response->sections['changelog'] ) ) {
330
- echo '<div style="background:#fff;padding:10px;">' . $response->sections['changelog'] . '</div>';
331
- }
332
-
333
-
334
- exit;
335
- }
336
 
337
  }
3
  // uncomment this line for testing
4
  //set_site_transient( 'update_plugins', null );
5
 
6
+ // Exit if accessed directly
7
+ if ( ! defined( 'ABSPATH' ) ) exit;
8
+
9
  /**
10
  * Allows plugins to use their own update API.
11
  *
12
  * @author Pippin Williamson
13
+ * @version 1.6.3
14
  */
15
  class EDD_SL_Plugin_Updater {
16
+ private $api_url = '';
17
+ private $api_data = array();
18
+ private $name = '';
19
+ private $slug = '';
20
+ private $version = '';
21
+
22
+ /**
23
+ * Class constructor.
24
+ *
25
+ * @uses plugin_basename()
26
+ * @uses hook()
27
+ *
28
+ * @param string $_api_url The URL pointing to the custom API endpoint.
29
+ * @param string $_plugin_file Path to the plugin file.
30
+ * @param array $_api_data Optional data to send with API calls.
31
+ */
32
+ public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
33
+
34
+ global $edd_plugin_data;
35
+
36
+ $this->api_url = trailingslashit( $_api_url );
37
+ $this->api_data = $_api_data;
38
+ $this->name = plugin_basename( $_plugin_file );
39
+ $this->slug = basename( $_plugin_file, '.php' );
40
+ $this->version = $_api_data['version'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ $edd_plugin_data[ $this->slug ] = $this->api_data;
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
+ // Set up hooks.
45
+ $this->init();
46
 
47
+ }
 
 
48
 
49
+ /**
50
+ * Set up WordPress filters to hook into WP's update process.
51
+ *
52
+ * @uses add_filter()
53
+ *
54
+ * @return void
55
+ */
56
+ public function init() {
57
 
58
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
59
+ add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
60
+ remove_action( 'after_plugin_row_' . $this->name, 'wp_plugin_update_row', 10, 2 );
61
+ add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );
62
+ add_action( 'admin_init', array( $this, 'show_changelog' ) );
63
 
64
+ }
65
 
66
+ /**
67
+ * Check for Updates at the defined API endpoint and modify the update array.
68
+ *
69
+ * This function dives into the update API just when WordPress creates its update array,
70
+ * then adds a custom API call and injects the custom plugin data retrieved from the API.
71
+ * It is reassembled from parts of the native WordPress plugin update code.
72
+ * See wp-includes/update.php line 121 for the original wp_update_plugins() function.
73
+ *
74
+ * @uses api_request()
75
+ *
76
+ * @param array $_transient_data Update array build by WordPress.
77
+ * @return array Modified update array with custom plugin data.
78
+ */
79
+ public function check_update( $_transient_data ) {
80
 
81
+ global $pagenow;
82
 
83
+ if( ! is_object( $_transient_data ) ) {
84
+ $_transient_data = new stdClass;
85
+ }
86
 
87
+ if( 'plugins.php' == $pagenow && is_multisite() ) {
88
+ return $_transient_data;
89
+ }
90
 
91
+ if ( empty( $_transient_data->response ) || empty( $_transient_data->response[ $this->name ] ) ) {
92
 
93
+ $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
 
94
 
95
+ if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
96
 
97
+ if( version_compare( $this->version, $version_info->new_version, '<' ) ) {
98
 
99
+ $_transient_data->response[ $this->name ] = $version_info;
 
100
 
101
+ }
 
 
 
 
 
 
102
 
103
+ $_transient_data->last_checked = time();
104
+ $_transient_data->checked[ $this->name ] = $this->version;
 
105
 
106
+ }
 
 
107
 
108
+ }
 
 
109
 
110
+ return $_transient_data;
111
+ }
112
 
113
+ /**
114
+ * show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
115
+ *
116
+ * @param string $file
117
+ * @param array $plugin
118
+ */
119
+ public function show_update_notification( $file, $plugin ) {
120
 
121
+ if( ! current_user_can( 'update_plugins' ) ) {
122
+ return;
123
+ }
124
 
125
+ if( ! is_multisite() ) {
126
+ return;
127
+ }
128
 
129
+ if ( $this->name != $file ) {
130
+ return;
131
+ }
132
 
133
+ // Remove our filter on the site transient
134
+ remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );
135
 
136
+ $update_cache = get_site_transient( 'update_plugins' );
 
137
 
138
+ $update_cache = is_object( $update_cache ) ? $update_cache : new stdClass();
139
 
140
+ if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
 
 
141
 
142
+ $cache_key = md5( 'edd_plugin_' . sanitize_key( $this->name ) . '_version_info' );
143
+ $version_info = get_transient( $cache_key );
144
 
145
+ if( false === $version_info ) {
146
 
147
+ $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
148
 
149
+ set_transient( $cache_key, $version_info, 3600 );
150
+ }
151
 
152
+ if( ! is_object( $version_info ) ) {
153
+ return;
154
+ }
155
 
156
+ if( version_compare( $this->version, $version_info->new_version, '<' ) ) {
157
 
158
+ $update_cache->response[ $this->name ] = $version_info;
159
 
160
+ }
161
 
162
+ $update_cache->last_checked = time();
163
+ $update_cache->checked[ $this->name ] = $this->version;
164
 
165
+ set_site_transient( 'update_plugins', $update_cache );
166
 
167
+ } else {
 
 
168
 
169
+ $version_info = $update_cache->response[ $this->name ];
170
 
171
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
 
173
+ // Restore our filter
174
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
 
175
 
176
+ if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) {
177
 
178
+ // build a plugin list row, with update notification
179
+ $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
180
+ echo '<tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"><div class="update-message">';
 
 
 
 
 
 
 
 
181
 
182
+ $changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
183
 
184
+ if ( empty( $version_info->download_link ) ) {
185
+ printf(
186
+ __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s.', 'easy-digital-downloads' ),
187
+ esc_html( $version_info->name ),
188
+ '<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
189
+ esc_html( $version_info->new_version ),
190
+ '</a>'
191
+ );
192
+ } else {
193
+ printf(
194
+ __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s or %5$supdate now%6$s.', 'easy-digital-downloads' ),
195
+ esc_html( $version_info->name ),
196
+ '<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
197
+ esc_html( $version_info->new_version ),
198
+ '</a>',
199
+ '<a href="' . esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) ) .'">',
200
+ '</a>'
201
+ );
202
+ }
203
 
204
+ do_action( "in_plugin_update_message-{$file}", $plugin, $version_info );
205
 
206
+ echo '</div></td></tr>';
207
+ }
208
+ }
209
 
 
210
 
211
+ /**
212
+ * Updates information on the "View version x.x details" page with custom data.
213
+ *
214
+ * @uses api_request()
215
+ *
216
+ * @param mixed $_data
217
+ * @param string $_action
218
+ * @param object $_args
219
+ * @return object $_data
220
+ */
221
+ public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
222
 
 
223
 
224
+ if ( $_action != 'plugin_information' ) {
 
 
 
 
 
 
 
225
 
226
+ return $_data;
227
 
228
+ }
 
 
229
 
230
+ if ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) {
 
231
 
232
+ return $_data;
233
 
234
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
+ $to_send = array(
237
+ 'slug' => $this->slug,
238
+ 'is_ssl' => is_ssl(),
239
+ 'fields' => array(
240
+ 'banners' => false, // These will be supported soon hopefully
241
+ 'reviews' => false
242
+ )
243
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
+ $api_response = $this->api_request( 'plugin_information', $to_send );
246
 
247
+ if ( false !== $api_response ) {
248
+ $_data = $api_response;
249
+ }
250
+
251
+ return $_data;
252
+ }
253
 
 
 
 
 
 
254
 
255
+ /**
256
+ * Disable SSL verification in order to prevent download update failures
257
+ *
258
+ * @param array $args
259
+ * @param string $url
260
+ * @return object $array
261
+ */
262
+ public function http_request_args( $args, $url ) {
263
+ // If it is an https request and we are performing a package download, disable ssl verification
264
+ if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
265
+ $args['sslverify'] = false;
266
+ }
267
+ return $args;
268
+ }
269
+
270
+ /**
271
+ * Calls the API and, if successfull, returns the object delivered by the API.
272
+ *
273
+ * @uses get_bloginfo()
274
+ * @uses wp_remote_post()
275
+ * @uses is_wp_error()
276
+ *
277
+ * @param string $_action The requested action.
278
+ * @param array $_data Parameters for the API action.
279
+ * @return false|object
280
+ */
281
+ private function api_request( $_action, $_data ) {
282
+
283
+ global $wp_version;
284
+
285
+ $data = array_merge( $this->api_data, $_data );
286
+
287
+ if ( $data['slug'] != $this->slug ) {
288
+ return;
289
+ }
290
+
291
+ if( $this->api_url == home_url() ) {
292
+ return false; // Don't allow a plugin to ping itself
293
+ }
294
+
295
+ $api_params = array(
296
+ 'edd_action' => 'get_version',
297
+ 'license' => ! empty( $data['license'] ) ? $data['license'] : '',
298
+ 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
299
+ 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
300
+ 'slug' => $data['slug'],
301
+ 'author' => $data['author'],
302
+ 'url' => home_url()
303
+ );
304
+
305
+ $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
306
+
307
+ if ( ! is_wp_error( $request ) ) {
308
+ $request = json_decode( wp_remote_retrieve_body( $request ) );
309
+ }
310
+
311
+ if ( $request && isset( $request->sections ) ) {
312
+ $request->sections = maybe_unserialize( $request->sections );
313
+ } else {
314
+ $request = false;
315
+ }
316
+
317
+ return $request;
318
+ }
319
 
320
+ public function show_changelog() {
321
 
322
+ global $edd_plugin_data;
323
 
324
+ if( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
325
+ return;
326
+ }
327
+
328
+ if( empty( $_REQUEST['plugin'] ) ) {
329
+ return;
330
+ }
331
+
332
+ if( empty( $_REQUEST['slug'] ) ) {
333
+ return;
334
+ }
335
+
336
+ if( ! current_user_can( 'update_plugins' ) ) {
337
+ wp_die( __( 'You do not have permission to install plugin updates', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
338
+ }
339
+
340
+ $data = $edd_plugin_data[ $_REQUEST['slug'] ];
341
+ $cache_key = md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_version_info' );
342
+ $version_info = get_transient( $cache_key );
343
+
344
+ if( false === $version_info ) {
345
+
346
+ $api_params = array(
347
+ 'edd_action' => 'get_version',
348
+ 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
349
+ 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
350
+ 'slug' => $_REQUEST['slug'],
351
+ 'author' => $data['author'],
352
+ 'url' => home_url()
353
+ );
354
+
355
+ $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
356
+
357
+ if ( ! is_wp_error( $request ) ) {
358
+ $version_info = json_decode( wp_remote_retrieve_body( $request ) );
359
+ }
360
+
361
+ if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
362
+ $version_info->sections = maybe_unserialize( $version_info->sections );
363
+ } else {
364
+ $version_info = false;
365
+ }
366
+
367
+ set_transient( $cache_key, $version_info, 3600 );
368
+
369
+ }
370
+
371
+ if( ! empty( $version_info ) && isset( $version_info->sections['changelog'] ) ) {
372
+ echo '<div style="background:#fff;padding:10px;">' . $version_info->sections['changelog'] . '</div>';
373
+ }
374
 
375
+ exit;
376
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
 
378
  }
includes/update.php CHANGED
@@ -260,6 +260,9 @@
260
 
261
  // From 4.7.8
262
  'expiration_notice_period' => '2 weeks',
 
 
 
263
  )
264
  );
265
 
260
 
261
  // From 4.7.8
262
  'expiration_notice_period' => '2 weeks',
263
+
264
+ // From 4.8.2
265
+ 'feed_request_useragent' => null,
266
  )
267
  );
268
 
readme.txt CHANGED
@@ -1,12 +1,12 @@
1
  === WP RSS Aggregator ===
2
  Contributors: jeangalea, Mekku, xedin.unknown, markzahra, doytch, chiragswadia
3
  Plugin URI: http://www.wprssaggregator.com
4
- Tags: rss, aggregation, autoblog, autoblog aggregator, autoblogger, autoblogging, autopost, content curation, feed aggregation, feed aggregator, feed import, feed reader, feed to post, feeds, multi feed import, multi feed importer, multi rss feeds, multiple feed import, multiple rss feeds,rss aggregator, rss feader, RSS Feed, rss feed to post, rss feeder, RSS import, rss multi importer, rss post importer, rss retriever, rss to post, syndication
5
  Requires at least: 4.0
6
  Tested up to: 4.4.1
7
- Stable tag: 4.8.1
8
  License: GPLv2 or later
9
- WP RSS Aggregator is the No.1 RSS feed importer and autoblogging plugin for WordPress. It provides the most comprehensive and elegant solution to import RSS feeds with premium add-ons available for additional functionality.
10
 
11
 
12
  == Description ==
@@ -15,6 +15,9 @@ WP RSS Aggregator is the original and best plugin for importing, merging and dis
15
 
16
  With this free core version of WP RSS Aggregator you’ll be able to aggregate as many RSS feeds from as many sources as you'd like. Using the [shortcodes](http://docs.wprssaggregator.com/shortcodes/) you can then display the imported feed items from one or more sources directly on your website.
17
 
 
 
 
18
  = Highlighted Features =
19
 
20
  * Set a name for each feed source.
@@ -45,7 +48,7 @@ WP RSS Aggregator also has a number of premium add-ons that add more functionali
45
  * [Full Text RSS Feeds](http://www.wprssaggregator.com/extension/full-text-rss-feeds/) adds connectivity to our Full Text Premium service, which allows you to import the full post content for an unlimited number of feed items per feed source, even when the feed itself doesn’t provide it. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/))
46
  * [WordAi](http://www.wprssaggregator.com/extension/wordai/) allows you to take an RSS feed and turn it into new content that is both completely unique and completely readable. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) and a [WordAi account](https://wordai.com/))
47
  * [Widget](http://www.wprssaggregator.com/extension/widget/) adds a widget to your website that displays the imported feed items. It can also display excerpts and thumbnail images when used in conjunction with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extension/excerpts-thumbnails/) add-on.
48
- * [SpinnerChief](http://www.wprssaggregator.com/extension/spinnerchief/) An extension for [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) that allows you to integrate the SpinnerChief article spinner so that the imported content is both completely unique and completely readable.
49
 
50
  [View a comparison of our three most popular add-ons here](http://www.wprssaggregator.com/product-comparison/). If you're unsure as to which add-ons you need, [we put together this post to help you out](http://www.wprssaggregator.com/add-ons-purchase/).
51
 
@@ -56,9 +59,7 @@ We also provide a [Feed Creator](http://createfeed.wprssaggregator.com/) service
56
  = Demo =
57
  The core plugin can be seen in use [on our website's demo page](http://www.wprssaggregator.com/demo/). There are also a number of [other demos](http://www.wprssaggregator.com/) available for our premium add-ons.
58
 
59
- = Video Walkthrough =
60
- Have a look at the core version of WP RSS Aggregator below, or [go here to view our introductory videos for the premium add-ons](http://docs.wprssaggregator.com/introductory-videos/).
61
- [youtube http://www.youtube.com/watch?v=fcENPsmJbvc]
62
 
63
  = Documentation =
64
  Our [comprehensive documentation](http://docs.wprssaggregator.com/) provides you with everything you need to install, set up and customize the plugin to your needs. You can also browse through [a large number of FAQs](http://docs.wprssaggregator.com/category/faqs/) that cover almost everything there is to ask.
@@ -78,6 +79,7 @@ Our [comprehensive documentation](http://docs.wprssaggregator.com/) provides you
78
  * [IndexWP](http://www.indexwp.com/wp-rss-aggregator-plugin-review/)
79
  * [WPulsar](http://www.wpulsar.com/wp-rss-aggregator-plugin-feed-to-posts-keyword-filtering-review/)
80
  * [Kevin Muldoon](http://www.kevinmuldoon.com/wp-rss-aggregator-wordpress-plugin/)
 
81
 
82
  = Translations =
83
  * Italian - Davide De Maestri
@@ -186,6 +188,14 @@ Our complete documentation with FAQs included can be found on [our dedicated doc
186
 
187
  == Changelog ==
188
 
 
 
 
 
 
 
 
 
189
  = 4.8.1 (2016-02-02) =
190
  * Fixed bug: Some exceptions used to cause fatal errors.
191
  * Fixed bug: Requests made by image caching used to always have an infinite timeout.
1
  === WP RSS Aggregator ===
2
  Contributors: jeangalea, Mekku, xedin.unknown, markzahra, doytch, chiragswadia
3
  Plugin URI: http://www.wprssaggregator.com
4
+ Tags: RSS feeds, aggregation, autoblog, content curation, feed reader, feed to post, RSS aggregator, RSS feeder, RSS import, RSS to post, syndication, multiple feed import
5
  Requires at least: 4.0
6
  Tested up to: 4.4.1
7
+ Stable tag: 4.8.2
8
  License: GPLv2 or later
9
+ WP RSS Aggregator is the most comprehensive RSS feed importer and autoblogging plugin for WordPress with premium add-ons for additional functionality.
10
 
11
 
12
  == Description ==
15
 
16
  With this free core version of WP RSS Aggregator you’ll be able to aggregate as many RSS feeds from as many sources as you'd like. Using the [shortcodes](http://docs.wprssaggregator.com/shortcodes/) you can then display the imported feed items from one or more sources directly on your website.
17
 
18
+ Have a look at the core version of WP RSS Aggregator below, or [go here to view our introductory videos for the premium add-ons](http://docs.wprssaggregator.com/introductory-videos/).
19
+ [youtube http://www.youtube.com/watch?v=fcENPsmJbvc]
20
+
21
  = Highlighted Features =
22
 
23
  * Set a name for each feed source.
48
  * [Full Text RSS Feeds](http://www.wprssaggregator.com/extension/full-text-rss-feeds/) adds connectivity to our Full Text Premium service, which allows you to import the full post content for an unlimited number of feed items per feed source, even when the feed itself doesn’t provide it. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/))
49
  * [WordAi](http://www.wprssaggregator.com/extension/wordai/) allows you to take an RSS feed and turn it into new content that is both completely unique and completely readable. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) and a [WordAi account](https://wordai.com/))
50
  * [Widget](http://www.wprssaggregator.com/extension/widget/) adds a widget to your website that displays the imported feed items. It can also display excerpts and thumbnail images when used in conjunction with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extension/excerpts-thumbnails/) add-on.
51
+ * [SpinnerChief](http://www.wprssaggregator.com/extension/spinnerchief/) is an extension for [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) that allows you to integrate the SpinnerChief article spinner so that the imported content is both completely unique and completely readable.
52
 
53
  [View a comparison of our three most popular add-ons here](http://www.wprssaggregator.com/product-comparison/). If you're unsure as to which add-ons you need, [we put together this post to help you out](http://www.wprssaggregator.com/add-ons-purchase/).
54
 
59
  = Demo =
60
  The core plugin can be seen in use [on our website's demo page](http://www.wprssaggregator.com/demo/). There are also a number of [other demos](http://www.wprssaggregator.com/) available for our premium add-ons.
61
 
62
+ For a fully fledged example of the plugin and add-ons in action check out the WordPress news site [WP News Desk](http://www.wpnewsdesk.com). If you want to create a news aggregator site like this you can follow our [step-by-step tutorial](http://www.wpmayor.com/how-to-set-up-a-news-aggregation-site-with-wordpress-wp-rss-aggregator/).
 
 
63
 
64
  = Documentation =
65
  Our [comprehensive documentation](http://docs.wprssaggregator.com/) provides you with everything you need to install, set up and customize the plugin to your needs. You can also browse through [a large number of FAQs](http://docs.wprssaggregator.com/category/faqs/) that cover almost everything there is to ask.
79
  * [IndexWP](http://www.indexwp.com/wp-rss-aggregator-plugin-review/)
80
  * [WPulsar](http://www.wpulsar.com/wp-rss-aggregator-plugin-feed-to-posts-keyword-filtering-review/)
81
  * [Kevin Muldoon](http://www.kevinmuldoon.com/wp-rss-aggregator-wordpress-plugin/)
82
+ * [Magazine3](http://magazine3.com/blog/news-aggregator-website/)
83
 
84
  = Translations =
85
  * Italian - Davide De Maestri
188
 
189
  == Changelog ==
190
 
191
+ = 4.8.2 (2016-02-22) =
192
+ * Fixed bug: Interface methods used to conflict, causing fatal error on activation.
193
+ * Fixed bug: Empty feed response used to cause misleading error message in log.
194
+ * Enhanced: Users can now override useragent sent with feed requests.
195
+ * Enhanced: Improvements to plugin updating system.
196
+ * Enhanced: Readme updated.
197
+ * Enhanced: "Open link behaviour" option's internal handling has been improved.
198
+
199
  = 4.8.1 (2016-02-02) =
200
  * Fixed bug: Some exceptions used to cause fatal errors.
201
  * Fixed bug: Requests made by image caching used to always have an infinite timeout.
wp-rss-aggregator.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: WP RSS Aggregator
4
  Plugin URI: http://www.wprssaggregator.com
5
  Description: Imports and aggregates multiple RSS Feeds using SimplePie
6
- Version: 4.8.1
7
  Author: Jean Galea
8
  Author URI: http://www.wprssaggregator.com
9
  License: GPLv2
@@ -29,7 +29,7 @@
29
 
30
  /**
31
  * @package WPRSSAggregator
32
- * @version 4.8.1
33
  * @since 1.0
34
  * @author Jean Galea <info@wprssaggregator.com>
35
  * @copyright Copyright (c) 2012-2015, Jean Galea
@@ -43,14 +43,14 @@
43
 
44
  // Set the version number of the plugin.
45
  if( !defined( 'WPRSS_VERSION' ) )
46
- define( 'WPRSS_VERSION', '4.8.1', true );
47
 
48
  if( !defined( 'WPRSS_WP_MIN_VERSION' ) )
49
  define( 'WPRSS_WP_MIN_VERSION', '4.0', true );
50
 
51
  // Set the database version number of the plugin.
52
  if( !defined( 'WPRSS_DB_VERSION' ) )
53
- define( 'WPRSS_DB_VERSION', 14 );
54
 
55
  // Set the plugin prefix
56
  if( !defined( 'WPRSS_PREFIX' ) )
3
  Plugin Name: WP RSS Aggregator
4
  Plugin URI: http://www.wprssaggregator.com
5
  Description: Imports and aggregates multiple RSS Feeds using SimplePie
6
+ Version: 4.8.2
7
  Author: Jean Galea
8
  Author URI: http://www.wprssaggregator.com
9
  License: GPLv2
29
 
30
  /**
31
  * @package WPRSSAggregator
32
+ * @version 4.8.2
33
  * @since 1.0
34
  * @author Jean Galea <info@wprssaggregator.com>
35
  * @copyright Copyright (c) 2012-2015, Jean Galea
43
 
44
  // Set the version number of the plugin.
45
  if( !defined( 'WPRSS_VERSION' ) )
46
+ define( 'WPRSS_VERSION', '4.8.2', true );
47
 
48
  if( !defined( 'WPRSS_WP_MIN_VERSION' ) )
49
  define( 'WPRSS_WP_MIN_VERSION', '4.0', true );
50
 
51
  // Set the database version number of the plugin.
52
  if( !defined( 'WPRSS_DB_VERSION' ) )
53
+ define( 'WPRSS_DB_VERSION', 15 );
54
 
55
  // Set the plugin prefix
56
  if( !defined( 'WPRSS_PREFIX' ) )