Completed
Push — master ( 45f118...bcc91e )
by Devin
17:37 queued 14:12
created

Give_License::includes()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 6
ccs 0
cts 3
cp 0
crap 6
rs 9.4285
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 26 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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 to new Give add-ons.
23
	 *
24
	 * @since 1.0
25
	 */
26
	class Give_License {
27
28
		/**
29
		 * File
30
		 *
31
		 * @access private
32
		 * @since  1.0
33
		 *
34
		 * @var    string
35
		 */
36
		private $file;
37
38
		/**
39
		 * License
40
		 *
41
		 * @access private
42
		 * @since  1.0
43
		 *
44
		 * @var    string
45
		 */
46
		private $license;
47
48
		/**
49
		 * Item name
50
		 *
51
		 * @access private
52
		 * @since  1.0
53
		 *
54
		 * @var    string
55
		 */
56
		private $item_name;
57
58
		/**
59
		 * License Information object.
60
		 *
61
		 * @access private
62
		 * @since  1.7
63
		 *
64
		 * @var    object
65
		 */
66
		private $license_data;
67
68
		/**
69
		 * Item shortname
70
		 *
71
		 * @access private
72
		 * @since  1.0
73
		 *
74
		 * @var    string
75
		 */
76
		private $item_shortname;
77
78
		/**
79
		 * Version
80
		 *
81
		 * @access private
82
		 * @since  1.0
83
		 *
84
		 * @var    string
85
		 */
86
		private $version;
87
88
		/**
89
		 * Author
90
		 *
91
		 * @access private
92
		 * @since  1.0
93
		 *
94
		 * @var    string
95
		 */
96
		private $author;
97
98
		/**
99
		 * API URL
100
		 *
101
		 * @access private
102
		 * @since  1.0
103
		 *
104
		 * @var    string
105
		 */
106
		private $api_url = 'https://givewp.com/edd-sl-api/';
107
108
		/**
109
		 * Account URL
110
		 *
111
		 * @access private
112
		 * @since  1.7
113
		 *
114
		 * @var null|string
115
		 */
116
		private $account_url = 'https://givewp.com/my-account/';
117
118
		/**
119
		 * Ccheckout URL
120
		 *
121
		 * @access private
122
		 * @since  1.7
123
		 *
124
		 * @var null|string
125
		 */
126
		private $checkout_url = 'https://givewp.com/checkout/';
127
128
		/**
129
		 * Class Constructor
130
		 *
131
		 * Set up the Give License Class.
132
		 *
133
		 * @access public
134
		 * @since  1.0
135
		 *
136
		 * @param string $_file
137
		 * @param string $_item_name
138
		 * @param string $_version
139
		 * @param string $_author
140
		 * @param string $_optname
141
		 * @param string $_api_url
142
		 * @param string $_checkout_url
143
		 * @param string $_account_url
144
		 */
145
		public function __construct( $_file, $_item_name, $_version, $_author, $_optname = null, $_api_url = null, $_checkout_url = null, $_account_url = null ) {
0 ignored issues
show
Unused Code introduced by
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...
146
147
			$give_options = give_get_settings();
148
149
			$this->file             = $_file;
150
			$this->item_name        = $_item_name;
151
			$this->item_shortname   = 'give_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $this->item_name ) ) );
152
			$this->version          = $_version;
153
			$this->license          = isset( $give_options[ $this->item_shortname . '_license_key' ] ) ? trim( $give_options[ $this->item_shortname . '_license_key' ] ) : '';
154
			$this->license_data     = get_option( $this->item_shortname . '_license_active' );
155
			$this->author           = $_author;
156
			$this->api_url          = is_null( $_api_url ) ? $this->api_url : $_api_url;
157
			$this->checkout_url     = is_null( $_checkout_url ) ? $this->checkout_url : $_checkout_url;
158
			$this->account_url      = is_null( $_account_url ) ? $this->account_url : $_account_url;
159
			$this->auto_updater_obj = null;
0 ignored issues
show
Bug introduced by
The property auto_updater_obj does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
160
161
			// Setup hooks
162
			$this->includes();
163
			$this->hooks();
164
			$this->auto_updater();
165
		}
166
167
		/**
168
		 * Includes
169
		 *
170
		 * Include the updater class.
171
		 *
172
		 * @access private
173
		 * @since  1.0
174
		 *
175
		 * @return void
176
		 */
177
		private function includes() {
178
179
			if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
180
				require_once 'admin/EDD_SL_Plugin_Updater.php';
181
			}
182
		}
