PluginProbe
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More / 2.0.4
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More v2.0.4
trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.10 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 47 releases
content-control / classes / Plugin / License.php

License.php in Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More 2.0.4, at classes/Plugin/License.php

482 lines 11.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Upgrade management.
4 *
5 * @copyright (c) 2023, Code Atlantic LLC.
6 *
7 * @package ContentControl
8 */
9
10 namespace ContentControl\Plugin;
11
12 defined( 'ABSPATH' ) || exit;
13
14 /**
15 * License management.
16 *
17 * @package ContentControl
18 */
19 class License {
20
21 /**
22 * EDD API URL.
23 *
24 * @var string
25 */
26 const API_URL = 'https://contentcontrolplugin.com/edd-sl-api/';
27
28 /**
29 * Item ID.
30 *
31 * @var int
32 */
33 const ID = 45;
34
35 /**
36 * Option key.
37 *
38 * @var string
39 */
40 const OPTION_KEY = 'content_control_license';
41
42 /**
43 * Container.
44 *
45 * @var Container
46 */
47 private $c;
48
49 /**
50 * License data
51 *
52 * @var array
53 */
54 private $license_data;
55
56 /**
57 * Initialize license management.
58 *
59 * @param Container $c Container.
60 */
61 public function __construct( $c ) {
62 $this->c = $c;
63
64 $this->register_hooks();
65 }
66
67 /**
68 * Register hooks.
69 */
70 public function register_hooks() {
71 add_action( 'init', [ $this, 'autoregister' ] );
72 add_action( 'content_control_license_status_check', [ $this, 'refresh_license_status' ] );
73 add_action( 'admin_init', [ $this, 'schedule_crons' ] );
74 }
75
76 /**
77 * Autoregister license.
78 */
79 public function autoregister() {
80 if ( defined( '\CONTENT_CONTROL_LICENSE_KEY' ) && ! empty( \CONTENT_CONTROL_LICENSE_KEY ) && '' === $this->get_license_key() ) {
81 try {
82 $this->activate_license( \CONTENT_CONTROL_LICENSE_KEY );
83 } catch ( \Exception $e ) {
84 // Do nothing.
85 }
86 }
87 }
88
89 /**
90 * Schedule cron jobs.
91 */
92 public function schedule_crons() {
93 if ( ! wp_next_scheduled( 'content_control_license_status_check' ) ) {
94 wp_schedule_event( time(), 'daily', 'content_control_license_status_check' );
95 }
96 }
97
98 /**
99 * Get license data.
100 *
101 * @return array
102 */
103 public function get_license_data() {
104 if ( ! isset( $this->license_data ) ) {
105 $this->license_data = \get_option( self::OPTION_KEY, [
106 'key' => '',
107 'status' => [
108 'success' => false, // bool.
109 'license' => 'invalid', // valid or invalid.
110 'item_id' => self::ID, // int or false.
111 'item_name' => '', // string.
112 'license_limit' => 1, // int. 0 = unlimited.
113 'site_count' => 0,
114 'expires' => '', // date or 'lifetime'.
115 'activations_left' => 0, // int or 'unlimited'.
116 'checksum' => '', // string.
117 'payment_id' => 0, // int.
118 'customer_name' => '', // string.
119 'customer_email' => '', // string.
120 'price_id' => 0, // string or int.
121 'error' => null, // string. expired, missing, invalid, item_name_mismatch, no_activations_left etc.
122 ],
123 ] );
124 }
125
126 return $this->license_data;
127 }
128
129 /**
130 * Get license key.
131 *
132 * @return string
133 */
134 public function get_license_key() {
135 $license_data = $this->get_license_data();
136 return isset( $license_data['key'] ) ? $license_data['key'] : '';
137 }
138
139 /**
140 * Get license status.
141 *
142 * @return array Array of license status data.
143 */
144 public function get_license_status() {
145 $license_data = $this->get_license_data();
146
147 $license_status = isset( $license_data['status'] ) ? $license_data['status'] : [];
148
149 return $license_status;
150 }
151
152 /**
153 * Update license data.
154 *
155 * @param array $license_data License data.
156 */
157 public function udpate_license_data( $license_data ) {
158 if ( \update_option( self::OPTION_KEY, $license_data ) ) {
159 $this->license_data = $license_data;
160 return true;
161 }
162
163 return false;
164 }
165
166 /**
167 * Update license key.
168 *
169 * @param string $key License key.
170 */
171 public function update_license_key( $key ) {
172 $license_data = $this->get_license_data();
173
174 $old_key = isset( $license_data['key'] ) ? $license_data['key'] : '';
175
176 $license_data['key'] = trim( $key );
177
178 $this->udpate_license_data( $license_data );
179
180 /**
181 * Fires when license key is changed.
182 *
183 * @param string $key License key.
184 * @param string $old_key Old license key.
185 */
186 \do_action( 'content_control_license_key_changed', $key, $old_key );
187 }
188
189 /**
190 * Update license status.
191 *
192 * @param array $license_status License status data.
193 */
194 public function update_license_status( $license_status ) {
195 $license_data = $this->get_license_data();
196
197 $previous_status = isset( $license_data['status'] ) ? $license_data['status'] : [];
198
199 if ( ! empty( $license_status['error'] ) ) {
200 $license_status['error_message'] = $this->get_license_error_message( $license_status );
201 }
202
203 $license_data['status'] = $license_status;
204
205 $this->udpate_license_data( $license_data );
206
207 /**
208 * Fires when license status is updated.
209 *
210 * @param array $license_status License status data.
211 * @param array $previous_status Previous license status data.
212 */
213 \do_action( 'content_control_license_status_updated', $license_status, $previous_status );
214 }
215
216 /**
217 * Get license expiration from license status data.
218 *
219 * @param bool $as_datetime Whether to return as DateTime object.
220 *
221 * @return DateTime|false|null
222 */
223 public function get_license_expiration( $as_datetime = false ) {
224 $status = $this->get_license_status();
225
226 $expiration = isset( $status['expires'] ) ? $status['expires'] : null;
227
228 return $as_datetime ?
229 \DateTime::createFromFormat( 'Y-m-d H:i:s', $expiration ) :
230 $expiration;
231 }
232
233 /**
234 * Fetch license status from remote server.
235 * This is a blocking request.
236 *
237 * @return array
238 */
239 public function refresh_license_status() {
240 $key = $this->get_license_key();
241
242 if ( empty( $key ) ) {
243 return [];
244 }
245
246 try {
247 $status = $this->check_license();
248 } catch ( \Exception $e ) {
249 $status = [];
250 }
251
252 $this->update_license_status( $status );
253
254 return $status;
255 }
256
257 /**
258 * Get license status from remote server.
259 *
260 * @return array
261 *
262 * @throws \Exception If there is an error.
263 */
264 private function check_license() {
265 $api_params = [
266 'edd_action' => 'check_license',
267 'license' => $this->get_license_key(),
268 'item_id' => self::ID,
269 'item_name' => rawurlencode( 'Content Control Pro' ),
270 'url' => home_url(),
271 'environment' => function_exists( 'wp_get_environment_type' ) ? wp_get_environment_type() : 'production',
272 ];
273
274 // Call the custom API.
275 $response = wp_remote_post(
276 self::API_URL,
277 [
278 'timeout' => 15,
279 'sslverify' => false,
280 'body' => $api_params,
281 ]
282 );
283
284 if ( is_wp_error( $response ) ) {
285 throw new \Exception( esc_html( $response->get_error_message() ) );
286 }
287
288 $license_status = json_decode( wp_remote_retrieve_body( $response ), true );
289
290 if ( empty( $license_status ) ) {
291 return [];
292 }
293
294 return $license_status;
295 }
296
297 /**
298 * Activate license.
299 *
300 * @param string $key License key.
301 *
302 * @return array License status data.
303 *
304 * @throws \Exception If there is an error.
305 */
306 public function activate_license( $key = null ) {
307 if ( ! empty( $key ) ) {
308 $this->update_license_key( $key );
309 } else {
310 $key = $this->get_license_key();
311 }
312
313 $api_params = [
314 'edd_action' => 'activate_license',
315 'license' => $key,
316 'item_id' => self::ID,
317 'item_name' => rawurlencode( 'Content Control' ),
318 'url' => home_url(),
319 'environment' => function_exists( 'wp_get_environment_type' ) ? wp_get_environment_type() : 'production',
320 ];
321
322 // Call the custom API.
323 $response = wp_remote_post(
324 self::API_URL,
325 [
326 'timeout' => 15,
327 'sslverify' => false,
328 'body' => $api_params,
329 ]
330 );
331
332 // Make sure the response came back okay.
333 if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
334 if ( is_wp_error( $response ) ) {
335 $message = $response->get_error_message();
336 } else {
337 $message = __( 'An error occurred, please try again.', 'content-control' );
338 }
339
340 throw new \Exception( esc_html( $message ) );
341 }
342
343 $license_status = json_decode( wp_remote_retrieve_body( $response ), true );
344
345 $this->update_license_status( $license_status );
346
347 if ( $this->is_license_active() ) {
348 if ( ! \get_option( 'content_control_pro_activation_date', false ) ) {
349 \update_option( 'content_control_pro_activation_date', time() );
350 }
351 }
352
353 return $this->get_license_status();
354 }
355
356 /**
357 * Deactivate license.
358 *
359 * @return array License status data.
360 *
361 * @throws \Exception If there is an error.
362 */
363 public function deactivate_license() {
364 $api_params = [
365 'edd_action' => 'deactivate_license',
366 'license' => $this->get_license_key(),
367 'item_id' => self::ID,
368 'item_name' => rawurlencode( 'Content Control' ),
369 'url' => home_url(),
370 'environment' => function_exists( 'wp_get_environment_type' ) ? wp_get_environment_type() : 'production',
371 ];
372
373 // Call the custom API.
374 $response = wp_remote_post(
375 self::API_URL,
376 [
377 'timeout' => 15,
378 'sslverify' => false,
379 'body' => $api_params,
380 ]
381 );
382
383 // Make sure the response came back okay.
384 if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
385 if ( is_wp_error( $response ) ) {
386 $message = $response->get_error_message();
387 } else {
388 $message = __( 'An error occurred, please try again.', 'content-control' );
389 }
390
391 throw new \Exception( esc_html( $message ) );
392 }
393
394 $license_status = json_decode( wp_remote_retrieve_body( $response ), true );
395
396 $this->update_license_status( $license_status );
397
398 return $license_status;
399 }
400
401 /**
402 * Convert license error to human readable message.
403 *
404 * @param array $license_status License status data.
405 *
406 * @return string
407 */
408 public function get_license_error_message( $license_status ) {
409 switch ( $license_status['error'] ) {
410 case 'expired':
411 $message = sprintf(
412 /* translators: the license key expiration date */
413 __( 'Your license key expired on %s.', 'content-control' ),
414 date_i18n( \get_option( 'date_format' ), strtotime( $license_status['expires'], time() ) )
415 );
416 break;
417
418 case 'disabled':
419 case 'revoked':
420 $message = __( 'Your license key has been disabled.', 'content-control' );
421 break;
422
423 case 'missing':
424 $message = __( 'Invalid license.', 'content-control' );
425 break;
426
427 case 'invalid':
428 case 'site_inactive':
429 $message = __( 'Your license is not active for this URL.', 'content-control' );
430 break;
431
432 case 'item_name_mismatch':
433 $message = sprintf(
434 /* translators: the plugin name */
435 __( 'This appears to be an invalid license key for %s.', 'content-control' ),
436 __( 'Content Control', 'content-control' )
437 );
438 break;
439
440 case 'no_activations_left':
441 $message = __( 'Your license key has reached its activation limit.', 'content-control' );
442 break;
443
444 default:
445 $message = __( 'An error occurred, please try again.', 'content-control' );
446 break;
447 }
448
449 return $message;
450 }
451
452 /**
453 * Remove license.
454 */
455 public function remove_license() {
456 try {
457 $deactivated = $this->deactivate_license();
458 } catch ( \Exception $e ) {
459 $deactivated = [];
460 }
461
462 if ( ! empty( $deactivated['license'] ) && 'active' !== $deactivated['license'] ) {
463 \delete_option( self::OPTION_KEY );
464 }
465 }
466
467 /**
468 * Check if license is active.
469 *
470 * @return bool
471 */
472 public function is_license_active() {
473 $license_status = $this->get_license_status();
474
475 if ( empty( $license_status ) ) {
476 return false;
477 }
478
479 return 'valid' === $license_status['license'];
480 }
481 }
482