PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.7.0.12
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.7.0.12
1.8.13.1 1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 All 212 releases
charitable / includes / licensing / class-charitable-licenses.php

class-charitable-licenses.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.7.0.12, at includes/licensing/class-charitable-licenses.php

855 lines 23.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class to assist with the setup of extension licenses.
4 *
5 * @package Charitable/Classes/Charitable_Licenses
6 * @version 1.4.20
7 * @author David Bisset
8 * @copyright Copyright (c) 2022, WP Charitable LLC
9 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10 */
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 if ( ! class_exists( 'Charitable_Licenses' ) ) :
18
19 /**
20 * Charitable_Licenses
21 *
22 * @since 1.0.0
23 */
24 class Charitable_Licenses {
25
26 /* @var string */
27 const UPDATE_URL = 'https://wpcharitable.com';
28
29 /**
30 * The single instance of this class.
31 *
32 * @var Charitable_Licenses|null
33 */
34 private static $instance = null;
35
36 /**
37 * All the registered products requiring licensing.
38 *
39 * @var array
40 */
41 private $products;
42
43 /**
44 * All the stored licenses.
45 *
46 * @var array
47 */
48 private $licenses;
49
50 /**
51 * Cached update data.
52 *
53 * @var array
54 */
55 private $update_data;
56
57 /**
58 * Returns and/or create the single instance of this class.
59 *
60 * @since 1.2.0
61 *
62 * @return Charitable_Licenses
63 */
64 public static function get_instance() {
65 if ( is_null( self::$instance ) ) {
66 self::$instance = new self();
67 }
68
69 return self::$instance;
70 }
71
72 /**
73 * Create class object.
74 *
75 * @since 1.0.0
76 */
77 private function __construct() {
78 $this->products = array();
79 $this->update_data = array();
80
81 add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_for_updates' ) );
82 add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
83 add_action( 'charitable_deactivate_license', array( $this, 'deactivate_license' ) );
84
85 add_action( 'init', array( $this, 'ajax_license_check' ) );
86 add_action( 'wp_ajax_charitable_license_check', array( $this, 'ajax_license_check' ) );
87 }
88
89 /**
90 * Checks licenses (new and legacy) to see if any are valid.
91 *
92 * @since 1.7.0
93 *
94 * @return boolean
95 */
96 public function is_pro() {
97
98 $products = $this->get_products();
99
100 if ( is_multisite() ) {
101
102 // get the main blog id to check for license
103 $network = get_network();
104 if ( ! $network ) {
105 return 0;
106 }
107
108 $blog_id = $network->site_id;
109
110 switch_to_blog( $blog_id );
111
112 if ( $this->is_v3_license_valid() ) {
113 return true;
114 }
115
116 $licenses = charitable_get_option( 'licenses', array() );
117
118 // go through licenses - if there is at least ONE VALID ADDON LICNESE then it's pro.
119 foreach ( $licenses as $slug => $license ) {
120 if ( isset( $license['valid'] ) && 1 === intval( $license['valid'] ) ) {
121 restore_current_blog();
122 return true;
123 }
124 }
125
126 restore_current_blog();
127
128 } else {
129
130 if ( empty( $products ) ) {
131 return false;
132 }
133
134 if ( $this->is_v3_license_valid() ) {
135 return true;
136 }
137
138 // fallback: go through licenses - if there is at least ONE VALID ADDON LICNESE then it's pro.
139 foreach ( $products as $slug => $item ) {
140 $valid = $this->has_valid_license( $slug );
141 if ( $valid ) {
142 return true;
143 }
144 }
145 }
146 }
147
148 /**
149 * Checks the "v3" license (starting Nov 2022) to see if it's valid.
150 * If valid, normally doesn't require other license/pro checks.
151 *
152 * @since 1.7.0.4
153 *
154 * @return boolean
155 */
156 public function is_v3_license_valid() {
157
158 $settings = get_option( 'charitable_settings' );
159 if ( false === $settings || ! isset( $settings['licenses']['charitable-v2'] ) || ! isset( $settings['licenses']['charitable-v2'][ 'valid' ] ) ) {
160 return false;
161 }
162 $valid = $settings['licenses']['charitable-v2'][ 'valid' ];
163 if ( 1 === intval( $valid ) ) {
164 return true;
165 }
166
167 return false;
168
169 }
170
171 /**
172 * Checks for any Charitable extensions with updates.
173 *
174 * @since 1.4.0
175 *
176 * @param array $_transient_data The plugin updates data.
177 * @return array
178 */
179 public function check_for_updates( $_transient_data ) {
180 global $pagenow;
181
182 if ( ! is_object( $_transient_data ) ) {
183 $_transient_data = new stdClass;
184 }
185
186 if ( 'plugins.php' == $pagenow && is_multisite() ) {
187 return $_transient_data;
188 }
189
190 /* Loop over our licensed products and check whether any are missing transient data. */
191 $missing_data = array();
192
193 foreach ( $this->get_products() as $product ) {
194 if ( $this->is_missing_version_info( $product, $_transient_data ) ) {
195 $missing_data[] = $product;
196 }
197 }
198
199 /* If we are missing data for any of our products, check whether any have an update. */
200 if ( ! empty( $missing_data ) ) {
201
202 $versions = $this->get_versions();
203
204 unset( $versions['request_speed'] );
205
206 if ( ! empty( $versions ) ) {
207
208 $versions_name_lookup = wp_list_pluck( $versions, 'name' );
209
210 foreach ( $missing_data as $product ) {
211
212 if ( ! in_array( $product['name'], $versions_name_lookup ) ) {
213 continue;
214 }
215
216 $plugin_file = plugin_basename( $product['file'] );
217 $product_key = array_search( $product['name'], wp_list_pluck( $this->get_products(), 'name' ) );
218 $version_info = $versions[ array_search( $product['name'], $versions_name_lookup ) ];
219 $version_info['license'] = $this->get_license_details( $product_key );
220
221 if ( version_compare( $product['version'], $version_info['new_version'], '<' ) ) {
222
223 if ( isset( $version_info['sections'] ) ) {
224 $version_info['sections'] = maybe_unserialize( $version_info['sections'] );
225 }
226
227 $can_update = $this->able_to_update( $version_info );
228
229 if ( is_array( $can_update ) ) {
230 $version_info['package'] = $can_update['reason_code'];
231 $version_info['download_link'] = $can_update['reason_code'];
232 $version_info['package_download_restriction'] = $can_update['description'];
233 }
234
235 $_transient_data->response[ $plugin_file ] = (object) $version_info;
236 }
237
238 $_transient_data->last_checked = time();
239 $_transient_data->checked[ $plugin_file ] = $product['version'];
240
241 }//end foreach
242 }//end if
243 }//end if
244
245 return $_transient_data;
246 }
247
248 /**
249 * Updates information on the "View version x.x details" page with custom data.
250 *
251 * @uses api_request()
252 *
253 * @since 1.4.20
254 * @since 1.7.0.10
255 *
256 * @param mixed $_data Default set of data.
257 * @param string $_action The current action.
258 * @param object $_args Request args.
259 * @return object $_data
260 */
261 public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
262 if ( 'plugin_information' != $_action ) {
263 return $_data;
264 }
265
266 if ( ! isset( $_args->slug ) ) {
267 return $_data;
268 }
269
270 $plugin_key = str_replace( '-', '_', $_args->slug );
271
272 if ( 'charitable' === $plugin_key || ! array_key_exists( $plugin_key, $this->products ) ) {
273 return $_data;
274 }
275
276 $version_info = $this->get_version_info( plugin_basename( $this->products[ $plugin_key ]['file'] ) );
277
278 if ( $version_info ) {
279 $_data = $version_info;
280 }
281
282 return $_data;
283 }
284
285 /**
286 * Return whether a particular plugin is missing version info.
287 *
288 * @since 1.4.20
289 *
290 * @param array $product Product details array.
291 * @param false|object $update_cache Optional argument to pass update cache.
292 * @return boolean
293 */
294 public function is_missing_version_info( $product, $update_cache = false ) {
295 return ! $this->get_version_info( plugin_basename( $product['file'] ), $update_cache );
296 }
297
298 /**
299 * Return the version update info for a particular plugin.
300 *
301 * @since 1.4.20
302 *
303 * @param string $slug The plugin slug.
304 * @param false|object $update_cache Optional argument to pass update cache.
305 * @return array|false Array if an update is available. False otherwise.
306 */
307 public function get_version_info( $slug, $update_cache = false ) {
308 if ( ! $update_cache ) {
309 $update_cache = get_site_transient( 'update_plugins' );
310 }
311
312 if ( ! is_object( $update_cache ) || empty( $update_cache->response ) || ! array_key_exists( $slug, $update_cache->response ) ) {
313 return false;
314 }
315
316 return $update_cache->response[ $slug ];
317 }
318
319 /**
320 * Checks whether the given plugin can be updated.
321 *
322 * @since 1.6.14
323 *
324 * @param array $version_info Version information.
325 * @return true|array If it can be updated, returns true. Otherwise
326 * returns an array with a reason_code and description.
327 */
328 protected function able_to_update( $version_info ) {
329 $changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $version_info['name'] . '&slug=' . $version_info['slug'] . '&TB_iframe=true&width=772&height=911' );
330
331 switch ( $version_info['package'] ) {
332
333 case 'missing_license':
334 return array(
335 'reason_code' => 'missing_license',
336 'description' => sprintf(
337 __( '<p>There is a new version of %1$s available but you have not activated your license. <a target="_top" href="%2$s">Activate your license</a> or <a target="_blank" class="thickbox" href="%3$s">view version %4$s details</a>.</p>', 'charitable' ),
338 esc_html( $version_info['name'] ),
339 admin_url( 'admin.php?page=charitable-settings&tab=licenses' ),
340 esc_url( $changelog_link ),
341 esc_html( $version_info['new_version'] )
342 ),
343 );
344
345 case 'expired_license':
346 $base_renewal_url = isset( $version_info['renewal_link'] ) ? $version_info['renewal_link'] : 'https://www.wpcharitable.com/account';
347
348 return array(
349 'reason_code' => 'expired_license',
350 'description' => sprintf(
351 __( '<p>There is a new version of %1$s available but your license has expired. <a target="_blank" href="%2$s">Renew your license</a> or <a target="_blank" class="thickbox" href="%3$s">view version %4$s details</a>.</p>', 'charitable' ),
352 esc_html( $version_info['name'] ),
353 charitable_ga_url(
354 $base_renewal_url,
355 urlencode( 'Expired License Notice'),
356 urlencode( 'Renew your license' )
357 ),
358 esc_url( $changelog_link ),
359 esc_html( $version_info['new_version'] )
360 ),
361 );
362
363 default:
364 if ( ! isset( $version_info['requirements'] ) ) {
365 return true;
366 }
367
368 $messages = array();
369
370 foreach ( $version_info['requirements'] as $type => $details ) {
371
372 switch ( $type ) {
373 case 'php':
374 if ( version_compare( phpversion(), $details, '<' ) ) {
375 $messages[] = esc_html(
376 sprintf(
377 __( '<li>Requires PHP version %s or greater.</li>' ),
378 $details
379 )
380 );
381 }
382 break;
383
384 case 'charitable':
385 if ( version_compare( charitable()->get_version(), $details, '<' ) ) {
386 $messages[] = esc_html(
387 sprintf(
388 __( 'Requires Charitable version %s or greater.' ),
389 $details
390 )
391 );
392 }
393 break;
394 }
395
396 if ( empty( $messages ) ) {
397 return true;
398 }
399
400 return array(
401 'reason_code' => 'missing_requirements',
402 'description' => sprintf(
403 __( '<p>There is a new version of %1$s available but you are missing the following minimum requirements:</p>%2$s', 'charitable' ),
404 esc_html( $version_info['name'] ),
405 '<ul>' . implode( '<br/>', $messages ) . '</ul>'
406 ),
407 );
408 }
409
410 return true;
411 }
412 }
413
414 /**
415 * Return the package string for an expired license.
416 *
417 * @since 1.4.20
418 *
419 * @param string $plugin Plugin basename.
420 * @return string
421 */
422 public function get_expired_license_package( $plugin ) {
423 $version_info = $this->get_version_info( $plugin );
424 $base_renewal_url = isset( $version_info->renewal_link ) ? $version_info->renewal_link : 'https://www.wpcharitable.com/account';
425
426 return sprintf( 'expired_license:%s', charitable_ga_url(
427 $base_renewal_url,
428 urlencode( 'WordPress Dashboard'),
429 urlencode( 'Expired License' )
430 ));
431
432 }
433
434 /**
435 * Return the package string for a plugin missing requirements.
436 *
437 * @since 1.6.14
438 *
439 * @param string $plugin Plugin basename.
440 * @return string
441 */
442 public function get_missing_requirements_package( $plugin ) {
443 $version_info = $this->get_version_info( $plugin );
444
445 return sprintf(
446 'missing_requirements:%s',
447 $version_info->package_download_restriction
448 );
449 }
450
451 /**
452 * Register a product that requires licensing.
453 *
454 * @since 1.0.0
455 *
456 * @param string $item_name The title of the product.
457 * @param string $author The author of the product.
458 * @param string $version The current product version we have installed.
459 * @param string $file The path to the plugin file.
460 * @param string $url The base URL where the plugin is licensed. Defaults to Charitable_Licenses::UPDATE_URL.
461 * @return void
462 */
463 public function register_licensed_product( $item_name, $author, $version, $file, $url = false ) {
464 if ( ! $url ) {
465 $url = Charitable_Licenses::UPDATE_URL;
466 }
467
468 $product_key = $this->get_item_key( $item_name );
469
470 $this->products[ $product_key ] = array(
471 'name' => $item_name,
472 'author' => $author,
473 'version' => $version,
474 'url' => $url,
475 'file' => $file,
476 );
477
478 $licenses = $this->get_licenses();
479 $license = isset( $licenses[ $product_key ]['license'] ) ? trim( $licenses[ $product_key ]['license'] ) : '';
480
481 new Charitable_Plugin_Updater( $url, $file, array(
482 'version' => $version,
483 'license' => $license,
484 'item_name' => $item_name,
485 'author' => $author,
486 ) );
487
488 }
489
490 /**
491 * Return the list of products requiring licensing.
492 *
493 * @since 1.0.0
494 *
495 * @return array[]
496 */
497 public function get_products() {
498 return $this->products;
499 }
500
501 /**
502 * Return a specific product's details.
503 *
504 * @since 1.0.0
505 *
506 * @param string $item The item for which we are getting product details.
507 * @return string[]
508 */
509 public function get_product_license_details( $item ) {
510 return isset( $this->products[ $item ] ) ? $this->products[ $item ] : false;
511 }
512
513 /**
514 * Returns whether the given product has a valid license.
515 *
516 * @since 1.0.0
517 *
518 * @param string $item The item to check.
519 * @return boolean
520 */
521 public function has_valid_license( $item ) {
522 $license = $this->get_license_details( $item );
523
524 if ( ! $license || ! isset( $license['valid'] ) ) {
525 return false;
526 }
527
528 return $license['valid'];
529 }
530
531 /**
532 * Returns the license details for the given product.
533 *
534 * @since 1.0.0
535 *
536 * @param string $item The item to get the license for.
537 * @return mixed[]
538 */
539 public function get_license( $item ) {
540 $license = $this->get_license_details( $item );
541
542 if ( ! $license || ! is_array( $license ) ) {
543 return false;
544 }
545
546 return $license['license'];
547 }
548
549 /**
550 * Returns the active license details for the given product.
551 *
552 * @since 1.0.0
553 *
554 * @param string $item The item to get active licensing details for.
555 * @return mixed[]
556 */
557 public function get_license_details( $item ) {
558 $licenses = $this->get_licenses();
559
560 if ( ! isset( $licenses[ $item ] ) ) {
561 return false;
562 }
563
564 return $licenses[ $item ];
565 }
566
567 /**
568 * Return the list of licenses.
569 *
570 * Note: The licenses are not necessarily valid. If a user enters an invalid
571 * license, the license will be stored but it will be flagged as invalid.
572 *
573 * @since 1.0.0
574 *
575 * @return array[]
576 */
577 public function get_licenses() {
578 if ( ! isset( $this->licenses ) ) {
579 $this->licenses = charitable_get_option( 'licenses', array() );
580 }
581
582 return $this->licenses;
583 }
584
585 /**
586 * Verify a license.
587 *
588 * @since 1.0.0
589 *
590 * @param string $item The item to verify.
591 * @param string $license The license key for the item.
592 * @param boolean $force Whether to force the verification check.
593 * @return mixed[]
594 */
595 public function verify_license( $item, $license, $force = false, $legacy = false ) {
596
597 $license = trim( $license );
598
599 if ( $license === $this->get_license( $item ) && ! $force ) {
600 return $this->get_license_details( $item );
601 }
602
603 $product_details = $this->get_product_license_details( $item );
604
605 /* This product was not correctly registered. */
606 if ( ! $product_details ) {
607 return;
608 }
609
610 /* Data to send in our API request */
611 $api_params = array(
612 'edd_action' => 'activate_license',
613 'license' => $license,
614 'legacy' => $legacy,
615 'item_name' => urlencode( $product_details['name'] ),
616 'url' => home_url(),
617 );
618
619 /* Call the custom API */
620 $response = wp_remote_post(
621 $product_details['url'],
622 array(
623 'timeout' => 15,
624 'sslverify' => false,
625 'body' => $api_params,
626 )
627 );
628
629 if ( defined( 'CHARITABLE_DEBUG' ) && CHARITABLE_DEBUG ) {
630 error_log( print_r( $api_params, true ) );
631 error_log( print_r( $product_details, true ) );
632 error_log( print_r( $response, true ) );
633 }
634
635 /* Make sure the response came back okay */
636 if ( is_wp_error( $response ) ) {
637 return;
638 }
639
640 $this->flush_update_cache();
641
642 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
643
644 $comm_success = isset( $license_data ) && ! empty( $license_data ) ? true : false;
645
646 // if the license is not valid, attempt to discover why - in this case, maybe the activation limit was exceeded.
647
648 $license_limit = isset( $license_data->license_limit ) ? intval( $license_data->license_limit ) : false;
649 $site_count = isset( $license_data->site_count ) ? intval( $license_data->site_count ) : false;
650 $limit_exceeded = ( $license_limit > 0 && $site_count >= $license_limit ) ? true : false;
651
652 return array(
653 'license' => $license,
654 'expiration_date' => isset( $license_data->expires) ? $license_data->expires : false,
655 'plan_id' => isset( $license_data->price_id ) ? $license_data->price_id : false,
656 'valid' => ( isset( $license_data->license ) && 'valid' === $license_data->license ),
657 'license_limit' => $limit_exceeded,
658 'comm_success' => $comm_success,
659 );
660 }
661
662 /**
663 * Return the URL to deactivate a specific license.
664 *
665 * @since 1.0.0
666 *
667 * @param string $item The item to deactivate.
668 * @return string
669 */
670 public function get_license_deactivation_url( $item ) {
671 return esc_url( add_query_arg( array(
672 'charitable_action' => 'deactivate_license',
673 'product_key' => $item,
674 '_nonce' => wp_create_nonce( 'license' ),
675 ), admin_url( 'admin.php?page=charitable-settings&tab=advanced' ) ) );
676 }
677
678 /**
679 * Deactivate a license.
680 *
681 * @since 1.0.0
682 *
683 * @return void
684 */
685 public function deactivate_license() {
686 if ( ! wp_verify_nonce( $_REQUEST['_nonce'], 'license' ) ) {
687 wp_die( esc_attr__( 'Cheatin\' eh?!', 'charitable' ) );
688 }
689
690 $product_key = isset( $_REQUEST['product_key'] ) ? $_REQUEST['product_key'] : false;
691
692 /* Product key must be set */
693 if ( false === $product_key ) {
694 wp_die( esc_attr__( 'Missing product key', 'charitable' ) );
695 }
696
697 $product = $this->get_product_license_details( $product_key );
698
699 /* Make sure we have a valid product with a valid license. */
700 if ( ! $product || ! $this->has_valid_license( $product_key ) ) {
701 wp_die( esc_attr__( 'This product is not valid or does not have a valid license key.', 'charitable' ) );
702 }
703
704 $license = $this->get_license( $product_key );
705
706 /* Data to send to wpcharitable.com to deactivate the license. */
707 $api_params = array(
708 'edd_action' => 'deactivate_license',
709 'license' => $license,
710 'item_name' => urlencode( $product['name'] ),
711 'url' => home_url(),
712 );
713
714 /* Call the custom API. */
715 $response = wp_remote_post( $product['url'], array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
716
717 /* Make sure the response came back okay */
718 if ( is_wp_error( $response ) ) {
719 return;
720 }
721
722 $this->flush_update_cache();
723
724 /* Decode the license data */
725 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
726
727 $settings = get_option( 'charitable_settings' );
728
729 unset( $settings['licenses'][ $product_key ] );
730
731 update_option( 'charitable_settings', $settings );
732
733 wp_redirect( add_query_arg( array( 'tab' => 'advanced' ), admin_url( 'admin.php?page=charitable-settings' ) ) );
734 exit;
735
736 }
737
738 /**
739 * Flush the version update cache.
740 *
741 * @since 1.4.20
742 *
743 * @return void
744 */
745 protected function flush_update_cache() {
746 wp_cache_delete( 'plugin_versions', 'charitable' );
747 set_site_transient( 'update_plugins', null );
748 }
749
750 /**
751 * Return a key for the item, based on the item name.
752 *
753 * @since 1.0.0
754 *
755 * @param string $item_name Name of the item.
756 * @return string
757 */
758 protected function get_item_key( $item_name ) {
759 return strtolower( str_replace( ' ', '_', $item_name ) );
760 }
761
762 /**
763 * Return the latest versions of Charitable plugins.
764 *
765 * @since 1.4.0
766 *
767 * @return array
768 */
769 protected function get_versions() {
770 $versions = wp_cache_get( 'plugin_versions', 'charitable' );
771
772 if ( false === $versions ) {
773
774 $licenses = array();
775
776 foreach ( $this->get_licenses() as $license ) {
777 if ( isset( $license['license'] ) ) {
778 $licenses[] = $license['license'];
779 }
780 }
781
782 $response = wp_remote_post(
783 Charitable_Licenses::UPDATE_URL . '/edd-api/versions-v2/',
784 array(
785 'sslverify' => false,
786 'timeout' => 15,
787 'body' => array(
788 'licenses' => $licenses,
789 'url' => home_url(),
790 ),
791 )
792 );
793
794 $versions = wp_remote_retrieve_body( $response );
795
796 $versions = json_decode( $versions, true );
797
798 wp_cache_set( 'plugin_versions', $versions, 'charitable' );
799 } //end if
800
801 return $versions;
802 }
803
804 public function ajax_license_check() {
805
806 if ( ! is_admin() ) {
807 return;
808 }
809
810 if ( ! isset( $_REQUEST['license'] ) ) {
811 return;
812 }
813
814 if ( ! isset( $_REQUEST['action'] ) && 'charitable_license_check' !== $_REQUEST['action'] ) {
815 return;
816 }
817
818 if ( ! isset( $_REQUEST['chartiable_action'] ) && 'verify' !== $_REQUEST['chartiable_action'] ) {
819 return;
820 }
821
822 // to-do: adjust spelling of chartiable_action and add nonce check.
823
824 $product_key = 'charitable';
825 $re_check = true;
826 $license = trim( esc_html( $_REQUEST['license'] ) );
827 $license_data = $this->verify_license( $product_key, $license, $re_check );
828
829 $this->flush_update_cache();
830
831 $settings = get_option( 'charitable_settings' );
832
833 $settings['licenses'][ $product_key . '-v2' ] = array(
834 'license' => $license,
835 'expiration_date' => isset( $license_data['expiration_date'] ) ? $license_data['expiration_date'] : false,
836 'plan_id' => isset( $license_data['plan_id'] ) ? $license_data['plan_id'] : false,
837 'valid' => isset( $license_data['plan_id'] ) ? 1 === intval( $license_data['valid'] ) : false,
838 );
839
840 update_option( 'charitable_settings', $settings );
841
842 if ( isset( $license_data['valid'] ) && intval( $license_data['valid'] ) === 1 ) {
843 $license_data['message'] = Charitable_Licenses_Settings::get_instance()->get_licensed_message();
844 } else {
845 $license_data['message'] = Charitable_Licenses_Settings::get_instance()->get_unlicensed_message( false, $license_data );
846 }
847
848 wp_send_json_success( $license_data );
849
850 }
851
852 }
853
854 endif;
855