183
184
		/**
185
		 * Hooks
186
		 *
187
		 * Setup license hooks.
188
		 *
189
		 * @access private
190
		 * @since  1.0
191
		 *
192
		 * @return void
193
		 */
194
		private function hooks() {
195
196
			// Register settings
197
			add_filter( 'give_settings_licenses', array( $this, 'settings' ), 1 );
198
199
			// Activate license key on settings save
200
			add_action( 'admin_init', array( $this, 'activate_license' ) );
201
202
			// Deactivate license key
203
			add_action( 'admin_init', array( $this, 'deactivate_license' ) );
204
205
			// Updater
206
			add_action( 'admin_init', array( $this, 'auto_updater' ), 0 );
207
			add_action( 'admin_notices', array( $this, 'notices' ) );
208
209
			// Check license weekly.
210
			add_action( 'give_weekly_scheduled_events', array( $this, 'weekly_license_check' ) );
211
			add_action( 'give_validate_license_when_site_migrated', array( $this, 'weekly_license_check' ) );
212
213
			// Check subscription weekly.
214
			add_action( 'give_weekly_scheduled_events', array( $this, 'weekly_subscription_check' ) );
215
			add_action( 'give_validate_license_when_site_migrated', array( $this, 'weekly_subscription_check' ) );
216
217
			// Show addon notice on plugin page.
218
			$plugin_name = end( explode( 'plugins/', $this->file ) );
0 ignored issues
show
Bug introduced by
explode('plugins/', $this->file) cannot be passed to end() as the parameter $array expects a reference.
Loading history...
219
			add_action( "after_plugin_row_{$plugin_name}", array( $this, 'plugin_page_notices' ), 10, 3 );
220
221
		}
222
223
224
		/**
225
		 * Auto Updater
226
		 *
227
		 * @access private
228
		 * @since  1.0
229
		 *
230
		 * @return void
231
		 */
232
		public function auto_updater() {
233
234
			// Setup the updater
235
			$this->auto_updater_obj = new EDD_SL_Plugin_Updater(
236
				$this->api_url,
237
				$this->file,
238
				array(
239
					'version'   => $this->version,
240
					'license'   => $this->license,
241
					'item_name' => $this->item_name,
242
					'author'    => $this->author,
243
				)
244
			);
245
		}
246
247
		/**
248
		 * License Settings
249
		 *
250
		 * Add license field to settings.
251
		 *
252
		 * @access public
253
		 * @since  1.0
254
		 *
255
		 * @param  array $settings License settings.
256
		 *
257
		 * @return array           License settings.
258
		 */
259
		public function settings( $settings ) {
260
261
			$give_license_settings = array(
262
				array(
263
					'name'    => $this->item_name,
264
					'id'      => $this->item_shortname . '_license_key',
265
					'desc'    => '',
266
					'type'    => 'license_key',
267
					'options' => array(
268
						'license'      => get_option( $this->item_shortname . '_license_active' ),
269
						'shortname'    => $this->item_shortname,
270
						'item_name'    => $this->item_name,
271
						'api_url'      => $this->api_url,
272
						'checkout_url' => $this->checkout_url,
273
						'account_url'  => $this->account_url,
274
					),
275
					'size'    => 'regular',
276
				),
277
			);
278
279
			return array_merge( $settings, $give_license_settings );
280
		}
281
282
		/**
283
		 * License Settings Content
284
		 *
285
		 * Add Some Content to the Licensing Settings.
286
		 *
287
		 * @access public
288
		 * @since  1.0
289
		 *
290
		 * @param  array $settings License settings content.
291
		 *
292
		 * @return array           License settings content.
293
		 */
294
		public function license_settings_content( $settings ) {
295
296
			$give_license_settings = array(
297
				array(
298
					'name' => __( 'Add-on Licenses', 'give' ),
299
					'desc' => '<hr>',
300
					'type' => 'give_title',
301
					'id'   => 'give_title',
302
				),
303
			);
304
305
			return array_merge( $settings, $give_license_settings );
306
		}
307
308
		/**
309
		 * Activate License
310
		 *
311
		 * Activate the license key.
312
		 *
313
		 * @access public
314
		 * @since  1.0
315
		 *
316
		 * @return void
317
		 */
