PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.7.0.6
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.7.0.6
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.6, at includes/licensing/class-charitable-licenses.php

844 lines 22.6 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 *
255 * @param mixed $_data Default set of data.
256 * @param string $_action The current action.
257 * @param object $_args Request args.
258 * @return object $_data
259 */
260 public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
261 if ( 'plugin_information' != $_action ) {
262 return $_data;
263 }
264
265 if ( ! isset( $_args->slug ) ) {
266 return $_data;
267 }
268
269 $plugin_key = str_replace( '-', '_', $_args->slug );
270
271 if ( ! array_key_exists( $plugin_key, $this->products ) ) {
272 return $_data;
273 }
274
275 $version_info = $this->get_version_info( plugin_basename( $this->products[ $plugin_key ]['file'] ) );
276
277 if ( $version_info ) {
278 $_data = $version_info;
279 }
280
281 return $_data;
282 }
283
284 /**
285 * Return whether a particular plugin is missing version info.
286 *
287 * @since 1.4.20
288 *
289 * @param array $product Product details array.
290 * @param false|object $update_cache Optional argument to pass update cache.
291 * @return boolean
292 */
293 public function is_missing_version_info( $product, $update_cache = false ) {
294 return ! $this->get_version_info( plugin_basename( $product['file'] ), $update_cache );
295 }
296
297 /**
298 * Return the version update info for a particular plugin.
299 *
300 * @since 1.4.20
301 *
302 * @param string $slug The plugin slug.
303 * @param false|object $update_cache Optional argument to pass update cache.
304 * @return array|false Array if an update is available. False otherwise.
305 */
306 public function get_version_info( $slug, $update_cache = false ) {
307 if ( ! $update_cache ) {
308 $update_cache = get_site_transient( 'update_plugins' );
309 }
310
311 if ( ! is_object( $update_cache ) || empty( $update_cache->response ) || ! array_key_exists( $slug, $update_cache->response ) ) {
312 return false;
313 }
314
315 return $update_cache->response[ $slug ];
316 }
317
318 /**
319 * Checks whether the given plugin can be updated.
320 *
321 * @since 1.6.14
322 *
323 * @param array $version_info Version information.
324 * @return true|array If it can be updated, returns true. Otherwise
325 * returns an array with a reason_code and description.
326 */
327 protected function able_to_update( $version_info ) {
328 $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' );
329
330 switch ( $version_info['package'] ) {
331
332 case 'missing_license':
333 return array(
334 'reason_code' => 'missing_license',
335 'description' => sprintf(
336 __( '<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' ),
337 esc_html( $version_info['name'] ),
338 admin_url( 'admin.php?page=charitable-settings&tab=licenses' ),
339 esc_url( $changelog_link ),
340 esc_html( $version_info['new_version'] )
341 ),
342 );
343
344 case 'expired_license':
345 $base_renewal_url = isset( $version_info['renewal_link'] ) ? $version_info['renewal_link'] : 'https://www.wpcharitable.com/account';
346
347 return array(
348 'reason_code' => 'expired_license',
349 'description' => sprintf(
350 __( '<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' ),
351 esc_html( $version_info['name'] ),
352 charitable_ga_url(
353 $base_renewal_url,
354 urlencode( 'Expired License Notice'),
355 urlencode( 'Renew your license' )
356 ),
357 esc_url( $changelog_link ),
358 esc_html( $version_info['new_version'] )
359 ),
360 );
361
362 default:
363 if ( ! isset( $version_info['requirements'] ) ) {
364 return true;
365 }
366
367 $messages = array();
368
369 foreach ( $version_info['requirements'] as $type => $details ) {
370
371 switch ( $type ) {
372 case 'php':
373 if ( version_compare( phpversion(), $details, '<' ) ) {
374 $messages[] = esc_html(
375 sprintf(
376 __( '<li>Requires PHP version %s or greater.</li>' ),
377 $details
378 )
379 );
380 }
381 break;
382
383 case 'charitable':
384 if ( version_compare( charitable()->get_version(), $details, '<' ) ) {
385 $messages[] = esc_html(
386 sprintf(
387 __( 'Requires Charitable version %s or greater.' ),
388 $details
389 )
390 );
391 }
392 break;
393 }
394
395 if ( empty( $messages ) ) {
396 return true;
397 }
398
399 return array(
400 'reason_code' => 'missing_requirements',
401 'description' => sprintf(
402 __( '<p>There is a new version of %1$s available but you are missing the following minimum requirements:</p>%2$s', 'charitable' ),
403 esc_html( $version_info['name'] ),
404 '<ul>' . implode( '<br/>', $messages ) . '</ul>'
405 ),
406 );
407 }
408
409 return true;
410 }
411 }
412
413 /**
414 * Return the package string for an expired license.
415 *
416 * @since 1.4.20
417 *
418 * @param string $plugin Plugin basename.
419 * @return string
420 */
421 public function get_expired_license_package( $plugin ) {
422 $version_info = $this->get_version_info( $plugin );
423 $base_renewal_url = isset( $version_info->renewal_link ) ? $version_info->renewal_link : 'https://www.wpcharitable.com/account';
424
425 return sprintf( 'expired_license:%s', charitable_ga_url(
426 $base_renewal_url,
427 urlencode( 'WordPress Dashboard'),
428 urlencode( 'Expired License' )
429 ));
430
431 }
432
433 /**
434 * Return the package string for a plugin missing requirements.
435 *
436 * @since 1.6.14
437 *
438 * @param string $plugin Plugin basename.
439 * @return string
440 */
441 public function get_missing_requirements_package( $plugin ) {
442 $version_info = $this->get_version_info( $plugin );
443
444 return sprintf(
445 'missing_requirements:%s',
446 $version_info->package_download_restriction
447 );
448 }
449
450 /**
451 * Register a product that requires licensing.
452 *
453 * @since 1.0.0
454 *
455 * @param string $item_name The title of the product.
456 * @param string $author The author of the product.
457 * @param string $version The current product version we have installed.
458 * @param string $file The path to the plugin file.
459 * @param string $url The base URL where the plugin is licensed. Defaults to Charitable_Licenses::UPDATE_URL.
460 * @return void
461 */
462 public function register_licensed_product( $item_name, $author, $version, $file, $url = false ) {
463 if ( ! $url ) {
464 $url = Charitable_Licenses::UPDATE_URL;
465 }
466
467 $product_key = $this->get_item_key( $item_name );
468
469 $this->products[ $product_key ] = array(
470 'name' => $item_name,
471 'author' => $author,
472 'version' => $version,
473 'url' => $url,
474 'file' => $file,
475 );
476
477 $licenses = $this->get_licenses();
478 $license = isset( $licenses[ $product_key ]['license'] ) ? trim( $licenses[ $product_key ]['license'] ) : '';
479
480 new Charitable_Plugin_Updater( $url, $file, array(
481 'version' => $version,
482 'license' => $license,
483 'item_name' => $item_name,
484 'author' => $author,
485 ) );
486
487 }
488
489 /**
490 * Return the list of products requiring licensing.
491 *
492 * @since 1.0.0
493 *
494 * @return array[]
495 */
496 public function get_products() {
497 return $this->products;
498 }
499
500 /**
501 * Return a specific product's details.
502 *
503 * @since 1.0.0
504 *
505 * @param string $item The item for which we are getting product details.
506 * @return string[]
507 */
508 public function get_product_license_details( $item ) {
509 return isset( $this->products[ $item ] ) ? $this->products[ $item ] : false;
510 }
511
512 /**
513 * Returns whether the given product has a valid license.
514 *
515 * @since 1.0.0
516 *
517 * @param string $item The item to check.
518 * @return boolean
519 */
520 public function has_valid_license( $item ) {
521 $license = $this->get_license_details( $item );
522
523 if ( ! $license || ! isset( $license['valid'] ) ) {
524 return false;
525 }
526
527 return $license['valid'];
528 }
529
530 /**
531 * Returns the license details for the given product.
532 *
533 * @since 1.0.0
534 *
535 * @param string $item The item to get the license for.
536 * @return mixed[]
537 */
538 public function get_license( $item ) {
539 $license = $this->get_license_details( $item );
540
541 if ( ! $license || ! is_array( $license ) ) {
542 return false;
543 }
544
545 return $license['license'];
546 }
547
548 /**
549 * Returns the active license details for the given product.
550 *
551 * @since 1.0.0
552 *
553 * @param string $item The item to get active licensing details for.
554 * @return mixed[]
555 */
556 public function get_license_details( $item ) {
557 $licenses = $this->get_licenses();
558
559 if ( ! isset( $licenses[ $item ] ) ) {
560 return false;
561 }
562
563 return $licenses[ $item ];
564 }
565
566 /**
567 * Return the list of licenses.
568 *
569 * Note: The licenses are not necessarily valid. If a user enters an invalid
570 * license, the license will be stored but it will be flagged as invalid.
571 *
572 * @since 1.0.0
573 *
574 * @return array[]
575 */
576 public function get_licenses() {
577 if ( ! isset( $this->licenses ) ) {
578 $this->licenses = charitable_get_option( 'licenses', array() );
579 }
580
581 return $this->licenses;
582 }
583
584 /**
585 * Verify a license.
586 *
587 * @since 1.0.0
588 *
589 * @param string $item The item to verify.
590 * @param string $license The license key for the item.
591 * @param boolean $force Whether to force the verification check.
592 * @return mixed[]
593 */
594 public function verify_license( $item, $license, $force = false, $legacy = false ) {
595
596 $license = trim( $license );
597
598 if ( $license === $this->get_license( $item ) && ! $force ) {
599 return $this->get_license_details( $item );
600 }
601
602 $product_details = $this->get_product_license_details( $item );
603
604 /* This product was not correctly registered. */
605 if ( ! $product_details ) {
606 return;
607 }
608
609 /* Data to send in our API request */
610 $api_params = array(
611 'edd_action' => 'activate_license',
612 'license' => $license,
613 'legacy' => $legacy,
614 'item_name' => urlencode( $product_details['name'] ),
615 'url' => home_url(),
616 );
617
618 /* Call the custom API */
619 $response = wp_remote_post(
620 $product_details['url'],
621 array(
622 'timeout' => 15,
623 'sslverify' => false,
624 'body' => $api_params,
625 )
626 );
627
628 if ( defined( 'CHARITABLE_DEBUG' ) && CHARITABLE_DEBUG ) {
629 error_log( print_r( $api_params, true ) );
630 error_log( print_r( $product_details, true ) );
631 error_log( print_r( $response, true ) );
632 }
633
634 /* Make sure the response came back okay */
635 if ( is_wp_error( $response ) ) {
636 return;
637 }
638
639 $this->flush_update_cache();
640
641 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
642
643 $comm_success = isset( $license_data ) && ! empty( $license_data ) ? true : false;
644
645 // if the license is not valid, attempt to discover why - in this case, maybe the activation limit was exceeded.
646
647 $license_limit = isset( $license_data->license_limit ) ? intval( $license_data->license_limit ) : false;
648 $site_count = isset( $license_data->site_count ) ? intval( $license_data->site_count ) : false;
649 $limit_exceeded = ( $license_limit > 0 && $site_count >= $license_limit ) ? true : false;
650
651 return array(
652 'license' => $license,
653 'expiration_date' => isset( $license_data->expires) ? $license_data->expires : false,
654 'plan_id' => isset( $license_data->price_id ) ? $license_data->price_id : false,
655 'valid' => ( isset( $license_data->license ) && 'valid' === $license_data->license ),
656 'license_limit' => $limit_exceeded,
657 'comm_success' => $comm_success,
658 );
659 }
660
661 /**
662 * Return the URL to deactivate a specific license.
663 *
664 * @since 1.0.0
665 *
666 * @param string $item The item to deactivate.
667 * @return string
668 */
669 public function get_license_deactivation_url( $item ) {
670 return esc_url( add_query_arg( array(
671 'charitable_action' => 'deactivate_license',
672 'product_key' => $item,
673 '_nonce' => wp_create_nonce( 'license' ),
674 ), admin_url( 'admin.php?page=charitable-settings&tab=advanced' ) ) );
675 }
676
677 /**
678 * Deactivate a license.
679 *
680 * @since 1.0.0
681 *
682 * @return void
683 */
684 public function deactivate_license() {
685 if ( ! wp_verify_nonce( $_REQUEST['_nonce'], 'license' ) ) {
686 wp_die( esc_attr__( 'Cheatin\' eh?!', 'charitable' ) );
687 }
688
689 $product_key = isset( $_REQUEST['product_key'] ) ? $_REQUEST['product_key'] : false;
690
691 /* Product key must be set */
692 if ( false === $product_key ) {
693 wp_die( esc_attr__( 'Missing product key', 'charitable' ) );
694 }
695
696 $product = $this->get_product_license_details( $product_key );
697
698 /* Make sure we have a valid product with a valid license. */
699 if ( ! $product || ! $this->has_valid_license( $product_key ) ) {
700 wp_die( esc_attr__( 'This product is not valid or does not have a valid license key.', 'charitable' ) );
701 }
702
703 $license = $this->get_license( $product_key );
704
705 /* Data to send to wpcharitable.com to deactivate the license. */
706 $api_params = array(
707 'edd_action' => 'deactivate_license',
708 'license' => $license,
709 'item_name' => urlencode( $product['name'] ),
710 'url' => home_url(),
711 );
712
713 /* Call the custom API. */
714 $response = wp_remote_post( $product['url'], array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
715
716 /* Make sure the response came back okay */
717 if ( is_wp_error( $response ) ) {
718 return;
719 }
720
721 $this->flush_update_cache();
722
723 /* Decode the license data */
724 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
725
726 $settings = get_option( 'charitable_settings' );
727
728 unset( $settings['licenses'][ $product_key ] );
729
730 update_option( 'charitable_settings', $settings );
731
732 wp_redirect( add_query_arg( array( 'tab' => 'advanced' ), admin_url( 'admin.php?page=charitable-settings' ) ) );
733 exit;
734
735 }
736
737 /**
738 * Flush the version update cache.
739 *
740 * @since 1.4.20
741 *
742 * @return void
743 */
744 protected function flush_update_cache() {
745 wp_cache_delete( 'plugin_versions', 'charitable' );
746 set_site_transient( 'update_plugins', null );
747 }
748
749 /**
750 * Return a key for the item, based on the item name.
751 *
752 * @since 1.0.0
753 *
754 * @param string $item_name Name of the item.
755 * @return string
756 */
757 protected function get_item_key( $item_name ) {
758 return strtolower( str_replace( ' ', '_', $item_name ) );
759 }
760
761 /**
762 * Return the latest versions of Charitable plugins.
763 *
764 * @since 1.4.0
765 *
766 * @return array
767 */
768 protected function get_versions() {
769 $versions = wp_cache_get( 'plugin_versions', 'charitable' );
770
771 if ( false === $versions ) {
772
773 $licenses = array();
774
775 foreach ( $this->get_licenses() as $license ) {
776 if ( isset( $license['license'] ) ) {
777 $licenses[] = $license['license'];
778 }
779 }
780
781 $response = wp_remote_post(
782 Charitable_Licenses::UPDATE_URL . '/edd-api/versions-v2/',
783 array(
784 'sslverify' => false,
785 'timeout' => 15,
786 'body' => array(
787 'licenses' => $licenses,
788 'url' => home_url(),
789 ),
790 )
791 );
792
793 $versions = wp_remote_retrieve_body( $response );
794
795 $versions = json_decode( $versions, true );
796
797 wp_cache_set( 'plugin_versions', $versions, 'charitable' );
798 } //end if
799
800 return $versions;
801 }
802
803 public function ajax_license_check() {
804
805 if ( ! is_admin() ) {
806 return;
807 }
808
809 if ( ! isset( $_REQUEST['license'] ) ) {
810 return;
811 }
812
813 $product_key = 'charitable';
814 $re_check = true;
815 $license = trim( esc_html( $_REQUEST['license'] ) );
816 $license_data = $this->verify_license( $product_key, $license, $re_check );
817
818 $this->flush_update_cache();
819
820 $settings = get_option( 'charitable_settings' );
821
822 $settings['licenses'][ $product_key . '-v2' ] = array(
823 'license' => $license,
824 'expiration_date' => isset( $license_data['expiration_date'] ) ? $license_data['expiration_date'] : false,
825 'plan_id' => isset( $license_data['plan_id'] ) ? $license_data['plan_id'] : false,
826 'valid' => isset( $license_data['plan_id'] ) ? 1 === intval( $license_data['valid'] ) : false,
827 );
828
829 update_option( 'charitable_settings', $settings );
830
831 if ( isset( $license_data['valid'] ) && intval( $license_data['valid'] ) === 1 ) {
832 $license_data['message'] = Charitable_Licenses_Settings::get_instance()->get_licensed_message();
833 } else {
834 $license_data['message'] = Charitable_Licenses_Settings::get_instance()->get_unlicensed_message( false, $license_data );
835 }
836
837 wp_send_json_success( $license_data );
838
839 }
840
841 }
842
843 endif;
844