PluginProbe
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More / 2.0.1
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More v2.0.1
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.1, at classes/Plugin/License.php

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