318
		public function activate_license() {
319
			// Bailout: Check if license key set of not.
320
			if ( ! isset( $_POST[ $this->item_shortname . '_license_key' ] ) ) {
321
				return;
322
			}
323
324
			// Security check.
325
			if ( ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce' ], $this->item_shortname . '_license_key-nonce' ) ) {
326
				wp_die( __( 'Nonce verification failed.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
327
			}
328
329
			// Check if user have correct permissions.
330
			if ( ! current_user_can( 'manage_give_settings' ) ) {
331
				return;
332
			}
333
334
			// Allow third party addon developers to handle license activation.
335
			if ( $this->__is_third_party_addon() ) {
336
				do_action( 'give_activate_license', $this );
337
338
				return;
339
			}
340
341
			// Delete previous license setting if a empty license key submitted.
342
			if ( empty( $_POST[ $this->item_shortname . '_license_key' ] ) ) {
343
				delete_option( $this->item_shortname . '_license_active' );
344
345
				return;
346
			}
347
348
			// Do not simultaneously activate add-ons if the user want to deactivate a specific add-on.
349
			foreach ( $_POST as $key => $value ) {
350
				if ( false !== strpos( $key, 'license_key_deactivate' ) ) {
351
					// Don't activate a key when deactivating a different key
352
					return;
353
				}
354
			}
355
356
			// Check if plugin previously installed.
357
			if ( $this->is_valid_license() ) {
358
				return;
359
			}
360
361
			// Get license key.
362
			$license = sanitize_text_field( $_POST[ $this->item_shortname . '_license_key' ] );
363
364
			// Bailout.
365
			if ( empty( $license ) ) {
366
				return;
367
			}
368
369
			// Delete previous license key from subscription if previously added.
370
			$this->__remove_license_key_from_subscriptions();
371
372
			// Data to send to the API
373
			$api_params = array(
374
				'edd_action' => 'activate_license', // never change from "edd_" to "give_"!
375
				'license'    => $license,
376
				'item_name'  => urlencode( $this->item_name ),
377
				'url'        => home_url(),
378
			);
379
380
			// Call the API
381
			$response = wp_remote_post(
382
				$this->api_url,
383
				array(
384
					'timeout'   => 15,
385
					'sslverify' => false,
386
					'body'      => $api_params,
387
				)
388
			);
389
390
			// Make sure there are no errors
391
			if ( is_wp_error( $response ) ) {
392
				return;
393
			}
394
395
			// Tell WordPress to look for updates
396
			set_site_transient( 'update_plugins', null );
397
398
			// Decode license data
399
			$license_data = json_decode( wp_remote_retrieve_body( $response ) );
400
			update_option( $this->item_shortname . '_license_active', $license_data );
401
402
			// Add license key.
403
			give_update_option( "{$this->item_shortname}_license_key", $license );
404
405
			// Check subscription for license key and store this to db (if any).
406
			$this->__single_subscription_check();
407
		}
408
409
		/**
410
		 * Deactivate License
411
		 *
412
		 * Deactivate the license key.
413
		 *
414
		 * @access public
415
		 * @since  1.0
416
		 *
417
		 * @return void
418
		 */
419
		public function deactivate_license() {
420
421
			if ( ! isset( $_POST[ $this->item_shortname . '_license_key' ] ) ) {
422
				return;
423
			}
424
425
			if ( ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce' ], $this->item_shortname . '_license_key-nonce' ) ) {
426
				wp_die( __( 'Nonce verification failed.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
427
			}
428
429
			if ( ! current_user_can( 'manage_give_settings' ) ) {
430
				return;
431
			}
432
433
			// Allow third party add-on developers to handle license deactivation.
434
			if ( $this->__is_third_party_addon() ) {
435
				do_action( 'give_deactivate_license', $this );
436
437
				return;
438
			}
439
440
			// Run on deactivate button press
441
			if ( isset( $_POST[ $this->item_shortname . '_license_key_deactivate' ] ) ) {
442
443
				// Data to send to the API
444
				$api_params = array(
445
					'edd_action' => 'deactivate_license', // never change from "edd_" to "give_"!
446
					'license'    => $this->license,
447
					'item_name'  => urlencode( $this->item_name ),
448
					'url'        => home_url(),
449
				);
450
451
				// Call the API
452
				$response = wp_remote_post(
453
					$this->api_url,
454
					array(
455
						'timeout'   => 15,
456
						'sslverify' => false,
457
						'body'      => $api_params,
458
					)
459
				);
460
461
				// Make sure there are no errors
462
				if ( is_wp_error( $response ) ) {
463
					return;
464
				}
465
466
				// Decode the license data
467
				$license_data = json_decode( wp_remote_retrieve_body( $response ) );
468
469
				// Ensure deactivated successfully.
470
				if ( isset( $license_data->success ) ) {
471
472
					// Remove license data.
473
					delete_option( $this->item_shortname . '_license_active' );
474
					
475
					give_delete_option( $this->item_shortname . '_license_key' );
476
477
					// Remove license key from subscriptions if exist.
478
					$this->__remove_license_key_from_subscriptions();
479
480
				}
481
			}// End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
482
		}
483
484
		/**
485
		 * Check if license key is valid once per week.
486
		 *
487
		 * @access public
488
		 * @since  1.7
489
		 *
490
		 * @return bool|void
491
		 */
492
		public function weekly_license_check() {
493
494
			if ( ! empty( $_POST['give_settings'] ) ) {
495
				// Don't fire when saving settings
496
				return false;
497
			}
498
499
			if ( empty( $this->license ) ) {
500
				return false;
501
			}
502
503
			// Allow third party add-on developers to handle their license check.
504
			if ( $this->__is_third_party_addon() ) {
505
				do_action( 'give_weekly_license_check', $this );
506
507
				return false;
508
			}
509
510
			// Data to send in our API request.
511
			$api_params = array(
512
				'edd_action' => 'check_license',
513
				'license'    => $this->license,
514
				'item_name'  => urlencode( $this->item_name ),
515
				'url'        => home_url(),
516
			);
517
518
			// Call the API.
519
			$response = wp_remote_post(
520
				$this->api_url,
521
				array(
522
					'timeout'   => 15,
523
					'sslverify' => false,
524
					'body'      => $api_params,
525
				)
526
			);
527
528
			// Make sure the response came back okay.
529
			if ( is_wp_error( $response ) ) {
530
				return false;
531
			}
532
533
			$license_data = json_decode( wp_remote_retrieve_body( $response ) );
534
			update_option( $this->item_shortname . '_license_active', $license_data );
535
		}
536
537
		/**
538
		 * Check subscription validation once per week
539
		 *
540
		 * @access public
541
		 * @since  1.7
542
		 *
543
		 * @return bool|void
544
		 */
545
		public function weekly_subscription_check() {
546
547
			if ( ! empty( $_POST['give_settings'] ) ) {
548
				// Don't fire when saving settings
549
				return false;
550
			}
551
552
			// Remove old subscription data.
553
			if ( absint( get_option( '_give_subscriptions_edit_last', true ) ) < current_time( 'timestamp', 1 ) ) {
554
				delete_option( 'give_subscriptions' );
555
				update_option( '_give_subscriptions_edit_last', strtotime( '+ 1 day', current_time( 'timestamp', 1 ) ) );
556
			}
557
558
			if ( empty( $this->license ) ) {
559
				return false;
560
			}
561
562
			// Allow third party add-on developers to handle their subscription check.
563
			if ( $this->__is_third_party_addon() ) {
564
				do_action( 'give_weekly_subscription_check', $this );
565
566
				return false;
567
			}
568
569
			// Delete subscription notices show blocker.
570
			$this->__remove_license_notices_show_blocker();
571
572
			// Data to send in our API request.
573
			$api_params = array(
574
				// Do not get confused with edd_action check_subscription.
575
				// By default edd software licensing api does not have api to check subscription.
576
				// This is a custom feature to check subscriptions.
577
				'edd_action' => 'check_subscription',
578
				'license'    => $this->license,
579
				'item_name'  => urlencode( $this->item_name ),
580
				'url'        => home_url(),
581
			);
582
583
			// Call the API
584
			$response = wp_remote_post(
585
				$this->api_url,
586
				array(
587
					'timeout'   => 15,
588
					'sslverify' => false,
589
					'body'      => $api_params,
590
				)
591
			);
592
593
			// Make sure the response came back okay.
594
			if ( is_wp_error( $response ) ) {
595
				return false;
596
			}
597
598
			$subscription_data = json_decode( wp_remote_retrieve_body( $response ), true );
599
600
			if ( ! empty( $subscription_data['success'] ) && absint( $subscription_data['success'] ) ) {
601
				$subscriptions = get_option( 'give_subscriptions', array() );
602
603
				// Update subscription data only if subscription does not exist already.
604
				if ( ! array_key_exists( $subscription_data['id'], $subscriptions ) ) {
605
					$subscriptions[ $subscription_data['id'] ]             = $subscription_data;
606
					$subscriptions[ $subscription_data['id'] ]['licenses'] = array();
607
				}
608
609
				// Store licenses for subscription.
610
				if ( ! in_array( $this->license, $subscriptions[ $subscription_data['id'] ]['licenses'] ) ) {
611
					$subscriptions[ $subscription_data['id'] ]['licenses'][] = $this->license;
612
				}
613
614
				update_option( 'give_subscriptions', $subscriptions );
615
			}
616
		}
617
618
		/**
619
		 * Check if license key is part of subscription or not
620
		 *
621
		 * @access private
622
		 * @since  1.7
623
		 *
624
		 * @return bool|void
625
		 */
626
		private function __single_subscription_check() {
627
			// Do not fire if license key is not set.
628
			if ( ! isset( $_POST[ $this->item_shortname . '_license_key' ] ) ) {
629
				return false;
630
			}
631
632
			if ( empty( $this->license ) ) {
633
				return false;
634
			}
635
636
			// Data to send in our API request.
637
			$api_params = array(
638
				// Do not get confused with edd_action check_subscription.
639
				// By default edd software licensing api does not have api to check subscription.
640
				// This is a custom feature to check subscriptions.
641
				'edd_action' => 'check_subscription',
642
				'license'    => $this->license,
643
				'item_name'  => urlencode( $this->item_name ),
644
				'url'        => home_url(),
645
			);
646
647
			// Call the API
648
			$response = wp_remote_post(
649
				$this->api_url,
650
				array(
651
					'timeout'   => 15,
652
					'sslverify' => false,
653
					'body'      => $api_params,
654
				)
655
			);
656
657
			// Make sure the response came back okay.
658
			if ( is_wp_error( $response ) ) {
659
				return false;
660
			}
661
662
			$subscription_data = json_decode( wp_remote_retrieve_body( $response ), true );
663
664
			if ( ! empty( $subscription_data['success'] ) && absint( $subscription_data['success'] ) ) {
665
				$subscriptions = get_option( 'give_subscriptions', array() );
666
667
				// Update subscription data only if subscription does not exist already.
668
				if ( ! array_key_exists( $subscription_data['id'], $subscriptions ) ) {
669
					$subscriptions[ $subscription_data['id'] ]             = $subscription_data;
670
					$subscriptions[ $subscription_data['id'] ]['licenses'] = array();
671
				}
672
673
				// Store licenses for subscription.
674
				if ( ! in_array( $this->license, $subscriptions[ $subscription_data['id'] ]['licenses'] ) ) {
675
					$subscriptions[ $subscription_data['id'] ]['licenses'][] = $this->license;
676
				}
677
678
				update_option( 'give_subscriptions', $subscriptions );
679
			}
680
		}
681
682
		/**
683
		 * Admin notices for errors
684
		 *
685
		 * @access public
686
		 * @since  1.0
687
		 *
688
		 * @return void
689
		 */
690
		public function notices() {
691
692
			if ( ! current_user_can( 'manage_give_settings' ) ) {
693
				return;
694
			}
695
696
			// Do not show licenses notices on license tab.
697
			if ( 'licenses' === give_get_current_setting_tab() ) {
698
				return;
699
			}
700
701
			static $showed_invalid_message;
702
			static $showed_subscriptions_message;
703
			static $addon_license_key_in_subscriptions;
704
705
			// Set default value.
706
			$addon_license_key_in_subscriptions = ! empty( $addon_license_key_in_subscriptions ) ? $addon_license_key_in_subscriptions : array();
707
			$messages                           = array();
708
709
			if (
710
				empty( $this->license )
711
				&& ! $this->__is_notice_dismissed( 'general' )
712
				&& empty( $showed_invalid_message )
713
			) {
714
				$messages['general']    = sprintf(
715
					__( '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' ),
716
					admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' )
717
				);
718
				$showed_invalid_message = true;
719
720
			}
721
722
			// Get subscriptions.
723
			$subscriptions = get_option( 'give_subscriptions' );
724
725
			// Show subscription messages.
726
			if ( ! empty( $subscriptions ) && ! $showed_subscriptions_message ) {
727
728
				foreach ( $subscriptions as $subscription ) {
729
					// Subscription expires timestamp.
730
					$subscription_expires = strtotime( $subscription['expires'] );
731
732
					// Start showing subscriptions message before one week of renewal date.
733
					if ( strtotime( '- 7 days', $subscription_expires ) > current_time( 'timestamp', 1 ) ) {
734
						continue;
735
					}
736
737
					// Check if subscription message already exist in messages.
738
					if ( array_key_exists( $subscription['id'], $messages ) ) {
739
						continue;
740
					}
741
742
					if ( ( ! $this->__is_notice_dismissed( $subscription['id'] ) && 'active' !== $subscription['status'] ) ) {
743
744
						if ( strtotime( $subscription['expires'] ) < current_time( 'timestamp', 1 ) ) {// Check if license already expired.
745
							$messages[ $subscription['id'] ] = sprintf(
746
								__( '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 <a href="%4$s">Click here if already renewed</a>.', 'give' ),
747
								urldecode( $subscription['invoice_url'] ),
748
								$subscription['payment_id'],
749
								"{$this->checkout_url}?edd_license_key={$subscription['license_key']}&utm_campaign=admin&utm_source=licenses&utm_medium=expired",
750
								esc_url( add_query_arg( '_give_hide_license_notices_permanently', $subscription['id'], $_SERVER['REQUEST_URI'] ) )
751
							);
752
						} else {
753
							$messages[ $subscription['id'] ] = sprintf(
754
								__( '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 <a href="%5$s">Click here if already renewed</a>.', 'give' ),
755
								human_time_diff( current_time( 'timestamp', 1 ), strtotime( $subscription['expires'] ) ),
756
								urldecode( $subscription['invoice_url'] ),
757
								$subscription['payment_id'],
758
								"{$this->checkout_url}?edd_license_key={$subscription['license_key']}&utm_campaign=admin&utm_source=licenses&utm_medium=expired",
759
								esc_url( add_query_arg( '_give_hide_license_notices_permanently', $subscription['id'], $_SERVER['REQUEST_URI'] ) )
760
							);
761
						}
762
					}
763
764
					// Stop validation for these license keys.
765
					$addon_license_key_in_subscriptions = array_merge( $addon_license_key_in_subscriptions, $subscription['licenses'] );
766
				}// End foreach().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
767
				$showed_subscriptions_message = true;
768
			}// End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
769
770
			// Show non subscription addon messages.
771
			if (
772
				! in_array( $this->license, $addon_license_key_in_subscriptions )
773
				&& ! $this->__is_notice_dismissed( 'general' )
774
				&& ! $this->is_valid_license()
775
				&& empty( $showed_invalid_message )
776
			) {
777
778
				$messages['general']    = sprintf(
779
					__( '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' ),
780
					admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' )
781
				);
782
				$showed_invalid_message = true;
783
784
			}
785
786
			// Print messages.
787
			if ( ! empty( $messages ) ) {
788
				foreach ( $messages as $notice_id => $message ) {
789
790
					echo sprintf(
791
						'<div class="notice notice-error is-dismissible give-license-notice" data-dismiss-notice-shortly="%1$s"><p>%2$s</p></div>',
792
						esc_url( add_query_arg( '_give_hide_license_notices_shortly', $notice_id, $_SERVER['REQUEST_URI'] ) ),
793
						$message
794
					);
795
				}
796
			}
797
		}
798
799
		/**
800
		 * Check if license is valid or not.
801
		 *
802
		 * @access public
803
		 * @since  1.7
804
		 *
805
		 * @return bool
806
		 */
807
		public function is_valid_license() {
808
			if ( apply_filters( 'give_is_valid_license', ( is_object( $this->license_data ) && ! empty( $this->license_data ) && property_exists( $this->license_data, 'license' ) && 'valid' === $this->license_data->license ) ) ) {
809
				return true;
810
			}
811
812
			return false;
813
		}
814
815
		/**
816
		 * Check if license is valid or not.
817
		 *
818
		 * @access private
819
		 * @since  1.7
820
		 *
821
		 * @return bool
822
		 */
823
		private function __is_third_party_addon() {
824
			return ( false === strpos( $this->api_url, 'givewp.com/' ) );
825
		}
826
827
		/**
828
		 * Remove license key from subscription.
829
		 *
830
		 * This function mainly uses when admin user deactivate license key,
831
		 * then we do not need subscription information for that license key.
832
		 *
833
		 * @access private
834
		 * @since  1.7
835
		 *
836
		 * @return void|bool
837
		 */
838
		private function __remove_license_key_from_subscriptions() {
839
			$subscriptions = get_option( 'give_subscriptions', array() );
840
841
			// Bailout.
842
			if ( empty( $this->license ) ) {
843
				return false;
844
			}
845
846
			if ( ! empty( $subscriptions ) ) {
847
				foreach ( $subscriptions as $subscription_id => $subscription ) {
848
					$license_index = array_search( $this->license, $subscription['licenses'] );
849
					if ( false !== $license_index ) {
850
						// Remove license key.
851
						unset( $subscriptions[ $subscription_id ]['licenses'][ $license_index ] );
852
853
						// Rearrange license keys.
854
						$subscriptions[ $subscription_id ]['licenses'] = array_values( $subscriptions[ $subscription_id ]['licenses'] );
855
856
						// Update subscription information.
857
						update_option( 'give_subscriptions', $subscriptions );
858
						break;
859
					}
860
				}
861
			}
862
		}
863
864
		/**
865
		 * Remove license notices show blocker.
866
		 *
867
		 * @access private
868
		 * @since  1.7
869
		 *
870
		 * @return void
871
		 */
872
		private function __remove_license_notices_show_blocker() {
873
			global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
874
875
			// Delete permanent notice blocker.
876
			$wpdb->query(
877
				$wpdb->prepare(
878
					"
879
					DELETE FROM $wpdb->usermeta
880
					WHERE meta_key
881
					LIKE '%%%s%%'
882
					",
883
					'_give_hide_license_notices_permanently'
884
				)
885
			);
886
887
			// Delete short notice blocker.
888
			$wpdb->query(
889
				$wpdb->prepare(
890
					"
891
					DELETE FROM $wpdb->options
892
					WHERE option_name
893
					LIKE '%%%s%%'
894
					",
895
					'__give_hide_license_notices_shortly_'
896
				)
897
			);
898
		}
899
900
		/**
901
		 * Check if notice dismissed by admin user or not.
902
		 *
903
		 * @access private
904
		 * @since  1.7
905
		 *
906
		 * @param  int $notice_id Notice ID.
907
		 *
908
		 * @return bool
909
		 */
910
		private function __is_notice_dismissed( $notice_id ) {
911
			$current_user        = wp_get_current_user();
912
			$is_notice_dismissed = false;
913
914
			// Ge is notice dismissed permanently.
915
			$already_dismiss_notices = ( $already_dismiss_notices = get_user_meta( $current_user->ID, '_give_hide_license_notices_permanently', true ) )
916
				? $already_dismiss_notices
917
				: array();
918
919
			if (
920
				in_array( $notice_id, $already_dismiss_notices )
921
				|| Give_Cache::get( "_give_hide_license_notices_shortly_{$current_user->ID}_{$notice_id}", true )
922
			) {
923
				$is_notice_dismissed = true;
924
			}
925
926
			return $is_notice_dismissed;
927
		}
928
929
930
		/**
931
		 * @param $plugin_file
932
		 * @param $plugin_data
933
		 * @param $status
934
		 *
935
		 * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be false|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
936
		 */
937
		public function plugin_page_notices( $plugin_file, $plugin_data, $status ) {
0 ignored issues
show
Unused Code introduced by
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...
Unused Code introduced by
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...
Unused Code introduced by
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...
938
			// Bailout.
939
			if ( $this->is_valid_license() ) {
940
				return false;
941
			}
942
943
			$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>';
944
			$message            = $this->license_state_message();
945
946
			if ( ! empty( $message['message'] ) ) {
947
				echo sprintf( $update_notice_wrap, $message['message'] );
948
			}
949
		}
950
951
952
		/**
953
		 * Get message related to license state.
954
		 *
955
		 * @since  1.8.7
956
		 * @access public
957
		 * @return array
958
		 */
959
		public function license_state_message() {
960
			$message_data = array();
961
962
			if ( ! $this->is_valid_license() ) {
963
964
				$message_data['message'] = sprintf(
965
					'Please <a href="%1$s">activate your license</a> to receive updates and support for the %2$s add-on.',
966
					esc_url( admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' ) ),
967
					$this->item_name
968
				);
969
			}
970
971
			return $message_data;
972
		}
973
	}
974
975
endif; // end class_exists check
976