PluginProbe ʕ •ᴥ•ʔ
WP All Import – Drag & Drop Import for CSV, XML, Excel & Google Sheets / 4.1.1
WP All Import – Drag & Drop Import for CSV, XML, Excel & Google Sheets v4.1.1
4.1.1 3.9.5 3.9.6 4.0.0 4.0.1 4.1.0 trunk 2.12 2.13 2.14 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 3.4.8 3.4.9 3.5.0 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.5.6 3.5.7 3.5.8 3.5.9 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.6.9 3.7.0 3.7.1 3.7.2 3.7.3 3.7.3-beta-1.0 3.7.4 3.7.4-beta-1.0 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 3.8.0 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4
wp-all-import / addon-api / classes / updater.php
wp-all-import / addon-api / classes Last commit date
admin.php 1 month ago base.php 1 month ago data-importer.php 1 month ago helpers.php 1 month ago importer.php 1 month ago manager.php 1 month ago parser.php 1 month ago post-data-importer.php 1 month ago rest.php 1 month ago updater.php 1 month ago view.php 1 month ago
updater.php
414 lines
1 <?php
2 namespace Wpai\AddonAPI;
3
4 if ( ! defined( 'ABSPATH' ) ) exit;
5
6 class PMXI_Addon_Updater {
7 private $api_url = '';
8 private $api_data = array();
9 private $name = '';
10 private $slug = '';
11 private $_plugin_file = '';
12 private $did_check = false;
13 private $version;
14
15 /**
16 * Class constructor.
17 *
18 * @param string $_api_url The URL pointing to the custom API endpoint.
19 * @param string $_plugin_file Path to the plugin file.
20 * @param array $_api_data Optional data to send with API calls.
21 *
22 * @return void
23 * @uses plugin_basename()
24 * @uses hook()
25 *
26 */
27 function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
28 $this->api_url = trailingslashit( $_api_url );
29 $this->api_data = urlencode_deep( $_api_data );
30 $this->name = plugin_basename( $_plugin_file );
31 $this->slug = strtok($this->name, '/');//basename( $_plugin_file, '.php' );
32
33 $this->version = $_api_data['version'];
34 $this->_plugin_file = $_plugin_file;
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 * @return void
45 * @uses add_filter()
46 *
47 */
48 public function init() {
49
50 add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 21 );
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 add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
55 }
56
57 /**
58 * Show row meta on the plugin screen.
59 *
60 * @param mixed $links Plugin Row Meta
61 * @param mixed $file Plugin Base file
62 *
63 * @return array
64 */
65 public function plugin_row_meta( $links, $file ) {
66 if ( $file == $this->name ) {
67 $admin_url = esc_url(admin_url('plugin-install.php?tab=plugin-information&plugin='.$this->slug.'&section=changelog&TB_iframe=true&width=600&height=800'));
68 $title = esc_attr( esc_html__( 'View Changelog', 'wp-all-import' ) );
69 $text = esc_html__( 'Changelog', 'wp-all-import' );
70
71 $row_meta = array(
72 'changelog' => "<a href=\"{$admin_url}\" class=\"thickbox open-plugin-details-modal\" title=\"{$title}\">{$text}</a>",
73 );
74
75 return array_merge( $links, $row_meta );
76 }
77
78 return (array) $links;
79 }
80
81 /**
82 * Check for Updates at the defined API endpoint and modify the update array.
83 *
84 * This function dives into the update API just when WordPress creates its update array,
85 * then adds a custom API call and injects the custom plugin data retrieved from the API.
86 * It is reassembled from parts of the native WordPress plugin update code.
87 * See wp-includes/update.php line 121 for the original wp_update_plugins() function.
88 *
89 * @param array $_transient_data Update array build by WordPress.
90 *
91 * @return array Modified update array with custom plugin data.
92 * @uses api_request()
93 *
94 */
95 function check_update( $_transient_data ) {
96
97 global $pagenow;
98
99 if ( ! is_object( $_transient_data ) ) {
100 $_transient_data = new \stdClass;
101 }
102
103 if ( 'plugins.php' == $pagenow && is_multisite() ) {
104 return $_transient_data;
105 }
106
107 if ( empty( $_transient_data ) ) {
108 return $_transient_data;
109 }
110
111 if ( empty( $_transient_data->response ) || empty( $_transient_data->response[ $this->name ] ) ) {
112
113 $cache_key = md5( 'edd_plugin_' . sanitize_key( $this->name ) . '_version_info' );
114 $version_info = get_transient( $cache_key );
115
116 if ( false === $version_info ) {
117
118 $version_info = $this->api_request( 'check_update', array( 'slug' => $this->slug ) );
119 set_transient( $cache_key, $version_info, 3600 * 24 );
120 }
121
122 if ( ! is_object( $version_info ) ) {
123 return $_transient_data;
124 }
125
126 if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
127
128 $this->did_check = true;
129
130 if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
131
132 $_transient_data->response[ $this->name ] = $version_info;
133 }
134
135 $_transient_data->last_checked = time();
136 $_transient_data->checked[ $this->name ] = $this->version;
137 }
138 }
139
140 return $_transient_data;
141 }
142
143 /**
144 * show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
145 *
146 * @param string $file
147 * @param array $plugin
148 */
149 public function show_update_notification( $file, $plugin ) {
150
151 if ( ! current_user_can( 'update_plugins' ) ) {
152 return;
153 }
154
155 if ( ! is_multisite() ) {
156 return;
157 }
158
159 if ( $this->name != $file ) {
160 return;
161 }
162
163 // Remove our filter on the site transient
164 remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 21 );
165
166 $update_cache = get_site_transient( 'update_plugins' );
167
168 if ( ! is_object( $update_cache ) || empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
169
170 $cache_key = md5( 'edd_plugin_' . sanitize_key( $this->name ) . '_version_info' );
171 $version_info = get_transient( $cache_key );
172
173 if ( false === $version_info ) {
174
175 $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
176
177 set_transient( $cache_key, $version_info, 3600 * 24 );
178 }
179
180
181 if ( ! is_object( $version_info ) ) {
182 return;
183 }
184
185 if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
186
187 $update_cache->response[ $this->name ] = $version_info;
188 }
189
190 $update_cache->last_checked = time();
191 $update_cache->checked[ $this->name ] = $this->version;
192
193 set_site_transient( 'update_plugins', $update_cache );
194 } else {
195
196 $version_info = $update_cache->response[ $this->name ];
197 }
198
199 // Restore our filter
200 add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 21 );
201
202 if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) {
203
204 // build a plugin list row, with update notification
205 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
206 echo '<tr class="plugin-update-tr"><td colspan="' . esc_attr( $wp_list_table->get_column_count() ) . '" class="plugin-update colspanchange"><div class="update-message">';
207
208 $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' );
209
210 $allowed_html = array(
211 'a' => array(
212 'href' => array(),
213 'target' => array(),
214 'class' => array(),
215 ),
216 );
217
218 if ( empty( $version_info->download_link ) ) {
219 echo wp_kses(
220 sprintf(
221 /* translators: 1: add-on name, 2: changelog URL, 3: new version */
222 __( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a>.', 'wp-all-import' ),
223 esc_html( $version_info->name ),
224 esc_url( $changelog_link ),
225 esc_html( $version_info->new_version )
226 ),
227 $allowed_html
228 );
229 } else {
230 echo wp_kses(
231 sprintf(
232 /* translators: 1: add-on name, 2: changelog URL, 3: new version, 4: update URL */
233 __( '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>.', 'wp-all-import' ),
234 esc_html( $version_info->name ),
235 esc_url( $changelog_link ),
236 esc_html( $version_info->new_version ),
237 esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) )
238 ),
239 $allowed_html
240 );
241 }
242
243 echo '</div></td></tr>';
244 }
245 }
246
247 /**
248 * Updates information on the "View version x.x details" page with custom data.
249 *
250 * @param mixed $_data
251 * @param string $_action
252 * @param object $_args
253 *
254 * @return object $_data
255 * @uses api_request()
256 *
257 */
258 function plugins_api_filter( $_data, $_action = '', $_args = null ) {
259
260
261 if ( $_action != 'plugin_information' ) {
262
263 return $_data;
264 }
265
266 if ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) {
267
268 return $_data;
269 }
270
271 $cache_key = md5( 'edd_plugin_' . sanitize_key( $this->name ) . '_version_info' );
272 $_data = get_transient( $cache_key );
273
274 if ( false === $_data ) {
275
276 $to_send = array(
277 'slug' => $this->slug,
278 'is_ssl' => is_ssl(),
279 'fields' => array(
280 'banners' => false, // These will be supported soon hopefully
281 'reviews' => false
282 )
283 );
284
285 $api_response = $this->api_request( 'plugin_information', $to_send );
286
287 if ( false !== $api_response ) {
288 $_data = $api_response;
289 set_transient( $cache_key, $_data, 3600 * 24 );
290 }
291 }
292
293 return $_data;
294 }
295
296
297 /**
298 * Disable SSL verification in order to prevent download update failures
299 *
300 * @param array $args
301 * @param string $url
302 *
303 * @return object $array
304 */
305 function http_request_args( $args, $url ) {
306 // If it is an https request and we are performing a package download, disable ssl verification
307 if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
308 $args['sslverify'] = false;
309 }
310
311 return $args;
312 }
313
314 /**
315 * Calls the API and, if successfull, returns the object delivered by the API.
316 *
317 * @param string $_action The requested action.
318 * @param array $_data Parameters for the API action.
319 *
320 * @return false||object
321 * @uses get_bloginfo()
322 * @uses wp_remote_post()
323 * @uses is_wp_error()
324 *
325 */
326 private function api_request( $_action, $_data ) {
327
328 global $wp_version;
329
330 $data = array_merge( $this->api_data, $_data );
331
332 if ( $data['slug'] != $this->slug ) {
333 return;
334 }
335
336 /*if ( empty( $data['license'] ) )
337 return;*/
338
339 if ( $this->api_url == home_url() ) {
340 return false; // Don't allow a plugin to ping itself
341 }
342
343 $api_params = array(
344 'edd_action' => 'get_version',
345 'license' => false,
346 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
347 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
348 'slug' => $data['slug'],
349 'plugin' => $this->_plugin_file,
350 'author' => $data['author'],
351 'url' => home_url(),
352 'version' => $this->version
353 );
354
355 // Send request based on provided API URL.
356 if ( strpos( $this->api_url, 'update.' ) !== false ) {
357 $request = wp_remote_get( esc_url_raw( add_query_arg( $api_params, $this->api_url . 'check_version/?' ) ), array( 'timeout' => 15,
358 'sslverify' => true
359 ) );
360 } else {
361 $request = wp_remote_post( $this->api_url, array( 'timeout' => 15,
362 'sslverify' => true,
363 'body' => $api_params
364 ) );
365 }
366
367 if ( ! is_wp_error( $request ) ) {
368 $request = json_decode( wp_remote_retrieve_body( $request ) );
369 }
370
371 if ( $request && isset( $request->banners ) ) {
372 $request->banners = maybe_unserialize( $request->banners );
373 }
374
375 if ( $request && isset( $request->sections ) ) {
376 $request->sections = maybe_unserialize( $request->sections );
377 } else {
378 $request = false;
379 }
380
381 return $request;
382 }
383
384 public function show_changelog() {
385
386 // phpcs:disable WordPress.Security.NonceVerification.Recommended
387 if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
388 return;
389 }
390
391 if ( empty( $_REQUEST['plugin'] ) ) {
392 return;
393 }
394
395 if ( empty( $_REQUEST['slug'] ) ) {
396 return;
397 }
398
399 if ( ! current_user_can( 'update_plugins' ) ) {
400 wp_die( esc_html__( 'You do not have permission to install plugin updates', 'wp-all-import' ), esc_html__( 'Error', 'wp-all-import' ), array( 'response' => 403 ) );
401 }
402
403 $response = $this->api_request( 'show_changelog', array( 'slug' => sanitize_text_field( wp_unslash( $_REQUEST['slug'] ) ) ) );
404 // phpcs:enable WordPress.Security.NonceVerification.Recommended
405
406 if ( $response && isset( $response->sections['changelog'] ) ) {
407 echo '<div style="background:#fff;padding:10px;">' . wp_kses_post( $response->sections['changelog'] ) . '</div>';
408 }
409
410
411 exit;
412 }
413 }
414