PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
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 1.7.0.9 All 211 releases
charitable / includes / licensing / class-charitable-licenses.php

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

571 lines 17.3 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.8.2
7 * @author David Bisset
8 * @copyright Copyright (c) 2023, WP Charitable LLC
9 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10 */
11
12 use CharitableLicenses\CharitableLicenses;
13
14 // Exit if accessed directly.
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 if ( ! class_exists( 'Charitable_Licenses' ) ) :
20
21 /**
22 * Charitable_Licenses
23 *
24 * @since 1.0.0
25 */
26 class Charitable_Licenses {
27
28 /* @var string */
29 const UPDATE_URL = 'https://wpcharitable.com';
30
31 /**
32 * The single instance of this class.
33 *
34 * @var Charitable_Licenses|null
35 */
36 private static $instance = null;
37
38 /**
39 * All the registered products requiring licensing.
40 *
41 * @var array
42 */
43 private $products;
44
45 /**
46 * All the stored licenses.
47 *
48 * @var array
49 */
50 private $licenses;
51
52 /**
53 * The key for the failed request cache.
54 *
55 * @var string
56 */
57 private $failed_request_cache_key = 'wpc_edd_sl_failed_plugin_versions';
58
59 /**
60 * Cached update data.
61 *
62 * @var array
63 */
64 private $update_data;
65
66 /**
67 * Returns and/or create the single instance of this class.
68 *
69 * @since 1.2.0
70 *
71 * @return Charitable_Licenses
72 */
73 public static function get_instance() {
74 return self::$instance ??= new self();
75 }
76
77 /**
78 * Create class object.
79 *
80 * @since 1.0.0
81 */
82 private function __construct() {
83
84 $registry = charitable()->registry();
85
86 if ( ! $registry->has( 'charitable_licenses' ) ) {
87 $registry->register_object( CharitableLicenses::get_instance() );
88 }
89 }
90
91 /**
92 * Checks licenses (new and legacy) to see if any are valid.
93 *
94 * @since 1.7.0
95 *
96 * @return boolean
97 */
98 public function is_pro() {
99
100 if ( charitable_is_debug( 'vendor' ) ) {
101 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: is_pro()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
102 }
103
104 // On multisite subsites, the vendor's is_pro() only checks the network main site's license.
105 // Also check the current subsite's license so subsite admins with valid licenses are recognized.
106 if ( is_multisite() && ! is_main_site() ) {
107 $settings = get_option( 'charitable_settings' );
108 if ( $settings && isset( $settings['licenses']['charitable-v2']['valid'] ) && 1 === intval( $settings['licenses']['charitable-v2']['valid'] ) ) {
109 return true;
110 }
111 }
112
113 $registry = charitable()->registry();
114 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->is_pro();
115 }
116
117 /**
118 * Checks the "v3" license (starting Nov 2022) to see if it's valid.
119 * If valid, normally doesn't require other license/pro checks.
120 *
121 * @since 1.7.0.4
122 *
123 * @return boolean
124 */
125 public function is_v3_license_valid() {
126
127 if ( charitable_is_debug( 'vendor' ) ) {
128 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: is_v3_license_valid()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
129 }
130
131 $registry = charitable()->registry();
132 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->is_v3_license_valid();
133 }
134
135 /**
136 * Checks for any Charitable extensions with updates.
137 *
138 * @since 1.4.0
139 *
140 * @param array $_transient_data The plugin updates data.
141 * @return array
142 */
143 public function check_for_updates( $_transient_data ) {
144
145 if ( charitable_is_debug( 'vendor' ) ) {
146 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: check_for_updates()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
147 }
148
149 $registry = charitable()->registry();
150 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->check_for_updates( $_transient_data );
151 }
152
153
154 /**
155 * Updates information on the "View version x.x details" page with custom data.
156 *
157 * @uses api_request()
158 *
159 * @since 1.4.20
160 *
161 * @param mixed $_data Default set of data.
162 * @param string $_action The current action.
163 * @param object $_args Request args.
164 * @return object $_data
165 */
166 public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
167
168 if ( charitable_is_debug( 'vendor' ) ) {
169 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: plugins_api_filter()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
170 }
171
172 $registry = charitable()->registry();
173 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->plugins_api_filter( $_data, $_action, $_args );
174 }
175
176 /**
177 * Return whether a particular plugin is missing version info.
178 *
179 * @since 1.4.20
180 *
181 * @param array $product Product details array.
182 * @param false|object $update_cache Optional argument to pass update cache.
183 * @return boolean
184 */
185 public function is_missing_version_info( $product, $update_cache = false ) {
186
187 if ( charitable_is_debug( 'vendor' ) ) {
188 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: is_missing_version_info()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
189 }
190
191 $registry = charitable()->registry();
192 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->is_missing_version_info( $product, $update_cache );
193 }
194
195 /**
196 * Return the version update info for a particular plugin.
197 *
198 * @since 1.4.20
199 *
200 * @param string $slug The plugin slug.
201 * @param false|object $update_cache Optional argument to pass update cache.
202 * @return array|false Array if an update is available. False otherwise.
203 */
204 public function get_version_info( $slug, $update_cache = false ) {
205
206 if ( charitable_is_debug( 'vendor' ) ) {
207 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_version_info()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
208 }
209
210 $registry = charitable()->registry();
211 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_version_info( $slug, $update_cache );
212 }
213
214 /**
215 * Checks whether the given plugin can be updated.
216 *
217 * @since 1.6.14
218 *
219 * @param array $version_info Version information.
220 * @return true|array If it can be updated, returns true. Otherwise
221 * returns an array with a reason_code and description.
222 */
223 protected function able_to_update( $version_info ) {
224
225 if ( charitable_is_debug( 'vendor' ) ) {
226 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: able_to_update()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
227 }
228
229 $registry = charitable()->registry();
230 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->able_to_update( $version_info );
231 }
232
233 /**
234 * Return the package string for an expired license.
235 *
236 * @since 1.4.20
237 *
238 * @param string $plugin Plugin basename.
239 * @return string
240 */
241 public function get_expired_license_package( $plugin ) {
242
243 if ( charitable_is_debug( 'vendor' ) ) {
244 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_expired_license_package()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
245 }
246
247 $registry = charitable()->registry();
248 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_expired_license_package( $plugin );
249 }
250
251
252 /**
253 * Return the package string for a plugin missing requirements.
254 *
255 * @since 1.6.14
256 *
257 * @param string $plugin Plugin basename.
258 * @return string
259 */
260 public function get_missing_requirements_package( $plugin ) {
261
262 if ( charitable_is_debug( 'vendor' ) ) {
263 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_missing_requirements_package()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
264 }
265
266 $registry = charitable()->registry();
267 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_missing_requirements_package( $plugin );
268 }
269
270 /**
271 * Register a product that requires licensing.
272 *
273 * @since 1.0.0
274 *
275 * @param string $item_name The title of the product.
276 * @param string $author The author of the product.
277 * @param string $version The current product version we have installed.
278 * @param string $file The path to the plugin file.
279 * @param string $url The base URL where the plugin is licensed. Defaults to Charitable_Licenses::UPDATE_URL.
280 * @return void
281 */
282 public function register_licensed_product( $item_name, $author, $version, $file, $url = false ) {
283
284 if ( charitable_is_debug( 'vendor' ) ) {
285 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: register_licensed_product()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
286 }
287
288 $registry = charitable()->registry();
289 $registry->get( 'CharitableLicenses\CharitableLicenses' )->register_licensed_product( $item_name, $author, $version, $file, $url );
290 }
291
292 /**
293 * Return the list of products requiring licensing.
294 *
295 * @since 1.0.0
296 *
297 * @return array[]
298 */
299 public function get_products() {
300
301 if ( charitable_is_debug( 'vendor' ) ) {
302 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_products()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
303 }
304
305 $registry = charitable()->registry();
306 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_products();
307 }
308
309 /**
310 * Return a specific product's details.
311 *
312 * @since 1.0.0
313 *
314 * @param string $item The item for which we are getting product details.
315 * @return string[]
316 */
317 public function get_product_license_details( $item ) {
318
319 if ( charitable_is_debug( 'vendor' ) ) {
320 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_product_license_details()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
321 }
322
323 $registry = charitable()->registry();
324 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_product_license_details( $item );
325 }
326
327 /**
328 * Returns whether the given product has a valid license.
329 *
330 * @since 1.0.0
331 *
332 * @param string $item The item to check.
333 * @return boolean
334 */
335 public function has_valid_license( $item ) {
336
337 if ( charitable_is_debug( 'vendor' ) ) {
338 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: has_valid_license()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
339 }
340
341 $registry = charitable()->registry();
342 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->has_valid_license( $item );
343 }
344
345 /**
346 * Returns the license details for the given product.
347 *
348 * @since 1.0.0
349 *
350 * @param string $item The item to get the license for.
351 * @return mixed[]
352 */
353 public function get_license( $item ) {
354
355 if ( charitable_is_debug( 'vendor' ) ) {
356 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_license()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
357 }
358
359 $registry = charitable()->registry();
360 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_license( $item );
361 }
362
363 /**
364 * Returns the active license details for the given product.
365 *
366 * @since 1.0.0
367 *
368 * @param string $item The item to get active licensing details for.
369 * @return mixed[]
370 */
371 public function get_license_details( $item ) {
372
373 if ( charitable_is_debug( 'vendor' ) ) {
374 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_license_details()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
375 }
376
377 $registry = charitable()->registry();
378 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_license_details( $item );
379 }
380
381 /**
382 * Return the list of licenses.
383 *
384 * Note: The licenses are not necessarily valid. If a user enters an invalid
385 * license, the license will be stored but it will be flagged as invalid.
386 *
387 * @since 1.0.0
388 *
389 * @return array[]
390 */
391 public function get_licenses() {
392
393 if ( charitable_is_debug( 'vendor' ) ) {
394 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_licenses()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
395 }
396
397 $registry = charitable()->registry();
398 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_licenses();
399 }
400
401 /**
402 * Verify a license.
403 *
404 * @since 1.0.0
405 *
406 * @param string $item The item to verify.
407 * @param string $license The license key for the item.
408 * @param boolean $force Whether to force the verification check.
409 * @param boolean $legacy Whether to use the legacy API (?).
410 * @return mixed[]
411 */
412 public function verify_license( $item, $license, $force = false, $legacy = false ) {
413
414 if ( charitable_is_debug( 'vendor' ) ) {
415 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: verify_license()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
416 }
417
418 $registry = charitable()->registry();
419 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->verify_license( $item, $license, $force, $legacy );
420 }
421
422 /**
423 * Return the URL to deactivate a specific license.
424 *
425 * @since 1.0.0
426 *
427 * @param string $item The item to deactivate.
428 * @return string
429 */
430 public function get_license_deactivation_url( $item ) {
431
432 if ( charitable_is_debug( 'vendor' ) ) {
433 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_license_deactivation_url()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
434 }
435
436 $registry = charitable()->registry();
437 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_license_deactivation_url( $item );
438 }
439
440 /**
441 * Deactivate a license.
442 *
443 * @since 1.0.0
444 *
445 * @return void
446 */
447 public function deactivate_license() {
448
449 if ( charitable_is_debug( 'vendor' ) ) {
450 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: deactivate_license()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
451 }
452
453 $registry = charitable()->registry();
454 $registry->get( 'CharitableLicenses\CharitableLicenses' )->deactivate_license();
455 }
456
457 /**
458 * Flush the version update cache.
459 *
460 * @since 1.4.20
461 * @since 1.8.1.1 - Remove site option. Other items in this function are depreciated.
462 *
463 * @return void
464 */
465 protected function flush_update_cache() {
466
467 if ( charitable_is_debug( 'vendor' ) ) {
468 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: flush_update_cache()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
469 }
470
471 $registry = charitable()->registry();
472 $registry->get( 'CharitableLicenses\CharitableLicenses' )->flush_update_cache();
473 }
474
475 /**
476 * Return a key for the item, based on the item name.
477 *
478 * @since 1.0.0
479 *
480 * @param string $item_name Name of the item.
481 * @return string
482 */
483 protected function get_item_key( $item_name ) {
484
485 if ( charitable_is_debug( 'vendor' ) ) {
486 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_item_key()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
487 }
488
489 $registry = charitable()->registry();
490 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_item_key( $item_name );
491 }
492
493 /**
494 * Return the latest versions of Charitable plugins.
495 *
496 * @since 1.4.0
497 * @since 1.8.1.1 - Removed cache_get method and site a site option instead.
498 * @since 1.8.1.3 - Added request_recently_failed check and log_failed_request call.
499 *
500 * @return array
501 */
502 protected function get_versions() {
503
504 if ( charitable_is_debug( 'vendor' ) ) {
505 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: get_versions()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
506 }
507
508 $registry = charitable()->registry();
509 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->get_versions();
510 }
511
512 /**
513 * Logs a failed HTTP request for this API URL.
514 *
515 * We set a timestamp for 1 hour from now. This prevents future API requests from being
516 * made to this domain for 1 hour. Once the timestamp is in the past, API requests
517 * will be allowed again. This way if the site is down for some reason we don't bombard
518 * it with failed API requests.
519 *
520 * @see EDD_SL_Plugin_Updater::request_recently_failed
521 *
522 * @since 1.8.1.3
523 */
524 private function log_failed_request() {
525
526 if ( charitable_is_debug( 'vendor' ) ) {
527 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: log_failed_request()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
528 }
529
530 $registry = charitable()->registry();
531 $registry->get( 'CharitableLicenses\CharitableLicenses' )->log_failed_request();
532 }
533
534 /**
535 * Determines if a request has recently failed.
536 *
537 * @since 1.8.1.3
538 *
539 * @return bool
540 */
541 private function request_recently_failed() {
542
543 if ( charitable_is_debug( 'vendor' ) ) {
544 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: request_recently_failed()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
545 }
546
547 $registry = charitable()->registry();
548 return $registry->get( 'CharitableLicenses\CharitableLicenses' )->request_recently_failed();
549 }
550
551 /**
552 * AJAX handler for license checks.
553 *
554 * @since 1.0.0
555 * @since 1.8.1.8 - Added nonce and permissions check.
556 *
557 * @return void
558 */
559 public function ajax_license_check() {
560
561 if ( charitable_is_debug( 'vendor' ) ) {
562 error_log( 'CHARITABLE: NEW VENDOR CALL THROWN: ajax_license_check()' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
563 }
564
565 $registry = charitable()->registry();
566 $registry->get( 'CharitableLicenses\CharitableLicenses' )->ajax_license_check();
567 }
568 }
569
570 endif;
571