PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.16.6
GiveWP – Donation Plugin and Fundraising Platform v4.16.6
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
793 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 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Ajax addon upload handler
19 *
20 * Note: only for internal use
21 *
22 * @since 4.16.6 Use Plugin_Upgrader to install/update the add-on, replacing unreliable
23 * filename-based pre-existing checks and post-install detection.
24 * @since 2.5.0
25 */
26 function give_upload_addon_handler() {
27 if ( ! isset( $_FILES['file']['name'] ) ) {
28 wp_send_json_error( [ 'errorMsg' => __( 'No file was uploaded.', 'give' ) ] );
29 }
30
31 if ( UPLOAD_ERR_OK !== $_FILES['file']['error'] ) {
32 wp_send_json_error( [ 'errorMsg' => __( 'The file upload failed. Please try again.', 'give' ) ] );
33 }
34
35 check_admin_referer( 'give-upload-addon' );
36
37 if ( ! current_user_can( 'upload_plugins' ) ) {
38 wp_send_json_error( [ 'errorMsg' => __( 'The current user does not have permission to upload plugins on this site.', 'give' ) ] );
39 }
40
41 $access_type = get_filesystem_method();
42
43 if ( 'direct' !== $access_type ) {
44 wp_send_json_error(
45 [
46 'errorMsg' => sprintf(
47 __( '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' ),
48 esc_url( admin_url( 'plugin-install.php?tab=upload' ) )
49 ),
50 ]
51 );
52 }
53
54 $file_type = wp_check_filetype( $_FILES['file']['name'], [ 'zip' => 'application/zip' ] );
55
56 if ( empty( $file_type['ext'] ) ) {
57 wp_send_json_error( [ 'errorMsg' => __( 'Uploaded add-ons must be (zipped) ZIP files. Upload a valid add-on ZIP.', 'give' ) ] );
58 }
59
60 // Snapshot existing Give add-ons for diff after installation.
61 $pre_addons_list = give_get_plugins( [ 'only_add_on' => true ] );
62
63 // Detect the plugin folder name from the ZIP to check for an existing installation.
64 $zip_folder = give_get_zip_plugin_folder( $_FILES['file']['tmp_name'] );
65
66 if ( ! empty( $zip_folder ) && ! empty( $pre_addons_list ) ) {
67 foreach ( $pre_addons_list as $addon_path => $addon_data ) {
68 if ( strpos( $addon_path, $zip_folder . '/' ) === 0 ) {
69 wp_send_json_error(
70 [
71 'errorMsg' => __( 'This add-on is already installed.', 'give' ),
72 'pluginInfo' => $addon_data,
73 ]
74 );
75 }
76 }
77 }
78
79 // Install the plugin using the WordPress upgrader.
80 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
81 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
82 require_once ABSPATH . 'wp-admin/includes/class-automatic-upgrader-skin.php';
83 require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
84 require_once ABSPATH . 'wp-admin/includes/plugin.php';
85
86 $skin = new Automatic_Upgrader_Skin();
87 $upgrader = new Plugin_Upgrader( $skin );
88
89 $buffer_level = ob_get_level();
90
91 $result = $upgrader->install( $_FILES['file']['tmp_name'] );
92
93 while ( ob_get_level() > $buffer_level ) {
94 // A non-removable buffer, such as zlib, would loop until the request times out.
95 if ( ! @ob_end_clean() ) {
96 break;
97 }
98 }
99
100 if ( is_wp_error( $result ) ) {
101 wp_send_json_error( [ 'errorMsg' => $result->get_error_message() ] );
102 }
103
104 if ( ! $result ) {
105 $error_message = is_wp_error( $skin->result )
106 ? $skin->result->get_error_message()
107 : __( 'The add-on could not be installed. Please try again or upload it manually.', 'give' );
108
109 wp_send_json_error( [ 'errorMsg' => $error_message ] );
110 }
111
112 // Refresh the plugin cache and find the newly installed or updated plugin.
113 wp_clean_plugins_cache( true );
114
115 $post_addons_list = give_get_plugins( [ 'only_add_on' => true ] );
116 $new_plugins = array_diff_key( $post_addons_list, $pre_addons_list );
117
118 $installed_addon = [];
119
120 if ( ! empty( $new_plugins ) ) {
121 $new_plugin_path = array_key_first( $new_plugins );
122 $installed_addon = $new_plugins[ $new_plugin_path ];
123 $installed_addon['path'] = $new_plugin_path;
124 }
125
126 if ( empty( $installed_addon ) ) {
127 wp_send_json_error(
128 [
129 'errorMsg' => sprintf(
130 /* translators: %1$s: URL to the plugins page */
131 __( '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' ),
132 esc_url( admin_url( 'plugins.php' ) )
133 ),
134 ]
135 );
136 }
137
138 wp_send_json_success(
139 [
140 'pluginPath' => $installed_addon['path'],
141 'pluginName' => $installed_addon['Name'],
142 'nonce' => wp_create_nonce( "give_activate-{$installed_addon['path']}" ),
143 'licenseSectionHtml' => Give_License::render_licenses_list(),
144 ]
145 );
146 }
147
148 /**
149 * Reads the top-level directory name from a plugin ZIP file.
150 *
151 * Returns the single top-level directory name inside the ZIP (e.g. "give-recurring").
152 * Returns an empty string if the ZIP can't be read or contains multiple top-level items.
153 *
154 * @since 4.16.6
155 *
156 * @param string $zip_file Absolute path to the ZIP file.
157 *
158 * @return string Plugin folder name, or empty string on failure.
159 */
160 function give_get_zip_plugin_folder( $zip_file ) {
161 if ( ! file_exists( $zip_file ) || ! class_exists( 'ZipArchive' ) ) {
162 return '';
163 }
164
165 $zip = new ZipArchive();
166
167 if ( true !== $zip->open( $zip_file ) ) {
168 return '';
169 }
170
171 $folder = '';
172
173 for ( $i = 0; $i < $zip->numFiles; $i++ ) {
174 $entry = $zip->getNameIndex( $i );
175 $parts = explode( '/', $entry );
176
177 // Skip macOS metadata folders.
178 if ( isset( $parts[0] ) && '__MACOSX' === $parts[0] ) {
179 continue;
180 }
181
182 if ( count( $parts ) > 1 && '' !== $parts[0] ) {
183 if ( '' === $folder ) {
184 $folder = $parts[0];
185 } elseif ( $folder !== $parts[0] ) {
186 // Multiple top-level directories — ambiguous.
187 $folder = '';
188 break;
189 }
190 }
191 }
192
193 $zip->close();
194
195 return $folder;
196 }
197
198 add_action( 'wp_ajax_give_upload_addon', 'give_upload_addon_handler' );
199
200 /**
201 * Ajax license inquiry handler
202 *
203 * Note: only for internal use
204 *
205 * @since 2.5.0
206 */
207 function give_get_license_info_handler() {
208 check_admin_referer( 'give-license-activator-nonce' );
209
210 // check user permission.
211 if ( ! current_user_can( 'manage_give_settings' ) ) {
212 give_die();
213 }
214
215 $license_key = ! empty( $_POST['license'] ) ? give_clean( $_POST['license'] ) : '';
216 $is_activating_single_license = ! empty( $_POST['single'] ) ? absint( $_POST['single'] ) : '';
217 $is_reactivating_license = ! empty( $_POST['reactivate'] ) ? absint( $_POST['reactivate'] ) : '';
218 $plugin_slug = $is_activating_single_license ? give_clean( $_POST['addon'] ) : '';
219 $licenses = get_option( 'give_licenses', [] );
220
221 if ( ! $license_key ) {
222 wp_send_json_error(
223 [
224 'errorMsg' => __( 'You entered an invalid key. Confirm your license key on your GiveWP dashboard and try again.', 'give' ),
225 ]
226 );
227
228 } elseif (
229 ! $is_reactivating_license
230 && array_key_exists( $license_key, $licenses )
231 ) {
232 // If admin already activated license but did not install add-on then send license info show notice to admin with download link.
233 $license = $licenses[ $license_key ];
234 if ( empty( $license['is_all_access_pass'] ) ) {
235 $plugin_data = Give_License::get_plugin_by_slug( $license['plugin_slug'] );
236
237 // Plugin license activated but does not install, sent notice which allow admin to download add-on.
238 if ( empty( $plugin_data ) ) {
239 wp_send_json_success( $license );
240 }
241 }
242
243 wp_send_json_error(
244 [
245 'errorMsg' => __( 'This license key is already in use on this website.', 'give' ),
246 ]
247 );
248 }
249
250 // Check license.
251 $check_license_res = Give_License::request_license_api(
252 [
253 'edd_action' => 'check_license',
254 'license' => $license_key,
255 ],
256 true
257 );
258
259 // Make sure there are no errors.
260 if ( is_wp_error( $check_license_res ) ) {
261 wp_send_json_error(
262 [
263 'errorMsg' => $check_license_res->get_error_message(),
264 ]
265 );
266 }
267
268 // Check if license valid or not.
269 if ( ! $check_license_res['success'] ) {
270 wp_send_json_error(
271 [
272 'errorMsg' => sprintf(
273 __( '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' ),
274 Give_License::get_account_url(),
275 $check_license_res['license']
276 ),
277 ]
278 );
279 }
280
281 if (
282 $is_activating_single_license
283 && ! empty( $check_license_res['plugin_slug'] )
284 && $plugin_slug !== $check_license_res['plugin_slug']
285 ) {
286 wp_send_json_error(
287 [
288 'errorMsg' => sprintf(
289 __( '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' ),
290 Give_License::get_account_url()
291 ),
292 ]
293 );
294 }
295
296 // Activate license.
297 $activate_license_res = Give_License::request_license_api(
298 [
299 'edd_action' => 'activate_license',
300 'item_name' => $check_license_res['item_name'],
301 'license' => $license_key,
302 ],
303 true
304 );
305
306 if ( is_wp_error( $activate_license_res ) ) {
307 wp_send_json_error(
308 [
309 'errorMsg' => $check_license_res->get_error_message(),
310 ]
311 );
312 }
313
314 // Return error if license activation is not success and admin is not reactivating add-on.
315 if ( ! $is_reactivating_license && ! $activate_license_res['success'] ) {
316
317 $response['errorMsg'] = sprintf(
318 __( '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' ),
319 Give_License::get_account_url(),
320 $check_license_res['license']
321 );
322
323 wp_send_json_error( $response );
324 }
325
326 $check_license_res['license'] = $activate_license_res['license'];
327 $check_license_res['site_count'] = $activate_license_res['site_count'];
328 $check_license_res['activations_left'] = $activate_license_res['activations_left'];
329
330 // Remove single license which is part of all access pass or already existed all access pass key because admin can only one active.
331 // @see https://github.com/impress-org/givewp/issues/4669
332 if ( ! empty( $check_license_res['is_all_access_pass'] ) ) {
333 $addonSlugs = Give_License::getAddonSlugsFromAllAccessPassLicense( $check_license_res );
334 foreach ( $licenses as $license_key => $data ) {
335 if ( in_array( $data['plugin_slug'], $addonSlugs, true ) || ! empty( $data['is_all_access_pass'] ) ) {
336 unset( $licenses[ $license_key ] );
337 }
338 }
339 }
340
341 $licenses[ $check_license_res['license_key'] ] = $check_license_res;
342 update_option( 'give_licenses', $licenses );
343
344 // Get license section HTML.
345 $response = $check_license_res;
346 $response['html'] = $is_activating_single_license && empty( $check_license_res['is_all_access_pass'] )
347 ? Give_License::html_by_plugin( Give_License::get_plugin_by_slug( $check_license_res['plugin_slug'] ) )
348 : Give_License::render_licenses_list();
349
350 // Return error if license activation is not success and admin is reactivating add-on.
351 if ( $is_reactivating_license && ! $activate_license_res['success'] ) {
352
353 $response['errorMsg'] = sprintf(
354 __( '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' ),
355 Give_License::get_account_url(),
356 $check_license_res['license']
357 );
358
359 wp_send_json_error( $response );
360 }
361
362 // Tell WordPress to look for updates.
363 give_refresh_licenses();
364
365 wp_send_json_success( $response );
366 }
367
368 add_action( 'wp_ajax_give_get_license_info', 'give_get_license_info_handler' );
369
370
371 /**
372 * Activate addon handler
373 *
374 * Note: only for internal use
375 *
376 * @since 4.16.6 Guard against empty or invalid plugin paths that previously bypassed
377 * the nonce and capability checks.
378 * @since 2.5.0
379 */
380 function give_activate_addon_handler() {
381 $plugin_path = give_clean( $_POST['plugin'] );
382
383 check_admin_referer( "give_activate-{$plugin_path}" );
384
385 // check user permission.
386 if ( ! current_user_can( 'manage_give_settings' ) ) {
387 give_die();
388 }
389
390 if ( empty( $plugin_path ) ) {
391 wp_send_json_error(
392 [
393 'errorMsg' => __( 'No plugin path was provided. The uploaded plugin may not have been detected correctly.', 'give' ),
394 ]
395 );
396 }
397
398 $plugin_file = WP_PLUGIN_DIR . '/' . $plugin_path;
399
400 if ( ! file_exists( $plugin_file ) ) {
401 wp_send_json_error(
402 [
403 'errorMsg' => sprintf(
404 /* translators: %1$s: plugin file path */
405 __( 'The plugin file "%1$s" could not be found. The add-on may not have been extracted correctly.', 'give' ),
406 esc_html( $plugin_path )
407 ),
408 ]
409 );
410 }
411
412 $plugin_data = get_plugin_data( $plugin_file );
413
414 if ( empty( $plugin_data['Name'] ) ) {
415 wp_send_json_error(
416 [
417 'errorMsg' => sprintf(
418 /* translators: %1$s: plugin file path */
419 __( 'The plugin "%1$s" does not have a valid plugin header. The add-on may be corrupted or incompatible.', 'give' ),
420 esc_html( $plugin_path )
421 ),
422 ]
423 );
424 }
425
426 $status = activate_plugin( $plugin_path );
427
428 if ( is_wp_error( $status ) ) {
429 wp_send_json_error( [ 'errorMsg' => $status->get_error_message() ] );
430 }
431
432 // Tell WordPress to look for updates.
433 give_refresh_licenses();
434
435 wp_send_json_success(
436 [
437 'licenseSectionHtml' => Give_License::render_licenses_list(),
438 ]
439 );
440 }
441
442 add_action( 'wp_ajax_give_activate_addon', 'give_activate_addon_handler' );
443
444
445 /**
446 * deactivate addon handler
447 *
448 * Note: only for internal use
449 *
450 * @since 2.5.0
451 */
452 function give_deactivate_license_handler() {
453 $license = give_clean( $_POST['license'] );
454 $item_name = give_clean( $_POST['item_name'] );
455 $plugin_dirname = give_clean( $_POST['plugin_dirname'] );
456
457 if ( ! $license || ! $item_name ) {
458 wp_send_json_error();
459 }
460
461 check_admin_referer( "give-deactivate-license-{$item_name}" );
462
463 // check user permission.
464 if ( ! current_user_can( 'manage_give_settings' ) ) {
465 give_die();
466 }
467
468 $give_licenses = get_option( 'give_licenses', [] );
469
470 if ( empty( $give_licenses[ $license ] ) ) {
471 wp_send_json_error(
472 [
473 'errorMsg' => __( 'License is invalid, so it can\'t be deactivated.', 'give' ),
474 ]
475 );
476 }
477
478 /* @var array|WP_Error $response */
479 $response = Give_License::request_license_api(
480 [
481 'edd_action' => 'deactivate_license',
482 'license' => $license,
483 'item_name' => $item_name,
484 ],
485 true
486 );
487
488 if ( is_wp_error( $response ) ) {
489 wp_send_json_error(
490 [
491 'errorMsg' => $response->get_error_message(),
492 'response' => $license,
493 ]
494 );
495 }
496
497 $is_all_access_pass = $give_licenses[ $license ]['is_all_access_pass'];
498
499 if ( ! empty( $give_licenses[ $license ] ) ) {
500 unset( $give_licenses[ $license ] );
501 update_option( 'give_licenses', $give_licenses );
502 }
503
504 $response['html'] = $is_all_access_pass
505 ? Give_License::render_licenses_list()
506 : Give_License::html_by_plugin( Give_License::get_plugin_by_slug( $plugin_dirname ) );
507
508 $response['msg'] = __( 'You have successfully deactivated the license.', 'give' );
509
510 // Tell WordPress to look for updates.
511 give_refresh_licenses();
512
513 wp_send_json_success( $response );
514 }
515
516 add_action( 'wp_ajax_give_deactivate_license', 'give_deactivate_license_handler' );
517
518
519 /**
520 * Refresh all addons licenses handler
521 *
522 * Note: only for internal use
523 *
524 * @since 2.5.0
525 */
526 function give_refresh_all_licenses_handler() {
527 check_admin_referer( 'give-refresh-all-licenses' );
528
529 // check user permission.
530 if ( ! current_user_can( 'manage_give_settings' ) ) {
531 give_die();
532 }
533
534 $data = Give_License::refresh_license_status();
535
536 // Update date and reset counter.
537 if ( $data['compare'] === date( 'Ymd' ) && 5 <= $data['count'] ) {
538 wp_send_json_error();
539 }
540
541 // Update date and reset counter.
542 if ( $data['compare'] < date( 'Ymd' ) ) {
543 $data['compare'] = date( 'Ymd' );
544 $data['count'] = 0;
545 }
546
547 // Update time.
548 $data['time'] = time();
549
550 ++ $data['count'];
551
552 update_option( 'give_licenses_refreshed_last_checked', $data, 'no' );
553
554 give_refresh_licenses();
555
556 $local_date = strtotime( get_date_from_gmt( date( 'Y-m-d H:i:s', $data['time'] ) ) );
557 wp_send_json_success(
558 [
559 'html' => Give_License::render_licenses_list(),
560 'refreshButton' => 5 <= $data['count'],
561 'refreshStatus' => $data,
562 'lastUpdateMsg' => sprintf(
563 __( 'Last refreshed on %1$s at %2$s', 'give' ),
564 date( give_date_format(), $local_date ),
565 date( 'g:i a', $local_date )
566 ),
567 ]
568 );
569 }
570
571 add_action( 'wp_ajax_give_refresh_all_licenses', 'give_refresh_all_licenses_handler' );
572
573
574 /**
575 * Updates information on the "View version x.x details" page with custom data.
576 * Note: only for internal use
577 *
578 * @param mixed $_data
579 * @param string $_action
580 * @param object $_args
581 *
582 * @return object $_data
583 * @since 2.5.0
584 * @uses api_request()
585 */
586 function give_plugins_api_filter( $_data, $_action = '', $_args = null ) {
587 // Exit.
588 if ( 'plugin_information' !== $_action ) {
589 return $_data;
590 }
591
592 $plugin = Give_License::get_plugin_by_slug( $_args->slug );
593
594 if (
595 ! $plugin
596 || 'add-on' !== $plugin['Type']
597 || false === strpos( $_args->slug, 'give-' )
598 ) {
599 return $_data;
600 }
601
602 $plugin_data = get_site_transient( 'update_plugins' );
603
604 if ( ! $plugin_data ) {
605 give_refresh_licenses();
606 }
607
608 $plugin_data = ! empty( $plugin_data->response[ $plugin['Path'] ] )
609 ? $plugin_data->response[ $plugin['Path'] ]
610 : [];
611
612 if ( ! $plugin_data ) {
613 return $_data;
614 }
615
616 $_data = $plugin_data;
617
618 return $_data;
619 }
620
621 add_filter( 'plugins_api', 'give_plugins_api_filter', 9999, 3 );
622
623
624 /**
625 * Check add-ons updates when WordPress check plugin updates
626 *
627 * @since 2.5.0
628 */
629 add_filter( 'pre_set_site_transient_update_plugins', 'give_check_addon_updates', 999, 1 );
630
631
632 /**
633 * Show plugin update notification on multi-site
634 *
635 * @param string $file
636 * @param array $plugin
637 *
638 * @since 2.5.0
639 */
640 function give_show_update_notification_on_multisite( $file, $plugin ) {
641 if ( is_network_admin() ) {
642 return;
643 }
644
645 if ( ! current_user_can( 'update_plugins' ) ) {
646 return;
647 }
648
649 if ( ! is_multisite() ) {
650 return;
651 }
652
653 if (
654 ! $plugin
655 || empty( $plugin['slug'] )
656 || false === strpos( $plugin['slug'], 'give-' )
657 ) {
658 return;
659 }
660
661 $plugin_data = Give_License::get_plugin_by_slug( $plugin['slug'] );
662
663 // Only show notices for Give add-ons
664 if ( 'add-on' !== $plugin_data['Type'] ) {
665 return;
666 }
667
668 // Do not print any message if updates does not exist.
669 $update_cache = get_site_transient( 'update_plugins' );
670
671 if ( ! isset( $update_cache->response[ $file ] ) ) {
672 return;
673 }
674
675 if ( ! empty( $update_cache->response[ $plugin_data['Path'] ] ) && version_compare( $plugin_data['Version'], $plugin['new_version'], '<' ) ) {
676 printf(
677 '<tr class="plugin-update-tr %3$s" id="%1$s-update" data-slug="%1$s" data-plugin="%2$s">',
678 $plugin['slug'],
679 $file,
680 'active' === $plugin_data['Status'] ? 'active' : 'inactive'
681 );
682
683 echo '<td colspan="3" class="plugin-update colspanchange">';
684 echo '<div class="update-message notice inline notice-warning notice-alt"><p>';
685
686 $changelog_link = self_admin_url( "plugin-install.php?tab=plugin-information&plugin={$plugin['slug']}&section=changelog&TB_iframe=true&width=772&height=299" );
687
688 if ( empty( $plugin['download_link'] ) ) {
689 printf(
690 __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s.', 'give' ),
691 esc_html( $plugin_data['Name'] ),
692 '<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
693 esc_html( $plugin['new_version'] ),
694 '</a>'
695 );
696 } else {
697 printf(
698 __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s or %5$supdate now%6$s.', 'give' ),
699 esc_html( $plugin_data['Name'] ),
700 '<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
701 esc_html( $plugin['new_version'] ),
702 '</a>',
703 '<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 ) ) . '">',
704 '</a>'
705 );
706 }
707
708 do_action( "in_plugin_update_message-{$file}", $plugin, $plugin );
709
710 echo '</p></div></td></tr>';
711 }
712 }
713
714 add_action( 'after_plugin_row', 'give_show_update_notification_on_multisite', 10, 2 );
715
716 /**
717 * Show plugin update notification on single site
718 *
719 * @param $file
720 * @param $plugin
721 *
722 * @since 2.5.0
723 * @since 2.10.2 update condition to verify givewp addons
724 */
725 function give_show_update_notification_on_single_site( $file, $plugin ) {
726 if ( ! current_user_can( 'update_plugins' ) || is_multisite() ) {
727 return;
728 }
729
730 if (
731 ! $plugin
732 || empty( $plugin['slug'] )
733 || false === strpos( $plugin['slug'], 'give-' )
734 ) {
735 return;
736 }
737
738 $plugin_data = Give_License::get_plugin_by_slug( $plugin['slug'] );
739
740 // Only show notices for Give add-ons
741 if (
742 ! $plugin_data
743 || 'add-on' !== $plugin_data['Type']
744 || $plugin_data['License']
745 ) {
746 return;
747 }
748
749 // Do not print any message if updates does not exist.
750 $update_plugins = get_site_transient( 'update_plugins' );
751 if ( ! isset( $update_plugins->response[ $file ] ) ) {
752 return;
753 }
754
755 // Remove core update notice.
756 remove_action( "after_plugin_row_{$file}", 'wp_plugin_update_row' );
757
758 $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>';
759 $changelog_link = self_admin_url( "plugin-install.php?tab=plugin-information&plugin={$plugin['slug']}&section=changelog&TB_iframe=true&width=772&height=299" );
760
761 echo sprintf(
762 $update_notice_wrap,
763 sprintf(
764 __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s.', 'give' ),
765 esc_html( $plugin_data['Name'] ),
766 '<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
767 esc_html( $plugin['new_version'] ),
768 '</a>'
769 ),
770 sprintf(
771 'Please <a href="%1$s" target="_blank">activate your license</a> to receive updates and support.',
772 esc_url( admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' ) )
773 ),
774 'active' === $plugin_data['Status'] ? 'active' : 'inactive'
775 );
776 }
777
778 add_action( 'after_plugin_row', 'give_show_update_notification_on_single_site', 1, 2 );
779
780 /**
781 * Look for Give core add-ons update when someone manually presses the "Check Again" button within WP's Dashboard > Updates
782 *
783 * @since 2.5.11
784 */
785 function give_refresh_license_on_force_check() {
786 if ( isset( $_GET['force-check'] ) ) {
787 give_refresh_licenses();
788 }
789 }
790 add_action( 'load-update-core.php', 'give_refresh_license_on_force_check', 9 );
791
792
793