PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.15.2
GiveWP – Donation Plugin and Fundraising Platform v4.15.2
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 / class-give-license-handler.php
give / includes Last commit date
admin 1 month ago api 3 years ago database 5 months ago deprecated 1 month ago donors 5 months ago emails 9 months ago forms 9 months ago frontend 6 years ago gateways 9 months ago libraries 9 months ago payments 2 months ago actions.php 9 months ago ajax-functions.php 9 months ago class-give-async-process.php 1 year ago class-give-background-updater.php 9 months ago class-give-cache-setting.php 1 year ago class-give-cache.php 9 months ago class-give-cli-commands.php 1 year ago class-give-comment.php 9 months ago class-give-cron.php 9 months ago class-give-donate-form.php 1 year ago class-give-donor.php 2 years ago class-give-email-access.php 5 years ago class-give-license-handler.php 1 month ago class-give-logging.php 9 months ago class-give-readme-parser.php 4 years ago class-give-roles.php 5 months ago class-give-scripts.php 8 months ago class-give-session.php 9 months ago class-give-stats.php 6 years ago class-give-template-loader.php 6 years ago class-give-tooltips.php 6 years ago class-give-translation.php 4 years ago class-notices.php 9 months ago country-functions.php 7 months ago currencies-list.php 7 months ago currency-functions.php 3 years ago error-tracking.php 6 years ago filters.php 9 months ago formatting.php 9 months ago install.php 9 months ago login-register.php 2 years ago misc-functions.php 1 month ago plugin-compatibility.php 6 years ago post-types.php 1 year ago price-functions.php 6 years ago process-donation.php 1 year ago setting-functions.php 6 years ago shortcodes.php 1 year ago template-functions.php 1 year ago user-functions.php 3 years ago
class-give-license-handler.php
1177 lines
1 <?php
2 /**
3 * Give License handler
4 *
5 * @package Give
6 * @subpackage Admin/License
7 * @copyright Copyright (c) 2016, GiveWP
8 * @license https://opensource.org/licenses/gpl-license GNU Public License
9 * @since 1.0
10 */
11
12 // Exit if accessed directly.
13 use Give\Log\Log;
14 use Give\Vendors\StellarWP\AdminNotices\AdminNotices;
15
16 if ( ! defined('ABSPATH') ) {
17 exit;
18 }
19
20 if ( ! class_exists('Give_License') ) :
21
22 /**
23 * Give_License Class
24 *
25 * This class simplifies the process of adding license information
26 * to new Give add-ons.
27 *
28 * @since 1.0
29 */
30 class Give_License
31 {
32
33 /**
34 * File
35 *
36 * @access private
37 * @since 1.0
38 *
39 * @var string
40 */
41 private $file;
42
43 /**
44 * License
45 *
46 * @access private
47 * @since 1.0
48 *
49 * @var string
50 */
51 private $license;
52
53 /**
54 * The license bundled with the premium add-on.
55 *
56 * @since 3.21.0
57 *
58 * @var string|null
59 */
60 private $bundled_license;
61
62 /**
63 * Item name
64 *
65 * @access private
66 * @since 1.0
67 *
68 * @var string
69 */
70 private $item_name;
71
72 /**
73 * Item ID
74 *
75 * @access private
76 * @since 2.2.4
77 *
78 * @var int
79 */
80 private $item_id;
81
82 /**
83 * License Information object.
84 *
85 * @access private
86 * @since 1.7
87 *
88 * @var object
89 */
90 private $license_data;
91
92 /**
93 * Item shortname
94 *
95 * @access private
96 * @since 1.0
97 *
98 * @var string
99 */
100 private $item_shortname;
101
102 /**
103 * Version
104 *
105 * @access private
106 * @since 1.0
107 *
108 * @var string
109 */
110 private $version;
111
112 /**
113 * Author
114 *
115 * @access private
116 * @since 1.0
117 *
118 * @var string
119 */
120 private $author;
121
122 /**
123 * Plugin basename (as provided by plugin_basename() function)
124 *
125 * @var string
126 */
127 private $plugin_basename;
128
129 /**
130 * Plugin directory name
131 *
132 * @access private
133 * @since 2.5.0
134 *
135 * @var string
136 */
137 private $plugin_dirname;
138
139 /**
140 * Website URL
141 *
142 * @access private
143 * @since 1.0
144 *
145 * @var string
146 */
147 private static $site_url = 'https://givewp.com/';
148
149 /**
150 * API URL
151 *
152 * @access private
153 * @since 1.0
154 *
155 * @var string
156 */
157 private static $api_url = 'https://givewp.com/edd-sl-api/';
158
159 /**
160 * array of licensed addons
161 *
162 * @since 3.21.0 store the Give_License instances, not just the plugin basenames
163 * @since 2.1.4
164 * @access private
165 *
166 * @var Give_License[]
167 */
168 private static $licensed_addons = [];
169
170 /**
171 * Account URL
172 *
173 * @access private
174 * @since 1.7
175 *
176 * @var null|string
177 */
178 private static $account_url = 'http://docs.givewp.com/settings-account';
179
180 /**
181 * Downloads URL
182 *
183 * @access private
184 * @since 2.5.0
185 *
186 * @var null|string
187 */
188 private static $downloads_url = 'http://docs.givewp.com/settings-downloads';
189
190 /**
191 * Checkout URL
192 *
193 * @access private
194 * @since 1.7
195 *
196 * @var null|string
197 */
198 private static $checkout_url = 'https://givewp.com/checkout/';
199
200 /**
201 * Class Constructor
202 *
203 * Set up the Give License Class.
204 *
205 * @access public
206 *
207 * @since 3.17.2 removed unused auto_updater_obj property assignment
208 * @since 1.0
209 *
210 * @param string $_file
211 * @param string $_item_name
212 * @param string $_version
213 * @param string $_author
214 * @param string $_optname
215 * @param string $_api_url
216 * @param string $_checkout_url
217 * @param string $_account_url
218 * @param int $_item_id
219 *
220 * @since 3.21.0 adds plugin_basename property
221 */
222 public function __construct(
223 $_file,
224 $_item_name,
225 $_version,
226 $_author,
227 $_optname = null,
228 $_api_url = null,
229 $_checkout_url = null,
230 $_account_url = null,
231 $_item_id = null
232 ) {
233
234 // Only load in wp-admin.
235 if ( ! is_admin() ) {
236 return;
237 }
238
239 if ( is_numeric( $_item_id ) ) {
240 $this->item_id = absint( $_item_id );
241 }
242
243 $this->file = $_file;
244 $this->item_name = $_item_name;
245 $this->plugin_basename = plugin_basename($this->file);
246 $this->plugin_dirname = dirname( plugin_basename( $this->file ) );
247 $this->item_shortname = self::get_short_name( $this->item_name );
248 $this->license_data = self::get_license_by_plugin_dirname( $this->plugin_dirname );
249 $this->version = $_version;
250 $this->license = ! empty( $this->license_data['license_key'] ) ? $this->license_data['license_key'] : '';
251 $this->bundled_license = self::get_bundled_license($this->file);
252 $this->author = $_author;
253 self::$api_url = is_null( $_api_url ) ? self::$api_url : $_api_url;
254 self::$checkout_url = is_null( $_checkout_url ) ? self::$checkout_url : $_checkout_url;
255 self::$account_url = is_null( $_account_url ) ? self::$account_url : $_account_url;
256
257 // Add plugin to registered licenses list.
258 array_push(self::$licensed_addons, $this);
259 }
260
261 /**
262 * Get plugin shortname
263 *
264 * @param $plugin_name
265 *
266 * @return string
267 * @since 2.1.0
268 * @access public
269 */
270 public static function get_short_name( $plugin_name ) {
271 $plugin_name = trim( str_replace( 'Give - ', '', $plugin_name ) );
272 $plugin_name = 'give_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $plugin_name ) ) );
273
274 return $plugin_name;
275 }
276
277 /**
278 * Checks to see if the license was bundled with the add-on and if so, returns it. This is meant to be a
279 * convenience, so any errors are ignored and the user can still manually enter their license key.
280 *
281 * @since 3.21.0
282 */
283 public static function get_bundled_license(string $plugin_file): ?string
284 {
285 $license = null;
286 $file_path = plugin_dir_path($plugin_file) . 'PLUGIN_LICENSE.php';
287 if (is_readable($file_path)) {
288 $license = include $file_path;
289 }
290
291 return $license ?: null;
292 }
293
294 /**
295 * This sorts through all the registered add-ons and checks to see if any of them have bundled licenses, but
296 * aren't set up with a license key. If so, it will attempt to activate the license key for them.
297 *
298 * It's likely that many add-ons will have the same license key which is a plan, so the license key will only be
299 * activated once for all add-ons using it.
300 *
301 * If any sort of error occurs, an admin notice will be shown to the user providing the error and instructions
302 * to manually activate the license key.
303 *
304 * Note: much of this code is taken directly from give_get_license_info_handler()
305 *
306 * @since 3.21.0
307 */
308 public static function activate_bundled_licenses(): void
309 {
310 $unactivated_bundled_licenses = [];
311 foreach (self::$licensed_addons as $addon) {
312 if ($addon->bundled_license && empty($addon->license)) {
313 // Store a unique associative array where the key is the license key and the value is an array of
314 // addons using that license
315 if ( ! isset($unactivated_bundled_licenses[$addon->bundled_license])) {
316 $unactivated_bundled_licenses[$addon->bundled_license] = [];
317 }
318
319 $unactivated_bundled_licenses[$addon->bundled_license][] = $addon;
320 }
321 }
322
323 if (empty($unactivated_bundled_licenses)) {
324 return;
325 }
326
327 $show_failed_activation_notice = static function ($license_key, $reason) {
328 AdminNotices::show(
329 "license-bundle-activation-error-$license_key",
330 "An error occurred while attempting to activate license <code>$license_key</code>. $reason. Please activate the license manually."
331 )->autoParagraph()->asError()->dismissible();
332 };
333
334 foreach ($unactivated_bundled_licenses as $license => $addons) {
335 $check_license_res = self::request_license_api(
336 [
337 'edd_action' => 'check_license',
338 'license' => $license,
339 ],
340 true
341 );
342 $is_plan_license = ! empty($check_license_res['is_all_access_pass']);
343
344 if (is_wp_error($check_license_res)) {
345 $show_failed_activation_notice($license, $check_license_res->get_error_message());
346 continue;
347 }
348
349 if ( ! $check_license_res['success']) {
350 $reason = $check_license_res['error'] ?? 'The licensing server was unreachable';
351 $show_failed_activation_notice( $license, $reason );
352 continue;
353 }
354
355 if ( ! $is_plan_license) {
356 if (count($addons) > 1) {
357 $show_failed_activation_notice(
358 $license,
359 'A single add-on license cannot be used for multiple add-ons'
360 );
361 continue;
362 }
363
364 if ($check_license_res['plugin_slug'] !== $addons[0]->plugin_dirname) {
365 $show_failed_activation_notice(
366 $license,
367 'The license is not valid for this add-on'
368 );
369 continue;
370 }
371 }
372
373 $activate_license_res = self::request_license_api(
374 [
375 'edd_action' => 'activate_license',
376 'item_name' => $check_license_res['item_name'],
377 'license' => $license,
378 ],
379 true
380 );
381
382 if (is_wp_error($activate_license_res)) {
383 $show_failed_activation_notice($license, $activate_license_res->get_error_message());
384 continue;
385 }
386
387 $check_license_res['license'] = $activate_license_res['license'];
388 $check_license_res['site_count'] = $activate_license_res['site_count'];
389 $check_license_res['activations_left'] = $activate_license_res['activations_left'];
390 $licenses = get_option('give_licenses', []);
391
392 if ($is_plan_license) {
393 $addonSlugs = self::getAddonSlugsFromAllAccessPassLicense($check_license_res);
394 foreach ($licenses as $license_key => $data) {
395 if (in_array($data['plugin_slug'], $addonSlugs, true) || ! empty($data['is_all_access_pass'])) {
396 unset($licenses[$license_key]);
397 }
398 }
399 }
400
401 $licenses[$check_license_res['license_key']] = $check_license_res;
402 update_option('give_licenses', $licenses);
403 }
404
405 // Have WordPress check for updates
406 give_refresh_licenses();
407 }
408
409 /**
410 * Activate License
411 *
412 * Activate the license key.
413 *
414 * @access public
415 * @return void
416 * @since 1.0
417 */
418 public function activate_license() {
419 }
420
421 /**
422 * Deactivate License
423 *
424 * Deactivate the license key.
425 *
426 * @access public
427 * @return void
428 * @since 1.0
429 */
430 public function deactivate_license() {
431 }
432
433
434 /**
435 * Get license information.
436 *
437 * @param string $edd_action
438 * @param bool $response_in_array
439 *
440 * @return mixed
441 * @deprecated 2.5.0 Use self::request_license_api instead.
442 *
443 * @since 1.8.9
444 * @access public
445 */
446 public function get_license_info($edd_action = '', $response_in_array = false)
447 {
448 if ( empty($edd_action) ) {
449 return false;
450 }
451
452 give_doing_it_wrong(__FUNCTION__, 'Use self::request_license_api instead from GiveWP 2.5.0');
453
454 // Data to send to the API.
455 $api_params = [
456 'edd_action' => $edd_action, // never change from "edd_" to "give_"!
457 'license' => $this->license,
458 'item_name' => urlencode($this->item_name),
459 ];
460
461 return self::request_license_api($api_params, $response_in_array);
462 }
463
464 /**
465 * Return licensed addons info
466 *
467 * Note: note only for internal logic
468 *
469 * @since 3.21.1 use array_map to safely access the private property
470 * @since 3.21.0 plucks the basename for backwards compatibility
471 * @since 2.1.4
472 * @return string[]
473 */
474 static function get_licensed_addons(): array
475 {
476 return array_map( static function ( Give_License $license ) {
477 return $license->plugin_basename;
478 }, self::$licensed_addons );
479 }
480
481 /**
482 * Check if license key attached to subscription
483 *
484 * @since 2.5.0
485 *
486 * @param string $license_key
487 *
488 * @return array
489 */
490 static function is_subscription($license_key = '')
491 {
492 // Check if current license is part of subscription or not.
493 $subscriptions = get_option('give_subscriptions');
494 $subscription = [];
495
496 if ( $subscriptions ) {
497 foreach ($subscriptions as $subs) {
498 if ( in_array($license_key, $subs['licenses']) ) {
499 $subscription = $subs;
500 break;
501 }
502 }
503 }
504
505 return $subscription;
506 }
507
508 /**
509 * Get license information.
510 *
511 * @since 1.8.9
512 * @since 2.18.0 log failed license api request information
513 *
514 * @param bool $response_in_array
515 *
516 * @param array $api_params
517 *
518 * @return array|WP_Error
519 */
520 public static function request_license_api($api_params = [], $response_in_array = false)
521 {
522 // Bailout.
523 if ( empty($api_params['edd_action']) ) {
524 return new WP_Error('give-invalid-edd-action', __('Valid edd_action not defined', 'give'));
525 }
526
527 // Data to send to the API.
528 $default_api_params = [
529 // 'edd_action' => $edd_action, never change from "edd_" to "give_"!
530 // 'license' => $this->license,
531 // 'item_name' => urlencode( $this->item_name ),
532 'url' => home_url(),
533 ];
534
535 $api_params = wp_parse_args($api_params, $default_api_params);
536
537 // Call the API.
538 $response = wp_remote_post(
539 self::get_api_url(),
540 apply_filters(
541 'give_request_license_api_args',
542 [
543 'timeout' => 15,
544 'sslverify' => false,
545 'body' => $api_params,
546 ]
547 )
548 );
549
550 $statusCode = wp_remote_retrieve_response_code($response);
551 $body = json_decode(wp_remote_retrieve_body($response), $response_in_array);
552
553 if ( 200 !== $statusCode ) {
554 Log::http(
555 'License Api request failed',
556 [
557 'category' => 'License',
558 'api url' => self::get_api_url(),
559 'request' => $api_params,
560 'status code' => $statusCode,
561 'response' => $response
562 ]
563 );
564 }
565
566 // Make sure there are no errors.
567 if ( is_wp_error($response) ) {
568 return $response;
569 }
570
571 return $body;
572 }
573
574 /**
575 * Get license by plugin dirname
576 *
577 * @param string $plugin_dirname
578 *
579 * @return array
580 *
581 * @since 4.15.0 add support for Harbor unified licenses
582 * @since 2.5.0
583 * @access public
584 */
585 public static function get_license_by_plugin_dirname( $plugin_dirname ) {
586 $license = [];
587 $give_licenses = get_option( 'give_licenses', [] );
588
589 if ( ! empty( $give_licenses ) ) {
590 foreach ( $give_licenses as $give_license ) {
591
592 // Logic to match all access pass license to add-on.
593 $compares = $give_license['is_all_access_pass']
594 ? $give_license['download']
595
596 // Prevent PHP notice if somehow automatic update does not run properly.
597 // Because plugin_slug will only define in updated license rest api response.
598 : [ [ 'plugin_slug' => ! empty( $give_license['plugin_slug'] ) ? $give_license['plugin_slug'] : '' ] ];
599
600 foreach ( $compares as $compare ) {
601 if ( ! empty( $compare['plugin_slug'] ) && $plugin_dirname === $compare['plugin_slug'] ) {
602 $license = $give_license;
603 break;
604 }
605 }
606 }
607 }
608
609 // Fall back to Harbor feature availability when no legacy license is found.
610 if ( empty( $license ) && lw_harbor_is_feature_available( $plugin_dirname ) ) {
611 $license = [ 'license' => 'valid' ];
612 }
613
614 return $license;
615 }
616
617
618 /**
619 * Get checkout url
620 *
621 * @return string|null
622 * @since 2.5.0
623 */
624 public static function get_checkout_url() {
625 return self::$checkout_url;
626 }
627
628 /**
629 * Get account url
630 *
631 * @return string|null
632 * @since 2.5.0
633 */
634 public static function get_account_url() {
635 return self::$account_url;
636 }
637
638 /**
639 * Get downloads url
640 *
641 * @return string|null
642 * @since 2.5.0
643 */
644 public static function get_downloads_url() {
645 return self::$downloads_url;
646 }
647
648 /**
649 * Get account url
650 *
651 * @since 3.20.0 allows to override the API URL via constant
652 * @since 2.5.0
653 */
654 public static function get_website_url(): ?string
655 {
656 if (defined('GIVE_SITE_URL')) {
657 return GIVE_SITE_URL;
658 }
659
660 return self::$site_url;
661 }
662
663
664 /**
665 * Get plugin information by id.
666 * Note: only for internal use
667 *
668 * @param string $plugin_slug
669 *
670 * @return array
671 * @since 2.5.0
672 */
673 public static function get_plugin_by_slug( $plugin_slug ) {
674 $give_plugins = give_get_plugins();
675 $matching_list = wp_list_pluck( $give_plugins, 'Dir', 'Path' );
676 $is_match_found = array_search( $plugin_slug, $matching_list, true );
677
678 return $is_match_found ? $give_plugins[ $is_match_found ] : [];
679 }
680
681 /**
682 * Get plugin information by id.
683 * Note: only for internal use
684 *
685 * @param string $plugin_slug
686 *
687 * @return string
688 * @since 2.5.0
689 */
690 public static function build_plugin_name_from_slug( $plugin_slug ) {
691 $plugin_name = str_replace( [ '-', 'give ' ], [ ' ', 'Give - ' ], $plugin_slug );
692
693 return ucwords( $plugin_name );
694 }
695
696 /**
697 * Render license section
698 *
699 * @return string
700 * @since 2.5.0
701 */
702 public static function render_licenses_list() {
703 $give_plugins = give_get_plugins( [ 'only_premium_add_ons' => true ] );
704 $give_licenses = get_option( 'give_licenses', [] );
705 $licenses_without_addon = $give_licenses;
706
707 // Get all access pass licenses
708 $all_access_pass_licenses = [];
709 $all_access_pass_addon_list = [];
710 foreach ( $give_licenses as $key => $give_license ) {
711 if ( $give_license['is_all_access_pass'] ) {
712 $all_access_pass_licenses[ $key ] = $give_license;
713
714 unset( $licenses_without_addon[ $key ] );
715
716 foreach ( $give_license['download'] as $download ) {
717 $all_access_pass_addon_list[] = $download['plugin_slug'];
718 }
719 }
720 }
721
722 $html = [
723 'unlicensed' => '',
724 'licensed' => '',
725 'licenses_without_addon' => '',
726 'all_access_licensed' => '',
727 ];
728
729 if ( ! empty( $give_plugins ) ) {
730 foreach ( $give_plugins as $give_plugin ) {
731 if ( in_array( $give_plugin['Dir'], $all_access_pass_addon_list ) ) {
732 continue;
733 }
734
735 $addon_license = self::get_license_by_plugin_dirname( $give_plugin['Dir'] );
736 $html_arr_key = 'unlicensed';
737
738 if ( $addon_license ) {
739 $html_arr_key = 'licensed';
740 unset( $licenses_without_addon[ $addon_license['license_key'] ] );
741 }
742
743 $html[ "{$html_arr_key}" ] .= self::html_by_plugin( $give_plugin );
744 }
745 }
746
747 if ( ! empty( $all_access_pass_licenses ) ) {
748 foreach ( $all_access_pass_licenses as $key => $all_access_pass_license ) {
749 $html['all_access_licensed'] .= self::html_by_license( $all_access_pass_license );
750 }
751 }
752
753 if ( ! empty( $licenses_without_addon ) ) {
754 foreach ( $licenses_without_addon as $key => $license ) {
755 if ( in_array( $license['plugin_slug'], $all_access_pass_addon_list ) ) {
756 continue;
757 }
758 $html['licenses_without_addon'] .= self::html_by_license( $license );
759 }
760 }
761
762 ksort( $html );
763
764 // After sorting order will be all_access_licensed -> licensed -> unlicensed
765
766 return implode( '', $html );
767 }
768
769 /**
770 * Get add-on item html
771 * Note: only for internal use
772 *
773 * @param $plugin
774 *
775 * @return string
776 * @since 2.5.0
777 */
778 public static function html_by_plugin( $plugin ) {
779 // Bailout.
780 if ( empty( $plugin ) ) {
781 return '';
782 }
783
784 ob_start();
785 $license = self::get_license_by_plugin_dirname( $plugin['Dir'] );
786
787 $default_plugin = [
788 'ChangeLogSlug' => $plugin['Dir'],
789 'DownloadURL' => '',
790 ];
791
792 if ( false !== strpos( $default_plugin['ChangeLogSlug'], '-gateway' ) ) {
793 // We found that each gateway addon does not have `-gateway` in changelog file slug
794 $default_plugin['ChangeLogSlug'] = str_replace( '-gateway', '', $default_plugin['ChangeLogSlug'] );
795 }
796
797 if ( $license ) {
798 $license['renew_url'] = self::$checkout_url . "?edd_license_key={$license['license_key']}";
799 $default_plugin['ChangeLogSlug'] = $license['readme'];
800 $default_plugin['DownloadURL'] = $license['download'];
801 }
802
803 $plugin['License'] = $license = wp_parse_args(
804 $license,
805 [
806 'item_name' => str_replace( 'give-', '', $plugin['Dir'] ),
807 'purchase_link' => $plugin['PluginURI'],
808 ]
809 );
810
811 $plugin = wp_parse_args( $plugin, $default_plugin );
812 ?>
813 <div class="give-addon-wrap">
814 <div class="give-addon-inner">
815 <?php echo self::html_license_row( $license, $plugin ); ?>
816 <?php echo self::html_plugin_row( $plugin ); ?>
817 </div>
818 </div>
819 <?php
820
821 return ob_get_clean();
822 }
823
824 /**
825 * Get add-on item html
826 * Note: only for internal use
827 *
828 * @param array $license
829 *
830 * @return string
831 * @since 2.5.0
832 */
833 private static function html_by_license( $license ) {
834 ob_start();
835
836 $license['renew_url'] = self::$checkout_url . "?edd_license_key={$license['license_key']}";
837 ?>
838 <div class="give-addon-wrap">
839 <div class="give-addon-inner">
840 <?php
841 echo self::html_license_row( $license );
842
843 $addons = $license['download'];
844
845 if ( empty( $license['is_all_access_pass'] ) ) {
846 $addons = [ $license ];
847 }
848
849 foreach ( $addons as $addon ) {
850 $default_plugin = [
851 // In single license key we will get item_name instead of name.
852 'Name' => ! empty( $addon['item_name'] ) ? $addon['item_name'] : $addon['name'],
853
854 'ChangeLogSlug' => $addon['readme'],
855 'Version' => $addon['current_version'],
856 'Status' => 'not installed',
857
858 // In single license key we will get download instead of file.
859 'DownloadURL' => ! empty( $addon['download'] ) ? $addon['download'] : $addon['file'],
860
861 ];
862
863 $plugin = wp_parse_args(
864 self::get_plugin_by_slug( $addon['plugin_slug'] ),
865 $default_plugin
866 );
867
868 $plugin['Name'] = false !== strpos( $plugin['Name'], 'Give' )
869 ? $plugin['Name']
870 : self::build_plugin_name_from_slug( $addon['plugin_slug'] );
871
872 $plugin['License'] = $license;
873
874 echo self::html_plugin_row( $plugin );
875 }
876 ?>
877 </div>
878 </div>
879 <?php
880
881 return ob_get_clean();
882 }
883
884
885 /**
886 * license row html
887 *
888 * @param array $license
889 * @param array $plugin
890 *
891 * @return string
892 * @since 2.5.0
893 */
894 private static function html_license_row( $license, $plugin = [] ) {
895 ob_start();
896
897 $is_license = $license && ! empty( $license['license_key'] );
898 $license_key = $is_license ? $license['license_key'] : '';
899 $license_is_inactive = $license_key && ! in_array( $license['license'], [ 'valid', 'expired' ] );
900 $expires_timestamp = $is_license ? strtotime( $license['expires'] ) : '';
901 $is_license_expired = $is_license && ( 'expired' === $license['license'] || $expires_timestamp < time() );
902 $addon_dir = ! empty( $plugin['Dir'] ) ? $plugin['Dir'] : ( ! empty( $license['plugin_slug'] ) ? $license['plugin_slug'] : '' );
903 ?>
904 <div class="give-license-row give-clearfix">
905 <div class="give-license-notice-container"></div>
906 <div class="give-license-top give-clearfix">
907
908 <div class="give-license-top-column give-license-key-field-wrap">
909
910 <div class="give-license__key<?php echo $license_key ? ' give-has-license-key' : ''; ?>">
911 <?php $value = $license_key ? give_hide_char( $license['license_key'], 5 ) : ''; ?>
912 <label for="give-license-addon-key-field" class="give-license-top-header"><?php _e( 'License Key', 'give' ); ?></label>
913 <input id="give-license-addon-key-field" type="text" autocomplete="off" value="<?php echo $value; ?>"<?php echo $value ? ' readonly' : ''; ?>>
914 <?php if ( ! $license_key ) : ?>
915 <button class="give-button__license-activate button-primary" data-addon="<?php echo $addon_dir; ?>">
916 <?php _e( 'Activate', 'give' ); ?>
917 </button>
918 <?php elseif ( $license_is_inactive ) : ?>
919 <button class="give-button__license-reactivate button-primary" data-addon="<?php echo $addon_dir; ?>" data-license="<?php echo $license['license_key']; ?>">
920 <?php _e( 'Reactivate', 'give' ); ?>
921 </button>
922 <?php else : ?>
923
924 <?php
925 echo sprintf(
926 '<button class="give-license__deactivate button button-secondary" data-license-key="%2$s" data-item-name="%3$s" data-plugin-dirname="%5$s" data-nonce="%4$s">%1$s</button>',
927 __( 'Deactivate', 'give' ),
928 $license['license_key'],
929 $license['item_name'],
930 wp_create_nonce( "give-deactivate-license-{$license['item_name']}" ),
931 ! empty( $license['plugin_slug'] ) ? $license['plugin_slug'] : ''
932 );
933 ?>
934
935 <?php endif; ?>
936
937 <div class="give-license__status">
938 <?php
939 echo $license_key && ! $license_is_inactive
940 ? sprintf(
941 '<span class="dashicons dashicons-%2$s"></span>&nbsp;%1$s',
942 $is_license_expired
943 ? __( 'License is expired. Please activate your license key.', 'give' )
944 : __( 'License is active and you are receiving updates and support.', 'give' ),
945 $is_license_expired
946 ? 'no'
947 : 'yes'
948 )
949 : sprintf(
950 '<span class="dashicons dashicons-no"></span> %1$s %2$s',
951 __( 'License is inactive.', 'give' ),
952 $license_is_inactive
953 ? sprintf(
954 __( 'Please <a href="%1$s" target="_blank">Visit your dashboard</a> to check this license details and activate this license to receive updates and support.', 'give' ),
955 self::get_account_url()
956 )
957 : __( 'Please activate your license key.', 'give' )
958 );
959 ?>
960 </div>
961 </div>
962 </div>
963
964 <div class="give-license-top-column give-license-info-field-wrap">
965 <h3 class="give-license-top-header"><?php _e( 'License Information', 'give' ); ?></h3>
966 <?php
967 // @todo: handle all license status;
968 if ( $license_key ) :
969 ?>
970
971 <?php if ( $license_key ) : ?>
972 <?php
973 echo sprintf(
974 '<p class="give-license-renewal-date"><span class="dashicons dashicons-calendar-alt"></span> <strong>%1$s</strong> %2$s</p>',
975 $is_license_expired ? __( 'Expired:', 'give' ) : __( 'Renews:', 'give' ),
976 date( give_date_format(), $expires_timestamp )
977 );
978 ?>
979 <?php endif; ?>
980
981 <?php
982 if ( $is_license_expired ) {
983 // @todo: need to test renew license link
984 echo sprintf(
985 '<a href="%1$s" target="_blank">%2$s</a>',
986 $license['renew_url'],
987 __( 'Renew to manage sites', 'give' )
988 );
989 } elseif ( $license_key ) {
990 if ( ! $license['activations_left'] ) {
991 echo sprintf(
992 '<span class="give-license-activations-left">%1$s</span>',
993 __( 'No activations remaining', 'give' )
994 );
995 } else {
996 echo sprintf(
997 '<span class="give-license-activations-left"><span class="give-license-activations-remaining-icon wp-ui-highlight">%1$s</span> %2$s</span>',
998 $license['activations_left'],
999 _n( 'Activation Remaining', 'Activations Remaining', $license['activations_left'], 'give' )
1000 );
1001 }
1002 }
1003 ?>
1004 <?php else : ?>
1005
1006 <p class="give-field-description"><?php _e( 'This is an unlicensed add-on and is not receiving updates or support. Please activate your license key to fix the issue.', 'give' ); ?></p>
1007
1008 <?php endif; ?>
1009 </div>
1010
1011 <div class="give-license-top-column">
1012 <h3 class="give-license-top-header"><?php _e( 'License Actions', 'give' ); ?></h3>
1013
1014 <?php
1015 // Purchase license link.
1016 if ( ! $license_key ) :
1017 ?>
1018 <?php
1019 echo sprintf(
1020 '<a class="give-button button-secondary" href="%1$s" target="_blank">%2$s</a>',
1021 $license['purchase_link'],
1022 __( 'Purchase License', 'give' )
1023 );
1024 ?>
1025 <?php endif; ?>
1026
1027 <?php
1028 // Manage license link on GiveWP.com
1029 if ( ! $is_license_expired && $license_key ) {
1030 echo sprintf(
1031 '<a href="%1$spurchase-history/?license_id=%2$s&action=manage_licenses&payment_id=%3$s" target="_blank" class="give-license-action-link">%4$s</a>',
1032 trailingslashit( self::get_website_url() ),
1033 $license['license_id'],
1034 $license['payment_id'],
1035 __( 'Manage License', 'give' )
1036 );
1037 echo sprintf(
1038 '<a href="%1$spriority-support/" target="_blank" class="give-license-action-link">%2$s</a>',
1039 trailingslashit( self::get_website_url() ),
1040 __( 'Access Support', 'give' )
1041 );
1042 }
1043 ?>
1044
1045 </div>
1046 </div>
1047 </div>
1048 <?php
1049 return ob_get_clean();
1050 }
1051
1052
1053 /**
1054 * Plugin row html
1055 *
1056 * @param array $plugin
1057 *
1058 * @return string
1059 * @since 2.5.0
1060 */
1061 public static function html_plugin_row( $plugin ) {
1062 // Bailout.
1063 if ( ! $plugin ) {
1064 return '';
1065 }
1066
1067 $is_license = $plugin['License'] && ! empty( $plugin['License']['license_key'] );
1068 $expires_timestamp = $is_license ? strtotime( $plugin['License']['expires'] ) : '';
1069 $is_license_expired = $is_license && ( 'expired' === $plugin['License']['license'] || $expires_timestamp < time() );
1070 ob_start();
1071 ?>
1072 <div class="give-addon-info-wrap give-clearfix">
1073
1074 <div class="give-addon-info-left">
1075 <span class="give-addon-name">
1076 <?php echo $plugin['Name']; ?>
1077 </span>
1078 <span class="give-addon-version">
1079 <?php echo sprintf( '%1$s %2$s', __( 'Version', 'give' ), $plugin['Version'] ); ?>
1080 </span>
1081 </div>
1082
1083 <div class="give-addon-info-right">
1084 <?php
1085 echo sprintf(
1086 '<a href="%1$s" class="give-ajax-modal give-addon-view-changelog" title="%3$s">%2$s</a>',
1087 give_modal_ajax_url(
1088 [
1089 'url' => filter_var( $plugin['ChangeLogSlug'], FILTER_VALIDATE_URL )
1090 ? urldecode_deep( $plugin['ChangeLogSlug'] )
1091 : urlencode_deep( give_get_addon_readme_url( $plugin['ChangeLogSlug'] ) ),
1092 'show_changelog' => 1,
1093 ]
1094 ),
1095 __( 'View Changelog', 'give' ),
1096 __( 'Changelog of', 'give' ) . " {$plugin['Name']}"
1097 );
1098 ?>
1099
1100 <?php
1101 // Activation status.
1102 if ( in_array( $plugin['Status'], [ 'active', 'inactive' ] ) ) {
1103 echo sprintf(
1104 '<span class="give-addon-activation-status give-addon-activation-status__%1$s">%1$s</span>',
1105 'active' === $plugin['Status'] ? __( 'activated', 'give' ) : __( 'installed', 'give' )
1106 );
1107 }
1108
1109 printf(
1110 '<%3$s class="give-button button button-secondary button-small" href="%1$s"%4$s><span class="dashicons dashicons-download"></span>%2$s</%3$s>',
1111 $plugin['DownloadURL'],
1112 __( 'Download', 'give' ),
1113 $is_license_expired || ! $plugin['DownloadURL'] ? 'button' : 'a',
1114 $is_license_expired || ! $plugin['DownloadURL'] ? ' disabled' : ''
1115 );
1116 ?>
1117 </div>
1118 </div>
1119 <?php
1120
1121 return ob_get_clean();
1122 }
1123
1124
1125 /**
1126 * Get refresh license status
1127 *
1128 * @return mixed|void
1129 * @since 2.5.0
1130 */
1131 public static function refresh_license_status() {
1132 return get_option(
1133 'give_licenses_refreshed_last_checked',
1134 [
1135 'compare' => date( 'Ymd' ),
1136 'time' => time(),
1137 'count' => 0,
1138 ]
1139 );
1140 }
1141
1142 /**
1143 * Get all download slugs from all access pass key.
1144 * Note: only for internal use and will be refactored in the future.
1145 *
1146 * @param array $license All access pass license data
1147 *
1148 * @return string[]
1149 * @since 2.6.3
1150 */
1151 public static function getAddonSlugsFromAllAccessPassLicense( $license ) {
1152 $result = [];
1153
1154 foreach ( $license['download'] as $download ) {
1155 $result[] = $download['plugin_slug'];
1156 }
1157
1158 return $result;
1159 }
1160
1161 /**
1162 * Returns the API URL for license requests, checking for a constant first.
1163 *
1164 * @since 3.20.0
1165 */
1166 public static function get_api_url(): string
1167 {
1168 if (defined('GIVE_LICENSE_API_URL')) {
1169 return GIVE_LICENSE_API_URL;
1170 }
1171
1172 return self::$api_url;
1173 }
1174 }
1175
1176 endif; // end class_exists check.
1177