Completed
Push — issues/611 ( 0c24f9...7d2e61 )
by Ravinder
20:50
created

Give_License::auto_updater()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 14
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 = explode( 'plugins/', $this->file );
219
			$plugin_name = end( $plugin_name );
220
			add_action( "after_plugin_row_{$plugin_name}", array( $this, 'plugin_page_notices' ), 10, 3 );
221
222
		}
223
224
225
		/**
226
		 * Auto Updater
227
		 *
228
		 * @access private
229
		 * @since  1.0
230
		 *
231
		 * @return void
232
		 */
233
		public function auto_updater() {
234
235
			// Setup the updater
236
			$this->auto_updater_obj = new EDD_SL_Plugin_Updater(
237
				$this->api_url,
238
				$this->file,
239
				array(
240
					'version'   => $this->version,
241
					'license'   => $this->license,
242
					'item_name' => $this->item_name,
243
					'author'    => $this->author,
244
				)
245
			);
246
		}
247
248
		/**
249
		 * License Settings
250
		 *
251
		 * Add license field to settings.
252
		 *
253
		 * @access public
254
		 * @since  1.0
255
		 *
256
		 * @param  array $settings License settings.
257
		 *
258
		 * @return array           License settings.
259
		 */
260
		public function settings( $settings ) {
261
262
			$give_license_settings = array(
263
				array(
264
					'name'    => $this->item_name,
265
					'id'      => $this->item_shortname . '_license_key',
266
					'desc'    => '',
267
					'type'    => 'license_key',
268
					'options' => array(
269
						'license'      => get_option( $this->item_shortname . '_license_active' ),
270
						'shortname'    => $this->item_shortname,
271
						'item_name'    => $this->item_name,
272
						'api_url'      => $this->api_url,
273
						'checkout_url' => $this->checkout_url,
274
						'account_url'  => $this->account_url,
275
					),
276
					'size'    => 'regular',
277
				),
278
			);
279
280
			return array_merge( $settings, $give_license_settings );
281
		}
282
283
		/**
284
		 * License Settings Content
285
		 *
286
		 * Add Some Content to the Licensing Settings.
287
		 *
288
		 * @access public
289
		 * @since  1.0
290
		 *
291
		 * @param  array $settings License settings content.
292
		 *
293
		 * @return array           License settings content.
294
		 */
295
		public function license_settings_content( $settings ) {
296
297
			$give_license_settings = array(
298
				array(
299
					'name' => __( 'Add-on Licenses', 'give' ),
300
					'desc' => '<hr>',
301
					'type' => 'give_title',
302
					'id'   => 'give_title',
303
				),
304
			);
305
306
			return array_merge( $settings, $give_license_settings );
307
		}
308
309
		/**
310
		 * Activate License
311
		 *
312
		 * Activate the license key.
313
		 *
314
		 * @access public
315
		 * @since  1.0
316
		 *
317
		 * @return void
318
		 */
