PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / trunk
GiveWP – Donation Plugin and Fundraising Platform vtrunk
4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / admin / add-ons / actions.php
give / includes / admin / add-ons Last commit date
actions.php 5 days ago
actions.php
814 lines
1 <?php
2 /**
3 * Admin Add-ons Actions
4 *
5 * @package Give
6 * @subpackage Admin/Add-ons/Actions
7 * @copyright Copyright (c) 2019, GiveWP
8 * @license https://opensource.org/licenses/gpl-license GNU Public License
9 * @since 2.5.0
10 */
11
12 use Give\VendorOverrides\Harbor\Actions\HarborHasLoaded;
13
14 // Exit if accessed directly.
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * Ajax addon upload handler
21 *
22 * Note: only for internal use
23 *
24 * @since 4.16.6 Use Plugin_Upgrader to install/update the add-on, replacing unreliable
25 * filename-based pre-existing checks and post-install detection.
26 * @since 2.5.0
27 */
28 function give_upload_addon_handler() {
29 if ( ! isset( $_FILES['file']['name'] ) ) {
30 wp_send_json_error( [ 'errorMsg' => __( 'No file was uploaded.', 'give' ) ] );
31 }
32
33 if ( UPLOAD_ERR_OK !== $_FILES['file']['error'] ) {
34 wp_send_json_error( [ 'errorMsg' => __( 'The file upload failed. Please try again.', 'give' ) ] );
35 }
36
37 check_admin_referer( 'give-upload-addon' );
38
39 if ( ! current_user_can( 'upload_plugins' ) ) {
40 wp_send_json_error( [ 'errorMsg' => __( 'The current user does not have permission to upload plugins on this site.', 'give' ) ] );
41 }
42
43 $access_type = get_filesystem_method();
44
45 if ( 'direct' !== $access_type ) {
46 wp_send_json_error(
47 [
48 'errorMsg' => sprintf(
49 __( 'In order to upload add-ons here, GiveWP needs direct access to the file system. Please <a href="%1$s" target="_blank">visit the main plugin page</a> to manually upload the add-on.', 'give' ),
50 esc_url( admin_url( 'plugin-install.php?tab=upload' ) )
51 ),
52 ]
53 );
54 }
55
56 $file_type = wp_check_filetype( $_FILES['file']['name'], [ 'zip' => 'application/zip' ] );
57
58 if ( empty( $file_type['ext'] ) ) {
59 wp_send_json_error( [ 'errorMsg' => __( 'Uploaded add-ons must be (zipped) ZIP files. Upload a valid add-on ZIP.', 'give' ) ] );
60 }
61
62 // Snapshot existing Give add-ons for diff after installation.
63 $pre_addons_list = give_get_plugins( [ 'only_add_on' => true ] );
64
65 // Detect the plugin folder name from the ZIP to check for an existing installation.
66 $zip_folder = give_get_zip_plugin_folder( $_FILES['file']['tmp_name'] );
67
68 if ( ! empty( $zip_folder ) && ! empty( $pre_addons_list ) ) {
69 foreach ( $pre_addons_list as $addon_path => $addon_data ) {
70 if ( strpos( $addon_path, $zip_folder . '/' ) === 0 ) {
71 wp_send_json_error(
72 [
73 'errorMsg' => __( 'This add-on is already installed.', 'give' ),
74 'pluginInfo' => $addon_data,
75 ]
76 );
77 }
78 }
79 }
80
81 // Install the plugin using the WordPress upgrader.
82 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
83 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
84 require_once ABSPATH . 'wp-admin/includes/class-automatic-upgrader-skin.php';
85 require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
86 require_once ABSPATH . 'wp-admin/includes/plugin.php';
87
88 $skin = new Automatic_Upgrader_Skin();
89 $upgrader = new Plugin_Upgrader( $skin );
90
91 $buffer_level = ob_get_level();
92
93 $result = $upgrader->install( $_FILES['file']['tmp_name'] );
94
95 while ( ob_get_level() > $buffer_level ) {
96 // A non-removable buffer, such as zlib, would loop until the request times out.
97 if ( ! @ob_end_clean() ) {
98 break;
99 }
100 }
101
102 if ( is_wp_error( $result ) ) {
103 wp_send_json_error( [ 'errorMsg' => $result->get_error_message() ] );
104 }
105
106 if ( ! $result ) {
107 $error_message = is_wp_error( $skin->result )
108 ? $skin->result->get_error_message()
109 : __( 'The add-on could not be installed. Please try again or upload it manually.', 'give' );
110
111 wp_send_json_error( [ 'errorMsg' => $error_message ] );
112 }
113
114 // Refresh the plugin cache and find the newly installed or updated plugin.
115 wp_clean_plugins_cache( true );
116
117 $post_addons_list = give_get_plugins( [ 'only_add_on' => true ] );
118 $new_plugins = array_diff_key( $post_addons_list, $pre_addons_list );
119
120 $installed_addon = [];
121
122 if ( ! empty( $new_plugins ) ) {
123 $new_plugin_path = array_key_first( $new_plugins );
124 $installed_addon = $new_plugins[ $new_plugin_path ];
125 $installed_addon['path'] = $new_plugin_path;
126 }
127
128 if ( empty( $installed_addon ) ) {
129 wp_send_json_error(
130 [
131 'errorMsg' => sprintf(
132 /* translators: %1$s: URL to the plugins page */
133 __( 'The add-on was uploaded but GiveWP could not detect it. Please <a href="%1$s">visit the plugins page</a> to activate it manually.', 'give' ),
134 esc_url( admin_url( 'plugins.php' ) )
135 ),
136 ]
137 );
138 }
139
140 wp_send_json_success(
141 [
142 'pluginPath' => $installed_addon['path'],
143 'pluginName' => $installed_addon['Name'],
144 'nonce' => wp_create_nonce( "give_activate-{$installed_addon['path']}" ),
145 'licenseSectionHtml' => Give_License::render_licenses_list(),
146 ]
147 );
148 }
149
150 /**
151 * Reads the top-level directory name from a plugin ZIP file.
152 *
153 * Returns the single top-level directory name inside the ZIP (e.g. "give-recurring").
154 * Returns an empty string if the ZIP can't be read or contains multiple top-level items.
155 *
156 * @since 4.16.6
157 *
158 * @param string $zip_file Absolute path to the ZIP file.
159 *
160 * @return string Plugin folder name, or empty string on failure.
161 */
162 function give_get_zip_plugin_folder( $zip_file ) {
163 if ( ! file_exists( $zip_file ) || ! class_exists( 'ZipArchive' ) ) {
164 return '';
165 }
166
167 $zip = new ZipArchive();
168
169 if ( true !== $zip->open( $zip_file ) ) {
170 return '';
171 }
172
173 $folder = '';
174
175 for ( $i = 0; $i < $zip->numFiles; $i++ ) {
176 $entry = $zip->getNameIndex( $i );
177 $parts = explode( '/', $entry );
178
179 // Skip macOS metadata folders.
180 if ( isset( $parts[0] ) && '__MACOSX' === $parts[0] ) {
181 continue;
182 }
183
184 if ( count( $parts ) > 1 && '' !== $parts[0] ) {
185 if ( '' === $folder ) {
186 $folder = $parts[0];
187 } elseif ( $folder !== $parts[0] ) {
188 // Multiple top-level directories — ambiguous.
189 $folder = '';
190 break;
191 }
192 }
193 }
194
195 $zip->close();
196
197 return $folder;
198 }
199
200 add_action( 'wp_ajax_give_upload_addon', 'give_upload_addon_handler' );
201
202 /**
203 * Ajax license inquiry handler
204 *
205 * Note: only for internal use
206 *
207 * @since 4.16.7 Redirect unified license keys (LWSW-) to the Unified License Manager, when it is available.
208 * @since 2.5.0
209 */
210 function give_get_license_info_handler() {
211 check_admin_referer( 'give-license-activator-nonce' );
212
213 // check user permission.
214 if ( ! current_user_can( 'manage_give_settings' ) ) {
215 give_die();
216 }
217
218 $license_key = ! empty( $_POST['license'] ) ? give_clean( $_POST['license'] ) : '';
219 $is_activating_single_license = ! empty( $_POST['single'] ) ? absint( $_POST['single'] ) : '';
220 $is_reactivating_license = ! empty( $_POST['reactivate'] ) ? absint( $_POST['reactivate'] ) : '';
221 $plugin_slug = $is_activating_single_license ? give_clean( $_POST['addon'] ) : '';
222 $licenses = get_option( 'give_licenses', [] );
223
224 if ( ! $license_key ) {
225 wp_send_json_error(
226 [
227 'errorMsg' => __( 'You entered an invalid key. Confirm your license key on your GiveWP dashboard and try again.', 'give' ),
228 ]
229 );
230
231 } elseif ( 0 === stripos( $license_key, 'LWSW-' ) ) {
232 // The Unified License Manager is only available once a premium add-on is installed and active.
233 $harborHasLoaded = give( HarborHasLoaded::class )();
234
235 $error_message = $harborHasLoaded
236 ? sprintf(
237 /* translators: %s: URL to the Unified License Manager page */
238 __( 'This is a unified license key. To activate it, enter your license in the <a href="%s" target="_blank">Unified License Manager</a> instead.', 'give' ),
239 esc_url( lw_harbor_get_license_page_url() )
240 )
241 : __( 'This is a unified license key. It can be added from the Unified License Manager, which appears under GiveWP &gt; Licensing once an add-on is installed.', 'give' );
242
243 wp_send_json_error(
244 [
245 'errorMsg' => $error_message,
246 ]
247 );
248
249 } elseif (
250 ! $is_reactivating_license
251 && array_key_exists( $license_key, $licenses )
252 ) {
253 // If admin already activated license but did not install add-on then send license info show notice to admin with download link.
254 $license = $licenses[ $license_key ];
255 if ( empty( $license['is_all_access_pass'] ) ) {
256 $plugin_data = Give_License::get_plugin_by_slug( $license['plugin_slug'] );
257
258 // Plugin license activated but does not install, sent notice which allow admin to download add-on.
259 if ( empty( $plugin_data ) ) {
260 wp_send_json_success( $license );
261 }
262 }
263
264 wp_send_json_error(
265 [
266 'errorMsg' => __( 'This license key is already in use on this website.', 'give' ),
267 ]
268 );
269 }
270
271 // Check license.
272 $check_license_res = Give_License::request_license_api(
273 [
274 'edd_action' => 'check_license',
275 'license' => $license_key,
276 ],
277 true
278 );
279
280 // Make sure there are no errors.
281 if ( is_wp_error( $check_license_res ) ) {
282 wp_send_json_error(
283 [
284 'errorMsg' => $check_license_res->get_error_message(),
285 ]
286 );
287 }
288
289 // Check if license valid or not.
290 if ( ! $check_license_res['success'] ) {
291 wp_send_json_error(
292 [
293 'errorMsg' => sprintf(
294 __( 'The license failed to activate, due to a status of <code>%2$s</code>. Check the logs at Donations > Tools > Logs for more detail, and <a href="%1$s" target="_blank">reach out to the Customer Success team.</a>', 'give' ),
295 Give_License::get_account_url(),
296 $check_license_res['license']
297 ),
298 ]
299 );
300 }
301
302 if (
303 $is_activating_single_license
304 && ! empty( $check_license_res['plugin_slug'] )
305 && $plugin_slug !== $check_license_res['plugin_slug']
306 ) {
307 wp_send_json_error(
308 [
309 'errorMsg' => sprintf(
310 __( 'This license key does not belong to this add-on. <a href="%1$s" target="_blank">Reach out to the Customer Success team</a> if you continue to have issues.', 'give' ),
311 Give_License::get_account_url()
312 ),
313 ]
314 );
315 }
316
317 // Activate license.
318 $activate_license_res = Give_License::request_license_api(
319 [
320 'edd_action' => 'activate_license',
321 'item_name' => $check_license_res['item_name'],
322 'license' => $license_key,
323 ],
324 true
325 );
326
327 if ( is_wp_error( $activate_license_res ) ) {
328 wp_send_json_error(
329 [
330 'errorMsg' => $check_license_res->get_error_message(),
331 ]
332 );
333 }
334
335 // Return error if license activation is not success and admin is not reactivating add-on.
336 if ( ! $is_reactivating_license && ! $activate_license_res['success'] ) {
337
338 $response['errorMsg'] = sprintf(
339 __( 'The license failed to activate, due to a status of <code>%2$s</code>. Check the logs at Donations > Tools > Logs for more detail, and <a href="%1$s" target="_blank">reach out to the Customer Success team.</a>', 'give' ),
340 Give_License::get_account_url(),
341 $check_license_res['license']
342 );
343
344 wp_send_json_error( $response );
345 }
346
347 $check_license_res['license'] = $activate_license_res['license'];
348 $check_license_res['site_count'] = $activate_license_res['site_count'];
349 $check_license_res['activations_left'] = $activate_license_res['activations_left'];
350
351 // Remove single license which is part of all access pass or already existed all access pass key because admin can only one active.
352 // @see https://github.com/impress-org/givewp/issues/4669
353 if ( ! empty( $check_license_res['is_all_access_pass'] ) ) {
354 $addonSlugs = Give_License::getAddonSlugsFromAllAccessPassLicense( $check_license_res );
355 foreach ( $licenses as $license_key => $data ) {
356 if ( in_array( $data['plugin_slug'], $addonSlugs, true ) || ! empty( $data['is_all_access_pass'] ) ) {
357 unset( $licenses[ $license_key ] );
358 }
359 }
360 }
361
362 $licenses[ $check_license_res['license_key'] ] = $check_license_res;
363 update_option( 'give_licenses', $licenses );
364
365 // Get license section HTML.
366 $response = $check_license_res;
367 $response['html'] = $is_activating_single_license && empty( $check_license_res['is_all_access_pass'] )
368 ? Give_License::html_by_plugin( Give_License::get_plugin_by_slug( $check_license_res['plugin_slug'] ) )
369 : Give_License::render_licenses_list();
370
371 // Return error if license activation is not success and admin is reactivating add-on.
372 if ( $is_reactivating_license && ! $activate_license_res['success'] ) {
373
374 $response['errorMsg'] = sprintf(
375 __( 'The license failed to activate, due to a status of <code>%2$s</code>. Check the logs at Donations > Tools > Logs for more detail, and <a href="%1$s" target="_blank">reach out to the Customer Success team.</a>', 'give' ),
376 Give_License::get_account_url(),
377 $check_license_res['license']
378 );
379
380 wp_send_json_error( $response );
381 }
382
383 // Tell WordPress to look for updates.
384 give_refresh_licenses();
385
386 wp_send_json_success( $response );
387 }
388
389 add_action( 'wp_ajax_give_get_license_info', 'give_get_license_info_handler' );
390
391
392 /**
393 * Activate addon handler
394 *
395 * Note: only for internal use
396 *
397 * @since 4.16.6 Guard against empty or invalid plugin paths that previously bypassed
398 * the nonce and capability checks.
399 * @since 2.5.0
400 */
401 function give_activate_addon_handler() {
402 $plugin_path = give_clean( $_POST['plugin'] );
403
404 check_admin_referer( "give_activate-{$plugin_path}" );
405
406 // check user permission.
407 if ( ! current_user_can( 'manage_give_settings' ) ) {
408 give_die();
409 }
410
411 if ( empty( $plugin_path ) ) {
412 wp_send_json_error(
413 [
414 'errorMsg' => __( 'No plugin path was provided. The uploaded plugin may not have been detected correctly.', 'give' ),
415 ]
416 );
417 }
418
419 $plugin_file = WP_PLUGIN_DIR . '/' . $plugin_path;
420
421 if ( ! file_exists( $plugin_file ) ) {
422 wp_send_json_error(
423 [
424 'errorMsg' => sprintf(
425 /* translators: %1$s: plugin file path */
426 __( 'The plugin file "%1$s" could not be found. The add-on may not have been extracted correctly.', 'give' ),
427 esc_html( $plugin_path )
428 ),
429 ]
430 );
431 }
432
433 $plugin_data = get_plugin_data( $plugin_file );
434
435 if ( empty( $plugin_data['Name'] ) ) {
436 wp_send_json_error(
437 [
438 'errorMsg' => sprintf(
439 /* translators: %1$s: plugin file path */
440 __( 'The plugin "%1$s" does not have a valid plugin header. The add-on may be corrupted or incompatible.', 'give' ),
441 esc_html( $plugin_path )
442 ),
443 ]
444 );
445 }
446
447 $status = activate_plugin( $plugin_path );
448
449 if ( is_wp_error( $status ) ) {
450 wp_send_json_error( [ 'errorMsg' => $status->get_error_message() ] );
451 }
452
453 // Tell WordPress to look for updates.
454 give_refresh_licenses();
455
456 wp_send_json_success(
457 [
458 'licenseSectionHtml' => Give_License::render_licenses_list(),
459 ]
460 );
461 }
462
463 add_action( 'wp_ajax_give_activate_addon', 'give_activate_addon_handler' );
464
465
466 /**
467 * deactivate addon handler
468 *
469 * Note: only for internal use
470 *
471 * @since 2.5.0
472 */
473 function give_deactivate_license_handler() {
474 $license = give_clean( $_POST['license'] );
475 $item_name = give_clean( $_POST['item_name'] );
476 $plugin_dirname = give_clean( $_POST['plugin_dirname'] );
477
478 if ( ! $license || ! $item_name ) {
479 wp_send_json_error();
480 }
481
482 check_admin_referer( "give-deactivate-license-{$item_name}" );
483
484 // check user permission.
485 if ( ! current_user_can( 'manage_give_settings' ) ) {
486 give_die();
487 }
488
489 $give_licenses = get_option( 'give_licenses', [] );
490
491 if ( empty( $give_licenses[ $license ] ) ) {
492 wp_send_json_error(
493 [
494 'errorMsg' => __( 'License is invalid, so it can\'t be deactivated.', 'give' ),
495 ]
496 );
497 }
498
499 /* @var array|WP_Error $response */
500 $response = Give_License::request_license_api(
501 [
502 'edd_action' => 'deactivate_license',
503 'license' => $license,
504 'item_name' => $item_name,
505 ],
506 true
507 );
508
509 if ( is_wp_error( $response ) ) {
510 wp_send_json_error(
511 [
512 'errorMsg' => $response->get_error_message(),
513 'response' => $license,
514 ]
515 );
516 }
517
518 $is_all_access_pass = $give_licenses[ $license ]['is_all_access_pass'];
519
520 if ( ! empty( $give_licenses[ $license ] ) ) {
521 unset( $give_licenses[ $license ] );
522 update_option( 'give_licenses', $give_licenses );
523 }
524
525 $response['html'] = $is_all_access_pass
526 ? Give_License::render_licenses_list()
527 : Give_License::html_by_plugin( Give_License::get_plugin_by_slug( $plugin_dirname ) );
528
529 $response['msg'] = __( 'You have successfully deactivated the license.', 'give' );
530
531 // Tell WordPress to look for updates.
532 give_refresh_licenses();
533
534 wp_send_json_success( $response );
535 }
536
537 add_action( 'wp_ajax_give_deactivate_license', 'give_deactivate_license_handler' );
538
539
540 /**
541 * Refresh all addons licenses handler
542 *
543 * Note: only for internal use
544 *
545 * @since 2.5.0
546 */
547 function give_refresh_all_licenses_handler() {
548 check_admin_referer( 'give-refresh-all-licenses' );
549
550 // check user permission.
551 if ( ! current_user_can( 'manage_give_settings' ) ) {
552 give_die();
553 }
554
555 $data = Give_License::refresh_license_status();
556
557 // Update date and reset counter.
558 if ( $data['compare'] === date( 'Ymd' ) && 5 <= $data['count'] ) {
559 wp_send_json_error();
560 }
561
562 // Update date and reset counter.
563 if ( $data['compare'] < date( 'Ymd' ) ) {
564 $data['compare'] = date( 'Ymd' );
565 $data['count'] = 0;
566 }
567
568 // Update time.
569 $data['time'] = time();
570
571 ++ $data['count'];
572
573 update_option( 'give_licenses_refreshed_last_checked', $data, 'no' );
574
575 give_refresh_licenses();
576
577 $local_date = strtotime( get_date_from_gmt( date( 'Y-m-d H:i:s', $data['time'] ) ) );
578 wp_send_json_success(
579 [
580 'html' => Give_License::render_licenses_list(),
581 'refreshButton' => 5 <= $data['count'],
582 'refreshStatus' => $data,
583 'lastUpdateMsg' => sprintf(
584 __( 'Last refreshed on %1$s at %2$s', 'give' ),
585 date( give_date_format(), $local_date ),
586 date( 'g:i a', $local_date )
587 ),
588 ]
589 );
590 }
591
592 add_action( 'wp_ajax_give_refresh_all_licenses', 'give_refresh_all_licenses_handler' );
593
594
595 /**
596 * Updates information on the "View version x.x details" page with custom data.
597 * Note: only for internal use
598 *
599 * @param mixed $_data
600 * @param string $_action
601 * @param object $_args
602 *
603 * @return object $_data
604 * @since 2.5.0
605 * @uses api_request()
606 */
607 function give_plugins_api_filter( $_data, $_action = '', $_args = null ) {
608 // Exit.
609 if ( 'plugin_information' !== $_action ) {
610 return $_data;
611 }
612
613 $plugin = Give_License::get_plugin_by_slug( $_args->slug );
614
615 if (
616 ! $plugin
617 || 'add-on' !== $plugin['Type']
618 || false === strpos( $_args->slug, 'give-' )
619 ) {
620 return $_data;
621 }
622
623 $plugin_data = get_site_transient( 'update_plugins' );
624
625 if ( ! $plugin_data ) {
626 give_refresh_licenses();
627 }
628
629 $plugin_data = ! empty( $plugin_data->response[ $plugin['Path'] ] )
630 ? $plugin_data->response[ $plugin['Path'] ]
631 : [];
632
633 if ( ! $plugin_data ) {
634 return $_data;
635 }
636
637 $_data = $plugin_data;
638
639 return $_data;
640 }
641
642 add_filter( 'plugins_api', 'give_plugins_api_filter', 9999, 3 );
643
644
645 /**
646 * Check add-ons updates when WordPress check plugin updates
647 *
648 * @since 2.5.0
649 */
650 add_filter( 'pre_set_site_transient_update_plugins', 'give_check_addon_updates', 999, 1 );
651
652
653 /**
654 * Show plugin update notification on multi-site
655 *
656 * @param string $file
657 * @param array $plugin
658 *
659 * @since 2.5.0
660 */
661 function give_show_update_notification_on_multisite( $file, $plugin ) {
662 if ( is_network_admin() ) {
663 return;
664 }
665
666 if ( ! current_user_can( 'update_plugins' ) ) {
667 return;
668 }
669
670 if ( ! is_multisite() ) {
671 return;
672 }
673
674 if (
675 ! $plugin
676 || empty( $plugin['slug'] )
677 || false === strpos( $plugin['slug'], 'give-' )
678 ) {
679 return;
680 }
681
682 $plugin_data = Give_License::get_plugin_by_slug( $plugin['slug'] );
683
684 // Only show notices for Give add-ons
685 if ( 'add-on' !== $plugin_data['Type'] ) {
686 return;
687 }
688
689 // Do not print any message if updates does not exist.
690 $update_cache = get_site_transient( 'update_plugins' );
691
692 if ( ! isset( $update_cache->response[ $file ] ) ) {
693 return;
694 }
695
696 if ( ! empty( $update_cache->response[ $plugin_data['Path'] ] ) && version_compare( $plugin_data['Version'], $plugin['new_version'], '<' ) ) {
697 printf(
698 '<tr class="plugin-update-tr %3$s" id="%1$s-update" data-slug="%1$s" data-plugin="%2$s">',
699 $plugin['slug'],
700 $file,
701 'active' === $plugin_data['Status'] ? 'active' : 'inactive'
702 );
703
704 echo '<td colspan="3" class="plugin-update colspanchange">';
705 echo '<div class="update-message notice inline notice-warning notice-alt"><p>';
706
707 $changelog_link = self_admin_url( "plugin-install.php?tab=plugin-information&plugin={$plugin['slug']}&section=changelog&TB_iframe=true&width=772&height=299" );
708
709 if ( empty( $plugin['download_link'] ) ) {
710 printf(
711 __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s.', 'give' ),
712 esc_html( $plugin_data['Name'] ),
713 '<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
714 esc_html( $plugin['new_version'] ),
715 '</a>'
716 );
717 } else {
718 printf(
719 __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s or %5$supdate now%6$s.', 'give' ),
720 esc_html( $plugin_data['Name'] ),
721 '<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
722 esc_html( $plugin['new_version'] ),
723 '</a>',
724 '<a target="_blank" class="update-link" href="' . esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $file, 'upgrade-plugin_' . $file ) ) . '">',
725 '</a>'
726 );
727 }
728
729 do_action( "in_plugin_update_message-{$file}", $plugin, $plugin );
730
731 echo '</p></div></td></tr>';
732 }
733 }
734
735 add_action( 'after_plugin_row', 'give_show_update_notification_on_multisite', 10, 2 );
736
737 /**
738 * Show plugin update notification on single site
739 *
740 * @param $file
741 * @param $plugin
742 *
743 * @since 2.5.0
744 * @since 2.10.2 update condition to verify givewp addons
745 */
746 function give_show_update_notification_on_single_site( $file, $plugin ) {
747 if ( ! current_user_can( 'update_plugins' ) || is_multisite() ) {
748 return;
749 }
750
751 if (
752 ! $plugin
753 || empty( $plugin['slug'] )
754 || false === strpos( $plugin['slug'], 'give-' )
755 ) {
756 return;
757 }
758
759 $plugin_data = Give_License::get_plugin_by_slug( $plugin['slug'] );
760
761 // Only show notices for Give add-ons
762 if (
763 ! $plugin_data
764 || 'add-on' !== $plugin_data['Type']
765 || $plugin_data['License']
766 ) {
767 return;
768 }
769
770 // Do not print any message if updates does not exist.
771 $update_plugins = get_site_transient( 'update_plugins' );
772 if ( ! isset( $update_plugins->response[ $file ] ) ) {
773 return;
774 }
775
776 // Remove core update notice.
777 remove_action( "after_plugin_row_{$file}", 'wp_plugin_update_row' );
778
779 $update_notice_wrap = '<tr class="plugin-update-tr %3$s"><td colspan="3" class="colspanchange"><div class="update-message notice inline notice-warning notice-alt give-invalid-license"><p>%1$s %2$s</p></div></td></tr>';
780 $changelog_link = self_admin_url( "plugin-install.php?tab=plugin-information&plugin={$plugin['slug']}&section=changelog&TB_iframe=true&width=772&height=299" );
781
782 echo sprintf(
783 $update_notice_wrap,
784 sprintf(
785 __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s.', 'give' ),
786 esc_html( $plugin_data['Name'] ),
787 '<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
788 esc_html( $plugin['new_version'] ),
789 '</a>'
790 ),
791 sprintf(
792 'Please <a href="%1$s" target="_blank">activate your license</a> to receive updates and support.',
793 esc_url( admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' ) )
794 ),
795 'active' === $plugin_data['Status'] ? 'active' : 'inactive'
796 );
797 }
798
799 add_action( 'after_plugin_row', 'give_show_update_notification_on_single_site', 1, 2 );
800
801 /**
802 * Look for Give core add-ons update when someone manually presses the "Check Again" button within WP's Dashboard > Updates
803 *
804 * @since 2.5.11
805 */
806 function give_refresh_license_on_force_check() {
807 if ( isset( $_GET['force-check'] ) ) {
808 give_refresh_licenses();
809 }
810 }
811 add_action( 'load-update-core.php', 'give_refresh_license_on_force_check', 9 );
812
813
814