Issues (4296)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/class-give-license-handler.php (21 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Give License handler
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/License
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
if ( ! class_exists( 'Give_License' ) ) :
18
19
	/**
20
	 * Give_License Class
21
	 *
22
	 * This class simplifies the process of adding license information
23
	 * to new Give add-ons.
24
	 *
25
	 * @since 1.0
26
	 */
27
	class Give_License {
28
29
		/**
30
		 * File
31
		 *
32
		 * @access private
33
		 * @since  1.0
34
		 *
35
		 * @var    string
36
		 */
37
		private $file;
38
39
		/**
40
		 * License
41
		 *
42
		 * @access private
43
		 * @since  1.0
44
		 *
45
		 * @var    string
46
		 */
47
		private $license;
48
49
		/**
50
		 * Item name
51
		 *
52
		 * @access private
53
		 * @since  1.0
54
		 *
55
		 * @var    string
56
		 */
57
		private $item_name;
58
59
		/**
60
		 * Item ID
61
		 *
62
		 * @access private
63
		 * @since  2.2.4
64
		 *
65
		 * @var    int
66
		 */
67
		private $item_id;
68
69
		/**
70
		 * License Information object.
71
		 *
72
		 * @access private
73
		 * @since  1.7
74
		 *
75
		 * @var    object
76
		 */
77
		private $license_data;
78
79
		/**
80
		 * Item shortname
81
		 *
82
		 * @access private
83
		 * @since  1.0
84
		 *
85
		 * @var    string
86
		 */
87
		private $item_shortname;
88
89
		/**
90
		 * Version
91
		 *
92
		 * @access private
93
		 * @since  1.0
94
		 *
95
		 * @var    string
96
		 */
97
		private $version;
98
99
		/**
100
		 * Author
101
		 *
102
		 * @access private
103
		 * @since  1.0
104
		 *
105
		 * @var    string
106
		 */
107
		private $author;
108
109
		/**
110
		 * API URL
111
		 *
112
		 * @access private
113
		 * @since  1.0
114
		 *
115
		 * @var    string
116
		 */
117
		private $api_url = 'https://givewp.com/edd-sl-api/';
118
119
		/**
120
		 * array of licensed addons
121
		 *
122
		 * @since  2.1.4
123
		 * @access private
124
		 *
125
		 * @var    array
126
		 */
127
		private static $licensed_addons = array();
128
129
		/**
130
		 * Account URL
131
		 *
132
		 * @access private
133
		 * @since  1.7
134
		 *
135
		 * @var null|string
136
		 */
137
		private $account_url = 'https://givewp.com/my-account/';
138
139
		/**
140
		 * Checkout URL
141
		 *
142
		 * @access private
143
		 * @since  1.7
144
		 *
145
		 * @var null|string
146
		 */
147
		private $checkout_url = 'https://givewp.com/checkout/';
148
149
		/**
150
		 * Class Constructor
151
		 *
152
		 * Set up the Give License Class.
153
		 *
154
		 * @access public
155
		 * @since  1.0
156
		 *
157
		 * @param string $_file
158
		 * @param string $_item_name
159
		 * @param string $_version
160
		 * @param string $_author
161
		 * @param string $_optname
162
		 * @param string $_api_url
163
		 * @param string $_checkout_url
164
		 * @param string $_account_url
165
		 * @param int    $_item_id
166
		 */
167
		public function __construct(
168
			$_file,
169
			$_item_name,
170
			$_version,
171
			$_author,
172
			$_optname = null,
0 ignored issues
show
The parameter $_optname is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
173
			$_api_url = null,
174
			$_checkout_url = null,
175
			$_account_url = null,
176
			$_item_id = null
177
		) {
178
179
			// Only load in wp-admin.
180
			if ( ! is_admin() ) {
181
				return;
182
			}
183
184
			if ( is_numeric( $_item_id ) ) {
185
				$this->item_id = absint( $_item_id );
186
			}
187
188
			$give_options = give_get_settings();
189
190
			$this->file             = $_file;
191
			$this->item_name        = $_item_name;
192
			$this->item_shortname   = self::get_short_name( $this->item_name );
193
			$this->version          = $_version;
194
			$this->license          = isset( $give_options[ $this->item_shortname . '_license_key' ] ) ? trim( $give_options[ $this->item_shortname . '_license_key' ] ) : '';
195
			$this->license_data     = __give_get_active_license_info( $this->item_shortname );
0 ignored issues
show
Documentation Bug introduced by
It seems like __give_get_active_licens...($this->item_shortname) of type array is incompatible with the declared type object of property $license_data.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
196
			$this->author           = $_author;
197
			$this->api_url          = is_null( $_api_url ) ? $this->api_url : $_api_url;
198
			$this->checkout_url     = is_null( $_checkout_url ) ? $this->checkout_url : $_checkout_url;
199
			$this->account_url      = is_null( $_account_url ) ? $this->account_url : $_account_url;
200
			$this->auto_updater_obj = null;
201
202
			// Add Setting for Give Add-on activation status.
203
			$is_addon_activated = get_option( 'give_is_addon_activated' );
204
			if ( ! $is_addon_activated && is_object( $this ) ) {
205
				update_option( 'give_is_addon_activated', true, false );
206
				Give_Cache::set( 'give_cache_hide_license_notice_after_activation', true, DAY_IN_SECONDS );
207
			}
208
209
			// Add plugin to registered licenses list.
210
			array_push( self::$licensed_addons, plugin_basename( $this->file ) );
211
212
			// Setup hooks
213
			$this->includes();
214
			$this->hooks();
215
216
		}
217
218
219
		/**
220
		 * Get plugin shortname
221
		 *
222
		 * @since  2.1.0
223
		 * @access public
224
		 *
225
		 * @param $plugin_name
226
		 *
227
		 * @return string
228
		 */
229
		public static function get_short_name( $plugin_name ) {
230
			$plugin_name = trim( str_replace( 'Give - ', '', $plugin_name ) );
231
			$plugin_name = 'give_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $plugin_name ) ) );
232
233
			return $plugin_name;
234
		}
235
236
		/**
237
		 * Includes
238
		 *
239
		 * Include the updater class.
240
		 *
241
		 * @access private
242
		 * @since  1.0
243
		 *
244
		 * @return void
245
		 */
246
		private function includes() {
247
248
			if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
249
				require_once 'admin/EDD_SL_Plugin_Updater.php';
250
			}
251
		}
252
253
		/**
254
		 * Hooks
255
		 *
256
		 * Setup license hooks.
257
		 *
258
		 * @access private
259
		 * @since  1.0
260
		 *
261
		 * @return void
262
		 */
263
		private function hooks() {
264
265
			// Register settings.
266
			add_filter( 'give_settings_licenses', array( $this, 'settings' ), 1 );
267
268
			// Activate license key on settings save.
269
			add_action( 'admin_init', array( $this, 'activate_license' ), 10 );
270
271
			// Deactivate license key.
272
			add_action( 'admin_init', array( $this, 'deactivate_license' ), 11 );
273
274
			// Updater.
275
			add_action( 'admin_init', array( $this, 'auto_updater' ), 0 );
276
			add_action( 'admin_notices', array( $this, 'notices' ) );
277
278
			// Check license weekly.
279
			Give_Cron::add_weekly_event( array( $this, 'weekly_license_check' ) );
280
281
			// Check subscription weekly.
282
			Give_Cron::add_weekly_event( array( $this, 'weekly_subscription_check' ) );
283
284
			// Show addon notice on plugin page.
285
			$plugin_name = explode( 'plugins/', $this->file );
286
			$plugin_name = end( $plugin_name );
287
			add_action( "after_plugin_row_{$plugin_name}", array( $this, 'plugin_page_notices' ), 10, 3 );
288
289
		}
290
291
292
		/**
293
		 * Auto Updater
294
		 *
295
		 * @access private
296
		 * @since  1.0
297
		 *
298
		 * @return void
299
		 */
300
		public function auto_updater() {
301
302
			if ( ! empty( $this->item_id ) ) {
303
				$args['item_id'] = $this->item_id;
304
			} else {
305
				$args['item_name'] = $this->item_name;
306
			}
307
308
			// Setup the updater.
309
			$this->auto_updater_obj = new EDD_SL_Plugin_Updater(
310
				$this->api_url,
311
				$this->file,
312
				array(
313
					'version'   => $this->version,
314
					'license'   => $this->license,
315
					'item_name' => $this->item_name,
316
					'author'    => $this->author,
317
				)
318
			);
319
		}
320
321
		/**
322
		 * License Settings
323
		 *
324
		 * Add license field to settings.
325
		 *
326
		 * @access public
327
		 * @since  1.0
328
		 *
329
		 * @param  array $settings License settings.
330
		 *
331
		 * @return array           License settings.
332
		 */
333
		public function settings( $settings ) {
334
335
			$give_license_settings = array(
336
				array(
337
					'name'    => $this->item_name,
338
					'id'      => $this->item_shortname . '_license_key',
339
					'desc'    => '',
340
					'type'    => 'license_key',
341
					'options' => array(
342
						'license'      => get_option( $this->item_shortname . '_license_active' ),
343
						'shortname'    => $this->item_shortname,
344
						'item_name'    => $this->item_name,
345
						'api_url'      => $this->api_url,
346
						'checkout_url' => $this->checkout_url,
347
						'account_url'  => $this->account_url,
348
					),
349
					'size'    => 'regular',
350
				),
351
			);
352
353
			return array_merge( $settings, $give_license_settings );
354
		}
355
356
		/**
357
		 * License Settings Content
358
		 *
359
		 * Add Some Content to the Licensing Settings.
360
		 *
361
		 * @access public
362
		 * @since  1.0
363
		 *
364
		 * @param  array $settings License settings content.
365
		 *
366
		 * @return array           License settings content.
367
		 */
368
		public function license_settings_content( $settings ) {
369
370
			$give_license_settings = array(
371
				array(
372
					'name' => __( 'Add-on Licenses', 'give' ),
373
					'desc' => '<hr>',
374
					'type' => 'give_title',
375
					'id'   => 'give_title',
376
				),
377
			);
378
379
			return array_merge( $settings, $give_license_settings );
380
		}
381
382
		/**
383
		 * Activate License
384
		 *
385
		 * Activate the license key.
386
		 *
387
		 * @access public
388
		 * @since  1.0
389
		 *
390
		 * @return void
391
		 */
392
		public function activate_license() {
393
			// Bailout.
394
			if ( ! $this->__is_user_can_edit_license() ) {
395
				return;
396
			}
397
398
			// Allow third party addon developers to handle license activation.
399
			if ( $this->__is_third_party_addon() ) {
400
				do_action( 'give_activate_license', $this );
401
402
				return;
403
			}
404
405
			// Delete previous license setting if a empty license key submitted.
406
			if ( empty( $_POST[ "{$this->item_shortname}_license_key" ] ) ) {
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
407
				$this->unset_license();
408
409
				return;
410
			}
411
412
			// Do not simultaneously activate add-ons if the user want to deactivate a specific add-on.
413
			if ( $this->is_deactivating_license() ) {
414
				return;
415
			}
416
417
			// Check if plugin previously installed.
418
			if ( $this->is_valid_license() ) {
419
				return;
420
			}
421
422
			// Get license key.
423
			$this->license = sanitize_text_field( $_POST[ $this->item_shortname . '_license_key' ] );
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_POST
Loading history...
424
425
			// Delete previous license key from subscription if previously added.
426
			$this->__remove_license_key_from_subscriptions();
427
428
			// Make sure there are no api errors.
429
			if ( ! ( $license_data = $this->get_license_info( 'activate_license' ) ) ) {
430
				return;
431
			}
432
433
			// Make sure license is valid.
434
			// return because admin will want to activate license again.
435
			if ( ! $this->is_license( $license_data ) ) {
436
				// Add license key.
437
				give_update_option( "{$this->item_shortname}_license_key", $this->license );
438
439
				return;
440
			}
441
442
			// Tell WordPress to look for updates.
443
			set_site_transient( 'update_plugins', null );
444
445
			// Add license data.
446
			update_option( "{$this->item_shortname}_license_active", $license_data, false );
447
448
			// Add license key.
449
			give_update_option( "{$this->item_shortname}_license_key", $this->license );
450
451
			// Check subscription for license key and store this to db (if any).
452
			$this->__single_subscription_check();
453
		}
454
455
		/**
456
		 * Deactivate License
457
		 *
458
		 * Deactivate the license key.
459
		 *
460
		 * @access public
461
		 * @since  1.0
462
		 *
463
		 * @return void
464
		 */
465
		public function deactivate_license() {
466
			// Bailout.
467
			if ( ! $this->__is_user_can_edit_license() ) {
468
				return;
469
			}
470
471
			// Allow third party add-on developers to handle license deactivation.
472
			if ( $this->__is_third_party_addon() ) {
473
				do_action( 'give_deactivate_license', $this );
474
475
				return;
476
			}
477
478
			// Run on deactivate button press.
479
			if ( isset( $_POST[ $this->item_shortname . '_license_key_deactivate' ] ) ) {
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
480
				$this->unset_license();
481
			}
482
		}
483
484
		/**
485
		 * Check if license key is valid once per week.
486
		 *
487
		 * @access public
488
		 * @since  1.7
489
		 *
490
		 * @return void
491
		 */
492
		public function weekly_license_check() {
493
494
			if (
495
				! empty( $_POST['give_settings'] ) ||
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
496
				empty( $this->license )
497
			) {
498
				return;
499
			}
500
501
			// Allow third party add-on developers to handle their license check.
502
			if ( $this->__is_third_party_addon() ) {
503
				do_action( 'give_weekly_license_check', $this );
504
505
				return;
506
			}
507
508
			// Make sure there are no api errors.
509
			if ( ! ( $license_data = $this->get_license_info( 'check_license' ) ) ) {
510
				return;
511
			}
512
513
			// Bailout.
514
			if ( ! $this->is_license( $license_data ) ) {
515
				return;
516
			}
517
518
			update_option( $this->item_shortname . '_license_active', $license_data, false );
519
520
			return;
521
		}
522
523
		/**
524
		 * Check subscription validation once per week
525
		 *
526
		 * @access public
527
		 * @since  1.7
528
		 *
529
		 * @return void
530
		 */
531
		public function weekly_subscription_check() {
532
			// Bailout.
533
			if (
534
				! empty( $_POST['give_settings'] )
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
535
				|| empty( $this->license )
536
			) {
537
				return;
538
			}
539
540
			// Remove old subscription data.
541
			if ( absint( get_option( '_give_subscriptions_edit_last', true ) ) < current_time( 'timestamp', 1 ) ) {
542
				delete_option( 'give_subscriptions' );
543
				update_option( '_give_subscriptions_edit_last', strtotime( '+ 1 day', current_time( 'timestamp', 1 ) ), false );
544
			}
545
546
			// Allow third party add-on developers to handle their subscription check.
547
			if ( $this->__is_third_party_addon() ) {
548
				do_action( 'give_weekly_subscription_check', $this );
549
550
				return;
551
			}
552
553
			$this->__single_subscription_check();
554
		}
555
556
		/**
557
		 * Check if license key is part of subscription or not
558
		 *
559
		 * @access private
560
		 * @since  1.7
561
		 *
562
		 * @return void
563
		 */
564
		private function __single_subscription_check() {
0 ignored issues
show
Method name "Give_License::__single_subscription_check" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
565
			if ( empty( $this->license ) ) {
566
				return;
567
			}
568
569
			/**
570
			 * Make sure there are no api errors.
571
			 *
572
			 * Do not get confused with edd_action check_subscription.
573
			 * By default edd software licensing api does not have api to check subscription.
574
			 * This is a custom feature to check subscriptions.
575
			 */
576
			$subscription_data = $this->get_license_info( 'check_subscription', true );
577
578
			if ( ! empty( $subscription_data['success'] ) && absint( $subscription_data['success'] ) ) {
579
580
				$subscriptions = get_option( 'give_subscriptions', array() );
581
582
				// Update subscription data only if subscription does not exist already.
583
				$subscriptions[ $subscription_data['id'] ] = $subscription_data;
584
585
				// Initiate default set of license for subscription.
586
				if ( ! isset( $subscriptions[ $subscription_data['id'] ]['licenses'] ) ) {
587
					$subscriptions[ $subscription_data['id'] ]['licenses'] = array();
588
				}
589
590
				// Store licenses for subscription.
591
				if ( ! in_array( $this->license, $subscriptions[ $subscription_data['id'] ]['licenses'] ) ) {
592
					$subscriptions[ $subscription_data['id'] ]['licenses'][] = $this->license;
593
				}
594
595
				update_option( 'give_subscriptions', $subscriptions, false );
596
			}
597
		}
598
599
		/**
600
		 * Admin notices for errors
601
		 *
602
		 * @access public
603
		 * @since  1.0
604
		 *
605
		 * @return void
606
		 */
607
		public function notices() {
608
609
			if ( ! current_user_can( 'manage_give_settings' ) ) {
610
				return;
611
			}
612
613
			// Do not show licenses notices on license tab.
614
			if ( 'licenses' === give_get_current_setting_tab() ) {
615
				return;
616
			}
617
618
			static $showed_invalid_message;
619
			static $showed_subscriptions_message;
620
			static $addon_license_key_in_subscriptions;
621
622
			// Set default value.
623
			$addon_license_key_in_subscriptions = ! empty( $addon_license_key_in_subscriptions ) ? $addon_license_key_in_subscriptions : array();
624
			$messages                           = array();
625
626
			// Check whether admin has Give Add-on activated since 24 hours?
627
			$is_license_notice_hidden = Give_Cache::get( 'give_cache_hide_license_notice_after_activation' );
628
629
			// Display Invalid License notice, if its more than 24 hours since first Give Add-on activation.
630
			if (
631
				empty( $this->license )
632
				&& empty( $showed_invalid_message )
633
				&& ( false === $is_license_notice_hidden )
634
			) {
635
636
				Give()->notices->register_notice(
637
					array(
638
						'id'               => 'give-invalid-license',
639
						'type'             => 'error',
640
						'description'      => sprintf(
641
							__( 'You have invalid or expired license keys for one or more Give Add-ons. Please go to the <a href="%s">licenses page</a> to correct this issue.', 'give' ),
642
							admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' )
643
						),
644
						'dismissible_type' => 'user',
645
						'dismiss_interval' => 'shortly',
646
					)
647
				);
648
649
				$showed_invalid_message = true;
650
651
			}
652
653
			// Get subscriptions.
654
			$subscriptions = get_option( 'give_subscriptions' );
655
656
			// Show subscription messages.
657
			if ( ! empty( $subscriptions ) && ! $showed_subscriptions_message ) {
658
659
				foreach ( $subscriptions as $subscription ) {
660
					// Subscription expires timestamp.
661
					$subscription_expires = strtotime( $subscription['expires'] );
662
663
					// Start showing subscriptions message before one week of renewal date.
664
					if ( strtotime( '- 7 days', $subscription_expires ) > current_time( 'timestamp', 1 ) ) {
665
						continue;
666
					}
667
668
					// Check if subscription message already exist in messages.
669
					if ( array_key_exists( $subscription['id'], $messages ) ) {
670
						continue;
671
					}
672
673
					// Check if license already expired.
674
					if ( strtotime( $subscription['expires'] ) < current_time( 'timestamp', 1 ) ) {
675
						Give()->notices->register_notice(
676
							array(
677
								'id'               => "give-expired-subscription-{$subscription['id']}",
678
								'type'             => 'error',
679
								'description'      => sprintf(
680
									__( 'Your Give add-on license expired for payment <a href="%1$s" target="_blank">#%2$d</a>. <a href="%3$s" target="_blank">Click to renew an existing license</a> or %4$s.', 'give' ),
681
									urldecode( $subscription['invoice_url'] ),
682
									$subscription['payment_id'],
683
									"{$this->checkout_url}?edd_license_key={$subscription['license_key']}&utm_campaign=admin&utm_source=licenses&utm_medium=expired",
684
									Give()->notices->get_dismiss_link(
685
										array(
686
											'title' => __( 'Click here if already renewed', 'give' ),
687
											'dismissible_type' => 'user',
688
											'dismiss_interval' => 'permanent',
689
										)
690
									)
691
								),
692
								'dismissible_type' => 'user',
693
								'dismiss_interval' => 'shortly',
694
							)
695
						);
696
					} else {
697
						Give()->notices->register_notice(
698
							array(
699
								'id'               => "give-expires-subscription-{$subscription['id']}",
700
								'type'             => 'error',
701
								'description'      => sprintf(
702
									__( 'Your Give add-on license will expire in %1$s for payment <a href="%2$s" target="_blank">#%3$d</a>. <a href="%4$s" target="_blank">Click to renew an existing license</a> or %5$s.', 'give' ),
703
									human_time_diff( current_time( 'timestamp', 1 ), strtotime( $subscription['expires'] ) ),
704
									urldecode( $subscription['invoice_url'] ),
705
									$subscription['payment_id'],
706
									"{$this->checkout_url}?edd_license_key={$subscription['license_key']}&utm_campaign=admin&utm_source=licenses&utm_medium=expired",
707
									Give()->notices->get_dismiss_link(
708
										array(
709
											'title' => __( 'Click here if already renewed', 'give' ),
710
											'dismissible_type' => 'user',
711
											'dismiss_interval' => 'permanent',
712
										)
713
									)
714
								),
715
								'dismissible_type' => 'user',
716
								'dismiss_interval' => 'shortly',
717
							)
718
						);
719
					}
720
721
					// Stop validation for these license keys.
722
					$addon_license_key_in_subscriptions = array_merge( $addon_license_key_in_subscriptions, $subscription['licenses'] );
723
				}// End foreach().
724
				$showed_subscriptions_message = true;
725
			}// End if().
726
727
			// Show Non Subscription Give Add-on messages.
728
			if (
729
				! in_array( $this->license, $addon_license_key_in_subscriptions )
730
				&& ! empty( $this->license )
731
				&& empty( $showed_invalid_message )
732
				&& ! $this->is_valid_license()
733
			) {
734
735
				Give()->notices->register_notice(
736
					array(
737
						'id'               => 'give-invalid-license',
738
						'type'             => 'error',
739
						'description'      => sprintf(
740
							__( 'You have invalid or expired license keys for one or more Give Add-ons. Please go to the <a href="%s">licenses page</a> to correct this issue.', 'give' ),
741
							admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' )
742
						),
743
						'dismissible_type' => 'user',
744
						'dismiss_interval' => 'shortly',
745
					)
746
				);
747
748
				$showed_invalid_message = true;
749
750
			}
751
		}
752
753
		/**
754
		 * Check if license is valid or not.
755
		 *
756
		 * @since  1.7
757
		 * @access public
758
		 *
759
		 * @param null|object $licence_data
760
		 *
761
		 * @return bool
762
		 */
763
		public function is_valid_license( $licence_data = null ) {
764
			$license_data = empty( $licence_data ) ? $this->license_data : $licence_data;
765
766
			if ( apply_filters( 'give_is_valid_license', ( $this->is_license( $license_data ) && 'valid' === $license_data->license ) ) ) {
767
				return true;
768
			}
769
770
			return false;
771
		}
772
773
774
		/**
775
		 * Check if license is license object of no.
776
		 *
777
		 * @since  1.7
778
		 * @access public
779
		 *
780
		 * @param null|object $licence_data
781
		 *
782
		 * @return bool
783
		 */
784
		public function is_license( $licence_data = null ) {
785
			$license_data = empty( $licence_data ) ? $this->license_data : $licence_data;
786
787
			if ( apply_filters( 'give_is_license', ( is_object( $license_data ) && ! empty( $license_data ) && property_exists( $license_data, 'license' ) ) ) ) {
788
				return true;
789
			}
790
791
			return false;
792
		}
793
794
		/**
795
		 * Check if license is valid or not.
796
		 *
797
		 * @access private
798
		 * @since  1.7
799
		 *
800
		 * @return bool
801
		 */
802
		private function __is_third_party_addon() {
0 ignored issues
show
Method name "Give_License::__is_third_party_addon" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
803
			return ( false === strpos( $this->api_url, 'givewp.com/' ) );
804
		}
805
806
		/**
807
		 * Remove license key from subscription.
808
		 *
809
		 * This function mainly uses when admin user deactivate license key,
810
		 * then we do not need subscription information for that license key.
811
		 *
812
		 * @access private
813
		 * @since  1.7
814
		 *
815
		 * @return bool
816
		 */
817
		private function __remove_license_key_from_subscriptions() {
0 ignored issues
show
Method name "Give_License::__remove_license_key_from_subscriptions" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
818
			$subscriptions = get_option( 'give_subscriptions', array() );
819
820
			// Bailout.
821
			if ( empty( $this->license ) ) {
822
				return false;
823
			}
824
825
			if ( ! empty( $subscriptions ) ) {
826
				foreach ( $subscriptions as $subscription_id => $subscription ) {
827
					$license_index = array_search( $this->license, $subscription['licenses'] );
828
					if ( false !== $license_index ) {
829
						// Remove license key.
830
						unset( $subscriptions[ $subscription_id ]['licenses'][ $license_index ] );
831
832
						// Rearrange license keys.
833
						$subscriptions[ $subscription_id ]['licenses'] = array_values( $subscriptions[ $subscription_id ]['licenses'] );
834
835
						// Update subscription information.
836
						update_option( 'give_subscriptions', $subscriptions, false );
837
						break;
838
					}
839
				}
840
			}
841
		}
842
843
		/**
844
		 * Display plugin page licenses status notices.
845
		 *
846
		 * @param $plugin_file
847
		 * @param $plugin_data
848
		 * @param $status
849
		 *
850
		 * @return bool
851
		 */
852
		public function plugin_page_notices( $plugin_file, $plugin_data, $status ) {
0 ignored issues
show
The parameter $plugin_file is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $plugin_data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $status is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
853
			// Bailout.
854
			if ( $this->is_valid_license() ) {
855
				return false;
856
			}
857
858
			$update_notice_wrap = '<tr class="give-addon-notice-tr active"><td colspan="3" class="colspanchange"><div class="notice inline notice-warning notice-alt give-invalid-license"><p><span class="dashicons dashicons-info"></span> %s</p></div></td></tr>';
859
			$message            = $this->license_state_message();
860
861
			if ( ! empty( $message['message'] ) ) {
862
				echo sprintf( $update_notice_wrap, $message['message'] );
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
863
			}
864
		}
865
866
867
		/**
868
		 * Get message related to license state.
869
		 *
870
		 * @since  1.8.7
871
		 * @access public
872
		 * @return array
873
		 */
874
		public function license_state_message() {
875
			$message_data = array();
876
877
			if ( ! $this->is_valid_license() ) {
878
879
				$message_data['message'] = sprintf(
880
					'Please <a href="%1$s">activate your license</a> to receive updates and support for the %2$s add-on.',
881
					esc_url( admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' ) ),
882
					$this->item_name
883
				);
884
			}
885
886
			return $message_data;
887
		}
888
889
890
		/**
891
		 * Check if admin can edit license or not.
892
		 *
893
		 * @since  1.8.9
894
		 * @access private
895
		 */
896
		private function __is_user_can_edit_license() {
0 ignored issues
show
Method name "Give_License::__is_user_can_edit_license" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
897
898
			// Bailout.
899
			if (
900
				! Give_Admin_Settings::verify_nonce()
901
				|| ! current_user_can( 'manage_give_settings' )
902
				|| 'licenses' !== give_get_current_setting_tab()
903
			) {
904
				return false;
905
			}
906
907
			// Security check.
908
			if (
909
				isset( $_POST[ $this->item_shortname . '_license_key-nonce' ] )
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
910
				&& ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce' ], $this->item_shortname . '_license_key-nonce' )
0 ignored issues
show
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
911
			) {
912
				wp_die( __( 'Nonce verification failed.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
913
			}
914
915
			return true;
916
		}
917
918
919
		/**
920
		 * Get license information.
921
		 *
922
		 * @since  1.8.9
923
		 * @access public
924
		 *
925
		 * @param string $edd_action
926
		 * @param bool   $response_in_array
927
		 *
928
		 * @return mixed
929
		 */
930
		public function get_license_info( $edd_action = '', $response_in_array = false ) {
931
932
			if ( empty( $edd_action ) ) {
933
				return false;
934
			}
935
936
			// Data to send to the API.
937
			$api_params = array(
938
				'edd_action' => $edd_action, // never change from "edd_" to "give_"!
939
				'license'    => $this->license,
940
				'item_name'  => urlencode( $this->item_name ),
941
				'url'        => home_url(),
942
			);
943
944
			// Call the API.
945
			$response = wp_remote_post(
946
				$this->api_url,
947
				array(
948
					'timeout'   => 15,
949
					'sslverify' => false,
950
					'body'      => $api_params,
951
				)
952
			);
953
954
			// Make sure there are no errors.
955
			if ( is_wp_error( $response ) ) {
956
				return false;
957
			}
958
959
			return json_decode( wp_remote_retrieve_body( $response ), $response_in_array );
960
		}
961
962
963
		/**
964
		 * Unset license
965
		 *
966
		 * @since  1.8.14
967
		 * @access private
968
		 */
969
		private function unset_license() {
970
971
			// Remove license key from subscriptions if exist.
972
			$this->__remove_license_key_from_subscriptions();
973
974
			// Remove license from database.
975
			delete_option( "{$this->item_shortname}_license_active" );
976
			give_delete_option( "{$this->item_shortname}_license_key" );
977
			unset( $_POST[ "{$this->item_shortname}_license_key" ] );
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
978
979
			// Unset license param.
980
			$this->license = '';
981
		}
982
983
984
		/**
985
		 * Check if deactivating any license key or not.
986
		 *
987
		 * @since  1.8.17
988
		 * @access private
989
		 *
990
		 * @return bool
991
		 */
992
		private function is_deactivating_license() {
993
			$status = false;
994
995
			foreach ( $_POST as $key => $value ) {
996
				if ( false !== strpos( $key, 'license_key_deactivate' ) ) {
997
					$status = true;
998
					break;
999
				}
1000
			}
1001
1002
			return $status;
1003
		}
1004
1005
		/**
1006
		 * Return licensed addons info
1007
		 *
1008
		 * Note: note only for internal logic
1009
		 *
1010
		 * @since 2.1.4
1011
		 *
1012
		 * @return array
1013
		 */
1014
		static function get_licensed_addons() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1015
			return self::$licensed_addons;
1016
		}
1017
1018
	}
1019
1020
endif; // end class_exists check.
1021