319
		public function activate_license() {
320
			// Bailout: Check if license key set of not.
321
			if ( ! isset( $_POST[ $this->item_shortname . '_license_key' ] ) ) {
322
				return;
323
			}
324
325
			// Security check.
326
			if ( ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce' ], $this->item_shortname . '_license_key-nonce' ) ) {
327
				wp_die( __( 'Nonce verification failed.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
328
			}
329
330
			// Check if user have correct permissions.
331
			if ( ! current_user_can( 'manage_give_settings' ) ) {
332
				return;
333
			}
334
335
			// Allow third party addon developers to handle license activation.
336
			if ( $this->__is_third_party_addon() ) {
337
				do_action( 'give_activate_license', $this );
338
339
				return;
340
			}
341
342
			// Delete previous license setting if a empty license key submitted.
343
			if ( empty( $_POST[ $this->item_shortname . '_license_key' ] ) ) {
344
				delete_option( $this->item_shortname . '_license_active' );
345
346
				return;
347
			}
348
349
			// Do not simultaneously activate add-ons if the user want to deactivate a specific add-on.
350
			foreach ( $_POST as $key => $value ) {
351
				if ( false !== strpos( $key, 'license_key_deactivate' ) ) {
352
					// Don't activate a key when deactivating a different key
353
					return;
354
				}
355
			}
356
357
			// Check if plugin previously installed.
358
			if ( $this->is_valid_license() ) {
359
				return;
360
			}
361
362
			// Get license key.
363
			$license = sanitize_text_field( $_POST[ $this->item_shortname . '_license_key' ] );
364
365
			// Bailout.
366
			if ( empty( $license ) ) {
367
				return;
368
			}
369
370
			// Delete previous license key from subscription if previously added.
371
			$this->__remove_license_key_from_subscriptions();
372
373
			// Data to send to the API
374
			$api_params = array(
375
				'edd_action' => 'activate_license', // never change from "edd_" to "give_"!
376
				'license'    => $license,
377
				'item_name'  => urlencode( $this->item_name ),
378
				'url'        => home_url(),
379
			);
380
381
			// Call the API
382
			$response = wp_remote_post(
383
				$this->api_url,
384
				array(
385
					'timeout'   => 15,
386
					'sslverify' => false,
387
					'body'      => $api_params,
388
				)
389
			);
390
391
			// Make sure there are no errors
392
			if ( is_wp_error( $response ) ) {
393
				return;
394
			}
395
396
			// Tell WordPress to look for updates
397
			set_site_transient( 'update_plugins', null );
398
399
			// Decode license data
400
			$license_data = json_decode( wp_remote_retrieve_body( $response ) );
401
			update_option( $this->item_shortname . '_license_active', $license_data );
402
403
			// Add license key.
404
			give_update_option( "{$this->item_shortname}_license_key", $license );
405
406
			// Check subscription for license key and store this to db (if any).
407
			$this->__single_subscription_check();
408
		}
409
410
		/**
411
		 * Deactivate License
412
		 *
413
		 * Deactivate the license key.
414
		 *
415
		 * @access public
416
		 * @since  1.0
417
		 *
418
		 * @return void
419
		 */
420
		public function deactivate_license() {
421
422
			if ( ! isset( $_POST[ $this->item_shortname . '_license_key' ] ) ) {
423
				return;
424
			}
425
426
			if ( ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce' ], $this->item_shortname . '_license_key-nonce' ) ) {
427
				wp_die( __( 'Nonce verification failed.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
428
			}
429
430
			if ( ! current_user_can( 'manage_give_settings' ) ) {
431
				return;
432
			}
433
434
			// Allow third party add-on developers to handle license deactivation.
435
			if ( $this->__is_third_party_addon() ) {
436
				do_action( 'give_deactivate_license', $this );
437
438
				return;
439
			}
440
441
			// Run on deactivate button press
442
			if ( isset( $_POST[ $this->item_shortname . '_license_key_deactivate' ] ) ) {
443
444
				// Data to send to the API
445
				$api_params = array(
446
					'edd_action' => 'deactivate_license', // never change from "edd_" to "give_"!
447
					'license'    => $this->license,
448
					'item_name'  => urlencode( $this->item_name ),
449
					'url'        => home_url(),
450
				);
451
452
				// Call the API
453
				$response = wp_remote_post(
454
					$this->api_url,
455
					array(
456
						'timeout'   => 15,
457
						'sslverify' => false,
458
						'body'      => $api_params,
459
					)
460
				);
461
462
				// Make sure there are no errors
463
				if ( is_wp_error( $response ) ) {
464
					return;
465
				}
466
467
				// Decode the license data
468
				$license_data = json_decode( wp_remote_retrieve_body( $response ) );
469
470
				// Ensure deactivated successfully.
471
				if ( isset( $license_data->success ) ) {
472
473
					// Remove license data.
474
					delete_option( $this->item_shortname . '_license_active' );
475
					
476
					give_delete_option( $this->item_shortname . '_license_key' );
477
478
					// Remove license key from subscriptions if exist.
479
					$this->__remove_license_key_from_subscriptions();
480
481
				}
482
			}// 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...
483
		}
484
485
		/**
486
		 * Check if license key is valid once per week.
487
		 *
488
		 * @access public
489
		 * @since  1.7
490
		 *
491
		 * @return bool|void
492
		 */
493
		public function weekly_license_check() {
494
495
			if ( ! empty( $_POST['give_settings'] ) ) {
496
				// Don't fire when saving settings
497
				return false;
498
			}
499
500
			if ( empty( $this->license ) ) {
501
				return false;
502
			}
503
504
			// Allow third party add-on developers to handle their license check.
505
			if ( $this->__is_third_party_addon() ) {
506
				do_action( 'give_weekly_license_check', $this );
507
508
				return false;
509
			}
510
511
			// Data to send in our API request.
512
			$api_params = array(
513
				'edd_action' => 'check_license',
514
				'license'    => $this->license,
515
				'item_name'  => urlencode( $this->item_name ),
516
				'url'        => home_url(),
517
			);
518
519
			// Call the API.
520
			$response = wp_remote_post(
521
				$this->api_url,
522
				array(
523
					'timeout'   => 15,
524
					'sslverify' => false,
525
					'body'      => $api_params,
526
				)
527
			);
528
529
			// Make sure the response came back okay.
530
			if ( is_wp_error( $response ) ) {
531
				return false;
532
			}
533
534
			$license_data = json_decode( wp_remote_retrieve_body( $response ) );
535
			update_option( $this->item_shortname . '_license_active', $license_data );
536
		}
537
538
		/**
539
		 * Check subscription validation once per week
540
		 *
541
		 * @access public
542
		 * @since  1.7
543
		 *
544
		 * @return bool|void
545
		 */
546
		public function weekly_subscription_check() {
547
548
			if ( ! empty( $_POST['give_settings'] ) ) {
549
				// Don't fire when saving settings
550
				return false;
551
			}
552
553
			// Remove old subscription data.
554
			if ( absint( get_option( '_give_subscriptions_edit_last', true ) ) < current_time( 'timestamp', 1 ) ) {
555
				delete_option( 'give_subscriptions' );
556
				update_option( '_give_subscriptions_edit_last', strtotime( '+ 1 day', current_time( 'timestamp', 1 ) ) );
557
			}
558
559
			if ( empty( $this->license ) ) {
560
				return false;
561
			}
562
563
			// Allow third party add-on developers to handle their subscription check.
564
			if ( $this->__is_third_party_addon() ) {
565
				do_action( 'give_weekly_subscription_check', $this );
566
567
				return false;
568
			}
569
570
			// Delete subscription notices show blocker.
571
			$this->__remove_license_notices_show_blocker();
572
573
			// Data to send in our API request.
574
			$api_params = array(
575
				// Do not get confused with edd_action check_subscription.
576
				// By default edd software licensing api does not have api to check subscription.
577
				// This is a custom feature to check subscriptions.
578
				'edd_action' => 'check_subscription',
579
				'license'    => $this->license,
580
				'item_name'  => urlencode( $this->item_name ),
581
				'url'        => home_url(),
582
			);
583
584
			// Call the API
585
			$response = wp_remote_post(
586
				$this->api_url,
587
				array(
588
					'timeout'   => 15,
589
					'sslverify' => false,
590
					'body'      => $api_params,
591
				)
592
			);
593
594
			// Make sure the response came back okay.
595
			if ( is_wp_error( $response ) ) {
596
				return false;
597
			}
598
599
			$subscription_data = json_decode( wp_remote_retrieve_body( $response ), true );
600
601
			if ( ! empty( $subscription_data['success'] ) && absint( $subscription_data['success'] ) ) {
602
				$subscriptions = get_option( 'give_subscriptions', array() );
603
604
				// Update subscription data only if subscription does not exist already.
605
				if ( ! array_key_exists( $subscription_data['id'], $subscriptions ) ) {
606
					$subscriptions[ $subscription_data['id'] ]             = $subscription_data;
607
					$subscriptions[ $subscription_data['id'] ]['licenses'] = array();
608
				}
609
610
				// Store licenses for subscription.
611
				if ( ! in_array( $this->license, $subscriptions[ $subscription_data['id'] ]['licenses'] ) ) {
612
					$subscriptions[ $subscription_data['id'] ]['licenses'][] = $this->license;
613
				}
614
615
				update_option( 'give_subscriptions', $subscriptions );
616
			}
617
		}
618
619
		/**
620
		 * Check if license key is part of subscription or not
621
		 *
622
		 * @access private
623
		 * @since  1.7
624
		 *
625
		 * @return bool|void
626
		 */
627
		private function __single_subscription_check() {
628
			// Do not fire if license key is not set.
629
			if ( ! isset( $_POST[ $this->item_shortname . '_license_key' ] ) ) {
630
				return false;
631
			}
632
633
			if ( empty( $this->license ) ) {
634
				return false;
635
			}
636
637
			// Data to send in our API request.
638
			$api_params = array(
639
				// Do not get confused with edd_action check_subscription.
640
				// By default edd software licensing api does not have api to check subscription.
641
				// This is a custom feature to check subscriptions.
642
				'edd_action' => 'check_subscription',
643
				'license'    => $this->license,
644
				'item_name'  => urlencode( $this->item_name ),
645
				'url'        => home_url(),
646
			);
647
648
			// Call the API
649
			$response = wp_remote_post(
650
				$this->api_url,
651
				array(
652
					'timeout'   => 15,
653
					'sslverify' => false,
654
					'body'      => $api_params,
655
				)
656
			);
657
658
			// Make sure the response came back okay.
659
			if ( is_wp_error( $response ) ) {
660
				return false;
661
			}
662
663
			$subscription_data = json_decode( wp_remote_retrieve_body( $response ), true );
664
665
			if ( ! empty( $subscription_data['success'] ) && absint( $subscription_data['success'] ) ) {
666
				$subscriptions = get_option( 'give_subscriptions', array() );
667
668
				// Update subscription data only if subscription does not exist already.
669
				if ( ! array_key_exists( $subscription_data['id'], $subscriptions ) ) {
670
					$subscriptions[ $subscription_data['id'] ]             = $subscription_data;
671
					$subscriptions[ $subscription_data['id'] ]['licenses'] = array();
672
				}
673
674
				// Store licenses for subscription.
675
				if ( ! in_array( $this->license, $subscriptions[ $subscription_data['id'] ]['licenses'] ) ) {
676
					$subscriptions[ $subscription_data['id'] ]['licenses'][] = $this->license;
677
				}
678
679
				update_option( 'give_subscriptions', $subscriptions );
680
			}
681
		}
682
683
		/**
684
		 * Admin notices for errors
685
		 *
686
		 * @access public
687
		 * @since  1.0
688
		 *
689
		 * @return void
690
		 */
691
		public function notices() {
692
693
			if ( ! current_user_can( 'manage_give_settings' ) ) {
694
				return;
695
			}
696
697
			// Do not show licenses notices on license tab.
698
			if ( 'licenses' === give_get_current_setting_tab() ) {
699
				return;
700
			}
701
702
			static $showed_invalid_message;
703
			static $showed_subscriptions_message;
704
			static $addon_license_key_in_subscriptions;
705
706
			// Set default value.
707
			$addon_license_key_in_subscriptions = ! empty( $addon_license_key_in_subscriptions ) ? $addon_license_key_in_subscriptions : array();
708
			$messages                           = array();
709
710
			if (
711
				empty( $this->license )
712
				&& ! $this->__is_notice_dismissed( 'general' )
713
				&& empty( $showed_invalid_message )
714
			) {
715
				$messages['general']    = sprintf(
716
					__( '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' ),
717
					admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' )
718
				);
719
				$showed_invalid_message = true;
720
721
			}
722
723
			// Get subscriptions.
724
			$subscriptions = get_option( 'give_subscriptions' );
725
726
			// Show subscription messages.
727
			if ( ! empty( $subscriptions ) && ! $showed_subscriptions_message ) {
728
729
				foreach ( $subscriptions as $subscription ) {
730
					// Subscription expires timestamp.
731
					$subscription_expires = strtotime( $subscription['expires'] );
732
733
					// Start showing subscriptions message before one week of renewal date.
734
					if ( strtotime( '- 7 days', $subscription_expires ) > current_time( 'timestamp', 1 ) ) {
735
						continue;
736
					}
737
738
					// Check if subscription message already exist in messages.
739
					if ( array_key_exists( $subscription['id'], $messages ) ) {
740
						continue;
741
					}
742
743
					if ( ( ! $this->__is_notice_dismissed( $subscription['id'] ) && 'active' !== $subscription['status'] ) ) {
744
745
						if ( strtotime( $subscription['expires'] ) < current_time( 'timestamp', 1 ) ) {// Check if license already expired.
746
							$messages[ $subscription['id'] ] = sprintf(
747
								__( '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' ),
748
								urldecode( $subscription['invoice_url'] ),
749
								$subscription['payment_id'],
750
								"{$this->checkout_url}?edd_license_key={$subscription['license_key']}&utm_campaign=admin&utm_source=licenses&utm_medium=expired",
751
								esc_url( add_query_arg( '_give_hide_license_notices_permanently', $subscription['id'], $_SERVER['REQUEST_URI'] ) )
752
							);
753
						} else {
754
							$messages[ $subscription['id'] ] = sprintf(
755
								__( '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' ),
756
								human_time_diff( current_time( 'timestamp', 1 ), strtotime( $subscription['expires'] ) ),
757
								urldecode( $subscription['invoice_url'] ),
758
								$subscription['payment_id'],
759
								"{$this->checkout_url}?edd_license_key={$subscription['license_key']}&utm_campaign=admin&utm_source=licenses&utm_medium=expired",
760
								esc_url( add_query_arg( '_give_hide_license_notices_permanently', $subscription['id'], $_SERVER['REQUEST_URI'] ) )
761
							);
762
						}
763
					}
764
765
					// Stop validation for these license keys.
766
					$addon_license_key_in_subscriptions = array_merge( $addon_license_key_in_subscriptions, $subscription['licenses'] );
767
				}// 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...
768
				$showed_subscriptions_message = true;
769
			}// 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...
770
771
			// Show non subscription addon messages.
772
			if (
773
				! in_array( $this->license, $addon_license_key_in_subscriptions )
774
				&& ! $this->__is_notice_dismissed( 'general' )
775
				&& ! $this->is_valid_license()
776
				&& empty( $showed_invalid_message )
777
			) {
778
779
				$messages['general']    = sprintf(
780
					__( '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' ),
781
					admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' )
782
				);
783
				$showed_invalid_message = true;
784
785
			}
786
787
			// Print messages.
788
			if ( ! empty( $messages ) ) {
789
				foreach ( $messages as $notice_id => $message ) {
790
791
					echo sprintf(
792
						'<div class="notice notice-error is-dismissible give-license-notice" data-dismiss-notice-shortly="%1$s"><p>%2$s</p></div>',
793
						esc_url( add_query_arg( '_give_hide_license_notices_shortly', $notice_id, $_SERVER['REQUEST_URI'] ) ),
794
						$message
795
					);
796
				}
797
			}
798
		}
799
800
		/**
801
		 * Check if license is valid or not.
802
		 *
803
		 * @access public
804
		 * @since  1.7
805
		 *
806
		 * @return bool
807
		 */
808
		public function is_valid_license() {
809
			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 ) ) ) {
810
				return true;
811
			}
812
813
			return false;
814
		}
815
816
		/**
817
		 * Check if license is valid or not.
818
		 *
819
		 * @access private
820
		 * @since  1.7
821
		 *
822
		 * @return bool
823
		 */
824
		private function __is_third_party_addon() {
825
			return ( false === strpos( $this->api_url, 'givewp.com/' ) );
826
		}
827
828
		/**
829
		 * Remove license key from subscription.
830
		 *
831
		 * This function mainly uses when admin user deactivate license key,
832
		 * then we do not need subscription information for that license key.
833
		 *
834
		 * @access private
835
		 * @since  1.7
836
		 *
837
		 * @return void|bool
838
		 */
839
		private function __remove_license_key_from_subscriptions() {
840
			$subscriptions = get_option( 'give_subscriptions', array() );
841
842
			// Bailout.
843
			if ( empty( $this->license ) ) {
844
				return false;
845
			}
846
847
			if ( ! empty( $subscriptions ) ) {
848
				foreach ( $subscriptions as $subscription_id => $subscription ) {
849
					$license_index = array_search( $this->license, $subscription['licenses'] );
850
					if ( false !== $license_index ) {
851
						// Remove license key.
852
						unset( $subscriptions[ $subscription_id ]['licenses'][ $license_index ] );
853
854
						// Rearrange license keys.
855
						$subscriptions[ $subscription_id ]['licenses'] = array_values( $subscriptions[ $subscription_id ]['licenses'] );
856
857
						// Update subscription information.
858
						update_option( 'give_subscriptions', $subscriptions );
859
						break;
860
					}
861
				}
862
			}
863
		}
864
865
		/**
866
		 * Remove license notices show blocker.
867
		 *
868
		 * @access private
869
		 * @since  1.7
870
		 *
871
		 * @return void
872
		 */
873
		private function __remove_license_notices_show_blocker() {
874
			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...
875
876
			// Delete permanent notice blocker.
877
			$wpdb->query(
878
				$wpdb->prepare(
879
					"
880
					DELETE FROM $wpdb->usermeta
881
					WHERE meta_key
882
					LIKE '%%%s%%'
883
					",
884
					'_give_hide_license_notices_permanently'
885
				)
886
			);
887
888
			// Delete short notice blocker.
889
			$wpdb->query(
890
				$wpdb->prepare(
891
					"
892
					DELETE FROM $wpdb->options
893
					WHERE option_name
894
					LIKE '%%%s%%'
895
					",
896
					'__give_hide_license_notices_shortly_'
897
				)
898
			);
899
		}
900
901
		/**
902
		 * Check if notice dismissed by admin user or not.
903
		 *
904
		 * @access private
905
		 * @since  1.7
906
		 *
907
		 * @param  int $notice_id Notice ID.
908
		 *
909
		 * @return bool
910
		 */
911
		private function __is_notice_dismissed( $notice_id ) {
912
			$current_user        = wp_get_current_user();
913
			$is_notice_dismissed = false;
914
915
			// Ge is notice dismissed permanently.
916
			$already_dismiss_notices = ( $already_dismiss_notices = get_user_meta( $current_user->ID, '_give_hide_license_notices_permanently', true ) )
917
				? $already_dismiss_notices
918
				: array();
919
920
			if (
921
				in_array( $notice_id, $already_dismiss_notices )
922
				|| false !== Give_Cache::get( "_give_hide_license_notices_shortly_{$current_user->ID}_{$notice_id}", true )
923
			) {
924
				$is_notice_dismissed = true;
925
			}
926
927
			return $is_notice_dismissed;
928
		}
929
930
931
		/**
932
		 * @param $plugin_file
933
		 * @param $plugin_data
934
		 * @param $status
935
		 *
936
		 * @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...
937
		 */
938
		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...
939
			// Bailout.
940
			if ( $this->is_valid_license() ) {
941
				return false;
942
			}
943
944
			$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>';
945
			$message            = $this->license_state_message();
946
947
			if ( ! empty( $message['message'] ) ) {
948
				echo sprintf( $update_notice_wrap, $message['message'] );
949
			}
950
		}
951
952
953
		/**
954
		 * Get message related to license state.
955
		 *
956
		 * @since  1.8.7
957
		 * @access public
958
		 * @return array
959
		 */
960
		public function license_state_message() {
961
			$message_data = array();
962
963
			if ( ! $this->is_valid_license() ) {
964
965
				$message_data['message'] = sprintf(
966
					'Please <a href="%1$s">activate your license</a> to receive updates and support for the %2$s add-on.',
967
					esc_url( admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' ) ),
968
					$this->item_name
969
				);
970
			}
971
972
			return $message_data;
973
		}
974
	}
975
976
endif; // end class_exists check
977