PluginProbe
weForms – Easy Drag & Drop Contact Form Builder For WordPress / 1.4.7
weForms – Easy Drag & Drop Contact Form Builder For WordPress v1.4.7
1.6.7 1.6.8 1.6.9 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.18 1.6.19 1.6.2 1.6.20 1.6.21 1.6.22 1.6.23 1.6.24 1.6.25 1.6.26 1.6.27 1.6.28 1.6.3 1.6.4 1.6.5 1.6.6 All 74 releases
← All changes | includes/library/appsero/License.php +701 -701 1.6.12 → 1.4.7 View file →
@@ -1,701 +1,701 @@
1 -<?php
2 -namespace Appsero;
3 -
4 -/**
5 - * Appsero License Checker
6 - *
7 - * This class will check, active and deactive license
8 - */
9 -class License {
10 -
11 - /**
12 - * AppSero\Client
13 - *
14 - * @var object
15 - */
16 - protected $client;
17 -
18 - /**
19 - * Arguments of create menu
20 - *
21 - * @var array
22 - */
23 - protected $menu_args;
24 -
25 - /**
26 - * `option_name` of `wp_options` table
27 - *
28 - * @var string
29 - */
30 - protected $option_key;
31 -
32 - /**
33 - * Error message of HTTP request
34 - *
35 - * @var string
36 - */
37 - public $error;
38 -
39 - /**
40 - * Success message on form submit
41 - *
42 - * @var string
43 - */
44 - public $success;
45 -
46 - /**
47 - * Corn schedule hook name
48 - *
49 - * @var string
50 - */
51 - protected $schedule_hook;
52 -
53 - /**
54 - * Set value for valid licnese
55 - *
56 - * @var boolean
57 - */
58 - private $is_valid_licnese = null;
59 -
60 - /**
61 - * Initialize the class
62 - *
63 - * @param Appsero\Client
64 - */
65 - public function __construct( Client $client ) {
66 - $this->client = $client;
67 -
68 - $this->option_key = 'appsero_' . md5( $this->client->slug ) . '_manage_license';
69 -
70 - $this->schedule_hook = $this->client->slug . '_license_check_event';
71 -
72 - // Run hook to check license status daily
73 - add_action( $this->schedule_hook, array( $this, 'check_license_status' ) );
74 -
75 - // Active/Deactive corn schedule
76 - $this->run_schedule();
77 - }
78 -
79 - /**
80 - * Check license
81 - *
82 - * @return boolean
83 - */
84 - public function check( $license_key ) {
85 - $route = 'public/license/' . $this->client->hash . '/check';
86 -
87 - return $this->send_request( $license_key, $route );
88 - }
89 -
90 - /**
91 - * Active a license
92 - *
93 - * @return boolean
94 - */
95 - public function activate( $license_key ) {
96 - $route = 'public/license/' . $this->client->hash . '/activate';
97 -
98 - return $this->send_request( $license_key, $route );
99 - }
100 -
101 - /**
102 - * Deactivate a license
103 - *
104 - * @return boolean
105 - */
106 - public function deactivate( $license_key ) {
107 - $route = 'public/license/' . $this->client->hash . '/deactivate';
108 -
109 - return $this->send_request( $license_key, $route );
110 - }
111 -
112 - /**
113 - * Send common request
114 - *
115 - * @param $license_key
116 - * @param $route
117 - *
118 - * @return array
119 - */
120 - protected function send_request( $license_key, $route ) {
121 - $params = array(
122 - 'license_key' => $license_key,
123 - 'url' => esc_url( home_url() ),
124 - );
125 -
126 - $response = $this->client->send_request( $params, $route, true );
127 -
128 - if ( is_wp_error( $response ) ) {
129 - return array(
130 - 'success' => false,
131 - 'error' => $response->get_error_message()
132 - );
133 - }
134 -
135 - $response = json_decode( wp_remote_retrieve_body( $response ), true );
136 -
137 - if ( empty( $response ) || isset( $response['exception'] )) {
138 - return array(
139 - 'success' => false,
140 - 'error' => 'Unknown error occurred, Please try again.'
141 - );
142 - }
143 -
144 - if ( isset( $response['errors'] ) && isset( $response['errors']['license_key'] ) ) {
145 - $response = array(
146 - 'success' => false,
147 - 'error' => $response['errors']['license_key'][0]
148 - );
149 - }
150 -
151 - return $response;
152 - }
153 -
154 - /**
155 - * Add settings page for license
156 - *
157 - * @param array $args
158 - *
159 - * @return void
160 - */
161 - public function add_settings_page( $args = array() ) {
162 - $defaults = array(
163 - 'type' => 'menu', // Can be: menu, options, submenu
164 - 'page_title' => 'Manage License',
165 - 'menu_title' => 'Manage License',
166 - 'capability' => 'manage_options',
167 - 'menu_slug' => $this->client->slug . '-manage-license',
168 - 'icon_url' => '',
169 - 'position' => null,
170 - 'parent_slug' => '',
171 - );
172 -
173 - $this->menu_args = wp_parse_args( $args, $defaults );
174 -
175 - add_action( 'admin_menu', array( $this, 'admin_menu' ), 99 );
176 - }
177 -
178 - /**
179 - * Admin Menu hook
180 - *
181 - * @return void
182 - */
183 - public function admin_menu() {
184 - switch ( $this->menu_args['type'] ) {
185 - case 'menu':
186 - $this->add_menu_page();
187 - break;
188 -
189 - case 'submenu':
190 - $this->add_submenu_page();
191 - break;
192 -
193 - case 'options':
194 - $this->add_options_page();
195 - break;
196 - }
197 - }
198 -
199 - /**
200 - * License menu output
201 - */
202 - public function menu_output() {
203 -
204 - if ( isset( $_POST['submit'] ) ) {
205 - $this->license_form_submit( $_POST );
206 - }
207 -
208 - $license = get_option( $this->option_key, null );
209 - $action = ( $license && isset( $license['status'] ) && 'activate' == $license['status'] ) ? 'deactive' : 'active';
210 - $this->licenses_style();
211 - ?>
212 -
213 - <div class="wrap appsero-license-settings-wrapper">
214 - <h1>License Settings</h1>
215 -
216 - <?php
217 - $this->show_license_page_notices();
218 - do_action( 'before_appsero_license_section' );
219 - ?>
220 -
221 - <div class="appsero-license-settings appsero-license-section">
222 - <?php $this->show_license_page_card_header(); ?>
223 -
224 - <div class="appsero-license-details">
225 - <p>Active <strong><?php echo $this->client->name; ?></strong> by your license key to get professional support and automatic update from your WordPress dashboard.</p>
226 - <form method="post" action="<?php $this->formActionUrl(); ?>" novalidate="novalidate" spellcheck="false">
227 - <input type="hidden" name="_action" value="<?php echo $action; ?>">
228 - <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce( $this->client->name ); ?>">
229 - <div class="license-input-fields">
230 - <div class="license-input-key">
231 - <svg enable-background="new 0 0 512 512" version="1.1" viewBox="0 0 512 512" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
232 - <path d="m463.75 48.251c-64.336-64.336-169.01-64.335-233.35 1e-3 -43.945 43.945-59.209 108.71-40.181 167.46l-185.82 185.82c-2.813 2.813-4.395 6.621-4.395 10.606v84.858c0 8.291 6.709 15 15 15h84.858c3.984 0 7.793-1.582 10.605-4.395l21.211-21.226c3.237-3.237 4.819-7.778 4.292-12.334l-2.637-22.793 31.582-2.974c7.178-0.674 12.847-6.343 13.521-13.521l2.974-31.582 22.793 2.651c4.233 0.571 8.496-0.85 11.704-3.691 3.193-2.856 5.024-6.929 5.024-11.206v-27.929h27.422c3.984 0 7.793-1.582 10.605-4.395l38.467-37.958c58.74 19.043 122.38 4.929 166.33-39.046 64.336-64.335 64.336-169.01 0-233.35zm-42.435 106.07c-17.549 17.549-46.084 17.549-63.633 0s-17.549-46.084 0-63.633 46.084-17.549 63.633 0 17.548 46.084 0 63.633z"/>
233 - </svg>
234 - <input type="text" value="<?php echo $this->get_input_license_value( $action, $license ); ?>"
235 - placeholder="Enter your license key to activate" name="license_key"
236 - <?php echo ( 'deactive' == $action ) ? 'readonly="readonly"' : ''; ?>
237 - />
238 - </div>
239 - <button type="submit" name="submit" class="<?php echo 'deactive' == $action ? 'deactive-button' : ''; ?>">
240 - <?php echo $action == 'active' ? 'Activate License' : 'Deactivate License' ; ?>
241 - </button>
242 - </div>
243 - </form>
244 -
245 - <?php
246 - if ( 'deactive' == $action && isset( $license['remaining'] ) ) {
247 - $this->show_active_license_info( $license );
248 - }
249 - ?>
250 - </div>
251 - </div> <!-- /.appsero-license-settings -->
252 -
253 - <?php do_action( 'after_appsero_license_section' ); ?>
254 - </div>
255 - <?php
256 - }
257 -
258 - /**
259 - * License form submit
260 - */
261 - public function license_form_submit( $form ) {
262 - if ( ! isset( $form['_nonce'], $form['_action'] ) ) {
263 - $this->error = "Please add all information";
264 - return;
265 - }
266 -
267 - if ( ! wp_verify_nonce( $form['_nonce'], $this->client->name ) ) {
268 - $this->error = "You don't have permission to manage license.";
269 - return;
270 - }
271 -
272 - switch ( $form['_action'] ) {
273 - case 'active':
274 - $this->active_client_license( $form );
275 - break;
276 -
277 - case 'deactive':
278 - $this->deactive_client_license( $form );
279 - break;
280 - }
281 - }
282 -
283 - /**
284 - * Check license status on schedule
285 - */
286 - public function check_license_status() {
287 - $license = get_option( $this->option_key, null );
288 -
289 - if ( isset( $license['key'] ) && ! empty( $license['key'] ) ) {
290 - $response = $this->check( $license['key'] );
291 -
292 - if ( isset( $response['success'] ) && $response['success'] ) {
293 - $license['status'] = 'activate';
294 - $license['remaining'] = $response['remaining'];
295 - $license['activation_limit'] = $response['activation_limit'];
296 - $license['expiry_days'] = $response['expiry_days'];
297 - $license['title'] = $response['title'];
298 - $license['source_id'] = $response['source_identifier'];
299 - $license['recurring'] = $response['recurring'];
300 - } else {
301 - $license['status'] = 'deactivate';
302 - $license['expiry_days'] = 0;
303 - }
304 -
305 - update_option( $this->option_key, $license, false );
306 - }
307 - }
308 -
309 - /**
310 - * Check this is a valid license
311 - */
312 - public function is_valid() {
313 - if ( null !== $this->is_valid_licnese ) {
314 - return $this->is_valid_licnese;
315 - }
316 -
317 - $license = get_option( $this->option_key, null );
318 - if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
319 - $this->is_valid_licnese = true;
320 - } else {
321 - $this->is_valid_licnese = false;
322 - }
323 -
324 - return $this->is_valid_licnese;
325 - }
326 -
327 - /**
328 - * Check this is a valid license
329 - */
330 - public function is_valid_by( $option, $value ) {
331 - $license = get_option( $this->option_key, null );
332 -
333 - if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
334 - if ( isset( $license[ $option ] ) && $license[ $option ] == $value ) {
335 - return true;
336 - }
337 - }
338 -
339 - return false;
340 - }
341 -
342 - /**
343 - * Styles for licenses page
344 - */
345 - private function licenses_style() {
346 - ?>
347 - <style type="text/css">
348 - .appsero-license-section {
349 - width: 100%;
350 - max-width: 1100px;
351 - min-height: 1px;
352 - box-sizing: border-box;
353 - }
354 - .appsero-license-settings {
355 - background-color: #fff;
356 - box-shadow: 0px 3px 10px rgba(16, 16, 16, 0.05);
357 - }
358 - .appsero-license-settings * {
359 - box-sizing: border-box;
360 - }
361 - .appsero-license-title {
362 - background-color: #F8FAFB;
363 - border-bottom: 2px solid #EAEAEA;
364 - display: flex;
365 - align-items: center;
366 - padding: 10px 20px;
367 - }
368 - .appsero-license-title svg {
369 - width: 30px;
370 - height: 30px;
371 - fill: #0082BF;
372 - }
373 - .appsero-license-title span {
374 - font-size: 17px;
375 - color: #444444;
376 - margin-left: 10px;
377 - }
378 - .appsero-license-details {
379 - padding: 20px;
380 - }
381 - .appsero-license-details p {
382 - font-size: 15px;
383 - margin: 0 0 20px 0;
384 - }
385 - .license-input-key {
386 - position: relative;
387 - flex: 0 0 72%;
388 - max-width: 72%;
389 - }
390 - .license-input-key input {
391 - background-color: #F9F9F9;
392 - padding: 10px 15px 10px 48px;
393 - border: 1px solid #E8E5E5;
394 - border-radius: 3px;
395 - height: 45px;
396 - font-size: 16px;
397 - color: #71777D;
398 - width: 100%;
399 - box-shadow: 0 0 0 transparent;
400 - }
401 - .license-input-key input:focus {
402 - outline: 0 none;
403 - border: 1px solid #E8E5E5;
404 - box-shadow: 0 0 0 transparent;
405 - }
406 - .license-input-key svg {
407 - width: 22px;
408 - height: 22px;
409 - fill: #0082BF;
410 - position: absolute;
411 - left: 14px;
412 - top: 13px;
413 - }
414 - .license-input-fields {
415 - display: flex;
416 - justify-content: space-between;
417 - margin-bottom: 30px;
418 - max-width: 850px;
419 - width: 100%;
420 - }
421 - .license-input-fields button {
422 - color: #fff;
423 - font-size: 17px;
424 - padding: 8px;
425 - height: 46px;
426 - background-color: #0082BF;
427 - border-radius: 3px;
428 - cursor: pointer;
429 - flex: 0 0 25%;
430 - max-width: 25%;
431 - border: 1px solid #0082BF;
432 - }
433 - .license-input-fields button.deactive-button {
434 - background-color: #E40055;
435 - border-color: #E40055;
436 - }
437 - .license-input-fields button:focus {
438 - outline: 0 none;
439 - }
440 - .active-license-info {
441 - display: flex;
442 - }
443 - .single-license-info {
444 - min-width: 220px;
445 - flex: 0 0 30%;
446 - }
447 - .single-license-info h3 {
448 - font-size: 18px;
449 - margin: 0 0 12px 0;
450 - }
451 - .single-license-info p {
452 - margin: 0;
453 - color: #00C000;
454 - }
455 - .single-license-info p.occupied {
456 - color: #E40055;
457 - }
458 - </style>
459 - <?php
460 - }
461 -
462 - /**
463 - * Show active license information
464 - */
465 - private function show_active_license_info( $license ) {
466 - ?>
467 - <div class="active-license-info">
468 - <div class="single-license-info">
469 - <h3>Activation Remaining</h3>
470 - <?php if ( empty( $license['activation_limit'] ) ): ?>
471 - <p>Unlimited</p>
472 - <?php else: ?>
473 - <p class="<?php echo $license['remaining'] ? '' : 'occupied'; ?>">
474 - <?php echo $license['remaining']; ?> out of <?php echo $license['activation_limit']; ?>
475 - </p>
476 - <?php endif; ?>
477 - </div>
478 - <div class="single-license-info">
479 - <h3>Expires in</h3>
480 - <?php
481 - if ( $license['recurring'] && false !== $license['expiry_days'] ) {
482 - $occupied = $license['expiry_days'] > 10 ? '' : 'occupied';
483 - echo '<p class="' . $occupied . '">' . $license['expiry_days'] . ' days</p>';
484 - } else {
485 - echo '<p>Never</p>';
486 - }
487 - ?>
488 - </div>
489 - </div>
490 - <?php
491 - }
492 -
493 - /**
494 - * Show license settings page notices
495 - */
496 - private function show_license_page_notices() {
497 - if ( ! empty( $this->error ) ) :
498 - ?>
499 - <div class="notice notice-error is-dismissible appsero-license-section">
500 - <p><?php echo $this->error; ?></p>
501 - </div>
502 - <?php
503 - endif;
504 - if ( ! empty( $this->success ) ) :
505 - ?>
506 - <div class="notice notice-success is-dismissible appsero-license-section">
507 - <p><?php echo $this->success; ?></p>
508 - </div>
509 - <?php
510 - endif;
511 - echo '<br />';
512 - }
513 -
514 - /**
515 - * Card header
516 - */
517 - private function show_license_page_card_header() {
518 - ?>
519 - <div class="appsero-license-title">
520 - <svg enable-background="new 0 0 299.995 299.995" version="1.1" viewBox="0 0 300 300" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
521 - <path d="m150 161.48c-8.613 0-15.598 6.982-15.598 15.598 0 5.776 3.149 10.807 7.817 13.505v17.341h15.562v-17.341c4.668-2.697 7.817-7.729 7.817-13.505 0-8.616-6.984-15.598-15.598-15.598z"/>
522 - <path d="m150 85.849c-13.111 0-23.775 10.665-23.775 23.775v25.319h47.548v-25.319c-1e-3 -13.108-10.665-23.775-23.773-23.775z"/>
523 - <path d="m150 1e-3c-82.839 0-150 67.158-150 150 0 82.837 67.156 150 150 150s150-67.161 150-150c0-82.839-67.161-150-150-150zm46.09 227.12h-92.173c-9.734 0-17.626-7.892-17.626-17.629v-56.919c0-8.491 6.007-15.582 14.003-17.25v-25.697c0-27.409 22.3-49.711 49.711-49.711 27.409 0 49.709 22.3 49.709 49.711v25.697c7.993 1.673 14 8.759 14 17.25v56.919h2e-3c0 9.736-7.892 17.629-17.626 17.629z"/>
524 - </svg>
525 - <span>Activate License</span>
526 - </div>
527 - <?php
528 - }
529 -
530 - /**
531 - * Active client license
532 - */
533 - private function active_client_license( $form ) {
534 - if ( empty( $form['license_key'] ) ) {
535 - $this->error = 'The license key field is required.';
536 - return;
537 - }
538 -
539 - $license_key = sanitize_text_field( $form['license_key'] );
540 - $response = $this->activate( $license_key );
541 -
542 - if ( ! $response['success'] ) {
543 - $this->error = $response['error'] ? $response['error'] : 'Unknown error occurred.';
544 - return;
545 - }
546 -
547 - $data = array(
548 - 'key' => $license_key,
549 - 'status' => 'activate',
550 - 'remaining' => $response['remaining'],
551 - 'activation_limit' => $response['activation_limit'],
552 - 'expiry_days' => $response['expiry_days'],
553 - 'title' => $response['title'],
554 - 'source_id' => $response['source_identifier'],
555 - 'recurring' => $response['recurring'],
556 - );
557 -
558 - update_option( $this->option_key, $data, false );
559 -
560 - $this->success = 'License activated successfully.';
561 - }
562 -
563 - /**
564 - * Deactive client license
565 - */
566 - private function deactive_client_license( $form ) {
567 - $license = get_option( $this->option_key, null );
568 -
569 - if ( empty( $license['key'] ) ) {
570 - $this->error = 'License key not found.';
571 - return;
572 - }
573 -
574 - $response = $this->deactivate( $license['key'] );
575 -
576 - $data = array(
577 - 'key' => '',
578 - 'status' => 'deactivate',
579 - );
580 -
581 - update_option( $this->option_key, $data, false );
582 -
583 - if ( ! $response['success'] ) {
584 - $this->error = $response['error'] ? $response['error'] : 'Unknown error occurred.';
585 - return;
586 - }
587 -
588 - $this->success = 'License deactivated successfully.';
589 - }
590 -
591 - /**
592 - * Add license menu page
593 - */
594 - private function add_menu_page() {
595 - add_menu_page(
596 - $this->menu_args['page_title'],
597 - $this->menu_args['menu_title'],
598 - $this->menu_args['capability'],
599 - $this->menu_args['menu_slug'],
600 - array( $this, 'menu_output' ),
601 - $this->menu_args['icon_url'],
602 - $this->menu_args['position']
603 - );
604 - }
605 -
606 - /**
607 - * Add submenu page
608 - */
609 - private function add_submenu_page() {
610 - add_submenu_page(
611 - $this->menu_args['parent_slug'],
612 - $this->menu_args['page_title'],
613 - $this->menu_args['menu_title'],
614 - $this->menu_args['capability'],
615 - $this->menu_args['menu_slug'],
616 - array( $this, 'menu_output' ),
617 - $this->menu_args['position']
618 - );
619 - }
620 -
621 - /**
622 - * Add submenu page
623 - */
624 - private function add_options_page() {
625 - add_options_page(
626 - $this->menu_args['page_title'],
627 - $this->menu_args['menu_title'],
628 - $this->menu_args['capability'],
629 - $this->menu_args['menu_slug'],
630 - array( $this, 'menu_output' ),
631 - $this->menu_args['position']
632 - );
633 - }
634 -
635 - /**
636 - * Schedule daily sicense checker event
637 - */
638 - public function schedule_cron_event() {
639 - if ( ! wp_next_scheduled( $this->schedule_hook ) ) {
640 - wp_schedule_event( time(), 'daily', $this->schedule_hook );
641 -
642 - wp_schedule_single_event( time() + 20, $this->schedule_hook );
643 - }
644 - }
645 -
646 - /**
647 - * Clear any scheduled hook
648 - */
649 - public function clear_scheduler() {
650 - wp_clear_scheduled_hook( $this->schedule_hook );
651 - }
652 -
653 - /**
654 - * Enable/Disable schedule
655 - */
656 - private function run_schedule() {
657 - switch ( $this->client->type ) {
658 - case 'plugin':
659 - register_activation_hook( $this->client->file, array( $this, 'schedule_cron_event' ) );
660 - register_deactivation_hook( $this->client->file, array( $this, 'clear_scheduler' ) );
661 - break;
662 -
663 - case 'theme':
664 - add_action( 'after_switch_theme', array( $this, 'schedule_cron_event' ) );
665 - add_action( 'switch_theme', array( $this, 'clear_scheduler' ) );
666 - break;
667 - }
668 - }
669 -
670 - /**
671 - * Form action URL
672 - */
673 - private function formActionUrl() {
674 - echo add_query_arg(
675 - array( 'page' => $_GET['page'] ),
676 - admin_url( basename( $_SERVER['SCRIPT_NAME'] ) )
677 - );
678 - }
679 -
680 - /**
681 - * Get input license key
682 - * @param $action
683 - * @return $license
684 - */
685 - private function get_input_license_value( $action, $license ) {
686 - if ( 'active' == $action ) {
687 - return isset( $license['key'] ) ? $license['key'] : '';
688 - }
689 -
690 - if ( 'deactive' == $action ) {
691 - $key_length = strlen( $license['key'] );
692 -
693 - return str_pad(
694 - substr( $license['key'], 0, $key_length / 2 ), $key_length, '*'
695 - );
696 - }
697 -
698 - return '';
699 - }
700 -
701 -}
1 +<?php
2 +namespace Appsero;
3 +
4 +/**
5 + * Appsero License Checker
6 + *
7 + * This class will check, active and deactive license
8 + */
9 +class License {
10 +
11 + /**
12 + * AppSero\Client
13 + *
14 + * @var object
15 + */
16 + protected $client;
17 +
18 + /**
19 + * Arguments of create menu
20 + *
21 + * @var array
22 + */
23 + protected $menu_args;
24 +
25 + /**
26 + * `option_name` of `wp_options` table
27 + *
28 + * @var string
29 + */
30 + protected $option_key;
31 +
32 + /**
33 + * Error message of HTTP request
34 + *
35 + * @var string
36 + */
37 + public $error;
38 +
39 + /**
40 + * Success message on form submit
41 + *
42 + * @var string
43 + */
44 + public $success;
45 +
46 + /**
47 + * Corn schedule hook name
48 + *
49 + * @var string
50 + */
51 + protected $schedule_hook;
52 +
53 + /**
54 + * Set value for valid licnese
55 + *
56 + * @var boolean
57 + */
58 + private $is_valid_licnese = null;
59 +
60 + /**
61 + * Initialize the class
62 + *
63 + * @param Appsero\Client
64 + */
65 + public function __construct( Client $client ) {
66 + $this->client = $client;
67 +
68 + $this->option_key = 'appsero_' . md5( $this->client->slug ) . '_manage_license';
69 +
70 + $this->schedule_hook = $this->client->slug . '_license_check_event';
71 +
72 + // Run hook to check license status daily
73 + add_action( $this->schedule_hook, array( $this, 'check_license_status' ) );
74 +
75 + // Active/Deactive corn schedule
76 + $this->run_schedule();
77 + }
78 +
79 + /**
80 + * Check license
81 + *
82 + * @return boolean
83 + */
84 + public function check( $license_key ) {
85 + $route = 'public/license/' . $this->client->hash . '/check';
86 +
87 + return $this->send_request( $license_key, $route );
88 + }
89 +
90 + /**
91 + * Active a license
92 + *
93 + * @return boolean
94 + */
95 + public function activate( $license_key ) {
96 + $route = 'public/license/' . $this->client->hash . '/activate';
97 +
98 + return $this->send_request( $license_key, $route );
99 + }
100 +
101 + /**
102 + * Deactivate a license
103 + *
104 + * @return boolean
105 + */
106 + public function deactivate( $license_key ) {
107 + $route = 'public/license/' . $this->client->hash . '/deactivate';
108 +
109 + return $this->send_request( $license_key, $route );
110 + }
111 +
112 + /**
113 + * Send common request
114 + *
115 + * @param $license_key
116 + * @param $route
117 + *
118 + * @return array
119 + */
120 + protected function send_request( $license_key, $route ) {
121 + $params = array(
122 + 'license_key' => $license_key,
123 + 'url' => esc_url( home_url() ),
124 + );
125 +
126 + $response = $this->client->send_request( $params, $route, true );
127 +
128 + if ( is_wp_error( $response ) ) {
129 + return array(
130 + 'success' => false,
131 + 'error' => $response->get_error_message()
132 + );
133 + }
134 +
135 + $response = json_decode( wp_remote_retrieve_body( $response ), true );
136 +
137 + if ( empty( $response ) || isset( $response['exception'] )) {
138 + return array(
139 + 'success' => false,
140 + 'error' => 'Unknown error occurred, Please try again.'
141 + );
142 + }
143 +
144 + if ( isset( $response['errors'] ) && isset( $response['errors']['license_key'] ) ) {
145 + $response = array(
146 + 'success' => false,
147 + 'error' => $response['errors']['license_key'][0]
148 + );
149 + }
150 +
151 + return $response;
152 + }
153 +
154 + /**
155 + * Add settings page for license
156 + *
157 + * @param array $args
158 + *
159 + * @return void
160 + */
161 + public function add_settings_page( $args = array() ) {
162 + $defaults = array(
163 + 'type' => 'menu', // Can be: menu, options, submenu
164 + 'page_title' => 'Manage License',
165 + 'menu_title' => 'Manage License',
166 + 'capability' => 'manage_options',
167 + 'menu_slug' => $this->client->slug . '-manage-license',
168 + 'icon_url' => '',
169 + 'position' => null,
170 + 'parent_slug' => '',
171 + );
172 +
173 + $this->menu_args = wp_parse_args( $args, $defaults );
174 +
175 + add_action( 'admin_menu', array( $this, 'admin_menu' ), 99 );
176 + }
177 +
178 + /**
179 + * Admin Menu hook
180 + *
181 + * @return void
182 + */
183 + public function admin_menu() {
184 + switch ( $this->menu_args['type'] ) {
185 + case 'menu':
186 + $this->add_menu_page();
187 + break;
188 +
189 + case 'submenu':
190 + $this->add_submenu_page();
191 + break;
192 +
193 + case 'options':
194 + $this->add_options_page();
195 + break;
196 + }
197 + }
198 +
199 + /**
200 + * License menu output
201 + */
202 + public function menu_output() {
203 +
204 + if ( isset( $_POST['submit'] ) ) {
205 + $this->license_form_submit( $_POST );
206 + }
207 +
208 + $license = get_option( $this->option_key, null );
209 + $action = ( $license && isset( $license['status'] ) && 'activate' == $license['status'] ) ? 'deactive' : 'active';
210 + $this->licenses_style();
211 + ?>
212 +
213 + <div class="wrap appsero-license-settings-wrapper">
214 + <h1>License Settings</h1>
215 +
216 + <?php
217 + $this->show_license_page_notices();
218 + do_action( 'before_appsero_license_section' );
219 + ?>
220 +
221 + <div class="appsero-license-settings appsero-license-section">
222 + <?php $this->show_license_page_card_header(); ?>
223 +
224 + <div class="appsero-license-details">
225 + <p>Active <strong><?php echo $this->client->name; ?></strong> by your license key to get professional support and automatic update from your WordPress dashboard.</p>
226 + <form method="post" action="<?php $this->formActionUrl(); ?>" novalidate="novalidate" spellcheck="false">
227 + <input type="hidden" name="_action" value="<?php echo $action; ?>">
228 + <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce( $this->client->name ); ?>">
229 + <div class="license-input-fields">
230 + <div class="license-input-key">
231 + <svg enable-background="new 0 0 512 512" version="1.1" viewBox="0 0 512 512" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
232 + <path d="m463.75 48.251c-64.336-64.336-169.01-64.335-233.35 1e-3 -43.945 43.945-59.209 108.71-40.181 167.46l-185.82 185.82c-2.813 2.813-4.395 6.621-4.395 10.606v84.858c0 8.291 6.709 15 15 15h84.858c3.984 0 7.793-1.582 10.605-4.395l21.211-21.226c3.237-3.237 4.819-7.778 4.292-12.334l-2.637-22.793 31.582-2.974c7.178-0.674 12.847-6.343 13.521-13.521l2.974-31.582 22.793 2.651c4.233 0.571 8.496-0.85 11.704-3.691 3.193-2.856 5.024-6.929 5.024-11.206v-27.929h27.422c3.984 0 7.793-1.582 10.605-4.395l38.467-37.958c58.74 19.043 122.38 4.929 166.33-39.046 64.336-64.335 64.336-169.01 0-233.35zm-42.435 106.07c-17.549 17.549-46.084 17.549-63.633 0s-17.549-46.084 0-63.633 46.084-17.549 63.633 0 17.548 46.084 0 63.633z"/>
233 + </svg>
234 + <input type="text" value="<?php echo $this->get_input_license_value( $action, $license ); ?>"
235 + placeholder="Enter your license key to activate" name="license_key"
236 + <?php echo ( 'deactive' == $action ) ? 'readonly="readonly"' : ''; ?>
237 + />
238 + </div>
239 + <button type="submit" name="submit" class="<?php echo 'deactive' == $action ? 'deactive-button' : ''; ?>">
240 + <?php echo $action == 'active' ? 'Activate License' : 'Deactivate License' ; ?>
241 + </button>
242 + </div>
243 + </form>
244 +
245 + <?php
246 + if ( 'deactive' == $action && isset( $license['remaining'] ) ) {
247 + $this->show_active_license_info( $license );
248 + }
249 + ?>
250 + </div>
251 + </div> <!-- /.appsero-license-settings -->
252 +
253 + <?php do_action( 'after_appsero_license_section' ); ?>
254 + </div>
255 + <?php
256 + }
257 +
258 + /**
259 + * License form submit
260 + */
261 + public function license_form_submit( $form ) {
262 + if ( ! isset( $form['_nonce'], $form['_action'] ) ) {
263 + $this->error = "Please add all information";
264 + return;
265 + }
266 +
267 + if ( ! wp_verify_nonce( $form['_nonce'], $this->client->name ) ) {
268 + $this->error = "You don't have permission to manage license.";
269 + return;
270 + }
271 +
272 + switch ( $form['_action'] ) {
273 + case 'active':
274 + $this->active_client_license( $form );
275 + break;
276 +
277 + case 'deactive':
278 + $this->deactive_client_license( $form );
279 + break;
280 + }
281 + }
282 +
283 + /**
284 + * Check license status on schedule
285 + */
286 + public function check_license_status() {
287 + $license = get_option( $this->option_key, null );
288 +
289 + if ( isset( $license['key'] ) && ! empty( $license['key'] ) ) {
290 + $response = $this->check( $license['key'] );
291 +
292 + if ( isset( $response['success'] ) && $response['success'] ) {
293 + $license['status'] = 'activate';
294 + $license['remaining'] = $response['remaining'];
295 + $license['activation_limit'] = $response['activation_limit'];
296 + $license['expiry_days'] = $response['expiry_days'];
297 + $license['title'] = $response['title'];
298 + $license['source_id'] = $response['source_identifier'];
299 + $license['recurring'] = $response['recurring'];
300 + } else {
301 + $license['status'] = 'deactivate';
302 + $license['expiry_days'] = 0;
303 + }
304 +
305 + update_option( $this->option_key, $license, false );
306 + }
307 + }
308 +
309 + /**
310 + * Check this is a valid license
311 + */
312 + public function is_valid() {
313 + if ( null !== $this->is_valid_licnese ) {
314 + return $this->is_valid_licnese;
315 + }
316 +
317 + $license = get_option( $this->option_key, null );
318 + if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
319 + $this->is_valid_licnese = true;
320 + } else {
321 + $this->is_valid_licnese = false;
322 + }
323 +
324 + return $this->is_valid_licnese;
325 + }
326 +
327 + /**
328 + * Check this is a valid license
329 + */
330 + public function is_valid_by( $option, $value ) {
331 + $license = get_option( $this->option_key, null );
332 +
333 + if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
334 + if ( isset( $license[ $option ] ) && $license[ $option ] == $value ) {
335 + return true;
336 + }
337 + }
338 +
339 + return false;
340 + }
341 +
342 + /**
343 + * Styles for licenses page
344 + */
345 + private function licenses_style() {
346 + ?>
347 + <style type="text/css">
348 + .appsero-license-section {
349 + width: 100%;
350 + max-width: 1100px;
351 + min-height: 1px;
352 + box-sizing: border-box;
353 + }
354 + .appsero-license-settings {
355 + background-color: #fff;
356 + box-shadow: 0px 3px 10px rgba(16, 16, 16, 0.05);
357 + }
358 + .appsero-license-settings * {
359 + box-sizing: border-box;
360 + }
361 + .appsero-license-title {
362 + background-color: #F8FAFB;
363 + border-bottom: 2px solid #EAEAEA;
364 + display: flex;
365 + align-items: center;
366 + padding: 10px 20px;
367 + }
368 + .appsero-license-title svg {
369 + width: 30px;
370 + height: 30px;
371 + fill: #0082BF;
372 + }
373 + .appsero-license-title span {
374 + font-size: 17px;
375 + color: #444444;
376 + margin-left: 10px;
377 + }
378 + .appsero-license-details {
379 + padding: 20px;
380 + }
381 + .appsero-license-details p {
382 + font-size: 15px;
383 + margin: 0 0 20px 0;
384 + }
385 + .license-input-key {
386 + position: relative;
387 + flex: 0 0 72%;
388 + max-width: 72%;
389 + }
390 + .license-input-key input {
391 + background-color: #F9F9F9;
392 + padding: 10px 15px 10px 48px;
393 + border: 1px solid #E8E5E5;
394 + border-radius: 3px;
395 + height: 45px;
396 + font-size: 16px;
397 + color: #71777D;
398 + width: 100%;
399 + box-shadow: 0 0 0 transparent;
400 + }
401 + .license-input-key input:focus {
402 + outline: 0 none;
403 + border: 1px solid #E8E5E5;
404 + box-shadow: 0 0 0 transparent;
405 + }
406 + .license-input-key svg {
407 + width: 22px;
408 + height: 22px;
409 + fill: #0082BF;
410 + position: absolute;
411 + left: 14px;
412 + top: 13px;
413 + }
414 + .license-input-fields {
415 + display: flex;
416 + justify-content: space-between;
417 + margin-bottom: 30px;
418 + max-width: 850px;
419 + width: 100%;
420 + }
421 + .license-input-fields button {
422 + color: #fff;
423 + font-size: 17px;
424 + padding: 8px;
425 + height: 46px;
426 + background-color: #0082BF;
427 + border-radius: 3px;
428 + cursor: pointer;
429 + flex: 0 0 25%;
430 + max-width: 25%;
431 + border: 1px solid #0082BF;
432 + }
433 + .license-input-fields button.deactive-button {
434 + background-color: #E40055;
435 + border-color: #E40055;
436 + }
437 + .license-input-fields button:focus {
438 + outline: 0 none;
439 + }
440 + .active-license-info {
441 + display: flex;
442 + }
443 + .single-license-info {
444 + min-width: 220px;
445 + flex: 0 0 30%;
446 + }
447 + .single-license-info h3 {
448 + font-size: 18px;
449 + margin: 0 0 12px 0;
450 + }
451 + .single-license-info p {
452 + margin: 0;
453 + color: #00C000;
454 + }
455 + .single-license-info p.occupied {
456 + color: #E40055;
457 + }
458 + </style>
459 + <?php
460 + }
461 +
462 + /**
463 + * Show active license information
464 + */
465 + private function show_active_license_info( $license ) {
466 + ?>
467 + <div class="active-license-info">
468 + <div class="single-license-info">
469 + <h3>Activation Remaining</h3>
470 + <?php if ( empty( $license['activation_limit'] ) ): ?>
471 + <p>Unlimited</p>
472 + <?php else: ?>
473 + <p class="<?php echo $license['remaining'] ? '' : 'occupied'; ?>">
474 + <?php echo $license['remaining']; ?> out of <?php echo $license['activation_limit']; ?>
475 + </p>
476 + <?php endif; ?>
477 + </div>
478 + <div class="single-license-info">
479 + <h3>Expires in</h3>
480 + <?php
481 + if ( $license['recurring'] && false !== $license['expiry_days'] ) {
482 + $occupied = $license['expiry_days'] > 10 ? '' : 'occupied';
483 + echo '<p class="' . $occupied . '">' . $license['expiry_days'] . ' days</p>';
484 + } else {
485 + echo '<p>Never</p>';
486 + }
487 + ?>
488 + </div>
489 + </div>
490 + <?php
491 + }
492 +
493 + /**
494 + * Show license settings page notices
495 + */
496 + private function show_license_page_notices() {
497 + if ( ! empty( $this->error ) ) :
498 + ?>
499 + <div class="notice notice-error is-dismissible appsero-license-section">
500 + <p><?php echo $this->error; ?></p>
501 + </div>
502 + <?php
503 + endif;
504 + if ( ! empty( $this->success ) ) :
505 + ?>
506 + <div class="notice notice-success is-dismissible appsero-license-section">
507 + <p><?php echo $this->success; ?></p>
508 + </div>
509 + <?php
510 + endif;
511 + echo '<br />';
512 + }
513 +
514 + /**
515 + * Card header
516 + */
517 + private function show_license_page_card_header() {
518 + ?>
519 + <div class="appsero-license-title">
520 + <svg enable-background="new 0 0 299.995 299.995" version="1.1" viewBox="0 0 300 300" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
521 + <path d="m150 161.48c-8.613 0-15.598 6.982-15.598 15.598 0 5.776 3.149 10.807 7.817 13.505v17.341h15.562v-17.341c4.668-2.697 7.817-7.729 7.817-13.505 0-8.616-6.984-15.598-15.598-15.598z"/>
522 + <path d="m150 85.849c-13.111 0-23.775 10.665-23.775 23.775v25.319h47.548v-25.319c-1e-3 -13.108-10.665-23.775-23.773-23.775z"/>
523 + <path d="m150 1e-3c-82.839 0-150 67.158-150 150 0 82.837 67.156 150 150 150s150-67.161 150-150c0-82.839-67.161-150-150-150zm46.09 227.12h-92.173c-9.734 0-17.626-7.892-17.626-17.629v-56.919c0-8.491 6.007-15.582 14.003-17.25v-25.697c0-27.409 22.3-49.711 49.711-49.711 27.409 0 49.709 22.3 49.709 49.711v25.697c7.993 1.673 14 8.759 14 17.25v56.919h2e-3c0 9.736-7.892 17.629-17.626 17.629z"/>
524 + </svg>
525 + <span>Activate License</span>
526 + </div>
527 + <?php
528 + }
529 +
530 + /**
531 + * Active client license
532 + */
533 + private function active_client_license( $form ) {
534 + if ( empty( $form['license_key'] ) ) {
535 + $this->error = 'The license key field is required.';
536 + return;
537 + }
538 +
539 + $license_key = sanitize_text_field( $form['license_key'] );
540 + $response = $this->activate( $license_key );
541 +
542 + if ( ! $response['success'] ) {
543 + $this->error = $response['error'] ? $response['error'] : 'Unknown error occurred.';
544 + return;
545 + }
546 +
547 + $data = array(
548 + 'key' => $license_key,
549 + 'status' => 'activate',
550 + 'remaining' => $response['remaining'],
551 + 'activation_limit' => $response['activation_limit'],
552 + 'expiry_days' => $response['expiry_days'],
553 + 'title' => $response['title'],
554 + 'source_id' => $response['source_identifier'],
555 + 'recurring' => $response['recurring'],
556 + );
557 +
558 + update_option( $this->option_key, $data, false );
559 +
560 + $this->success = 'License activated successfully.';
561 + }
562 +
563 + /**
564 + * Deactive client license
565 + */
566 + private function deactive_client_license( $form ) {
567 + $license = get_option( $this->option_key, null );
568 +
569 + if ( empty( $license['key'] ) ) {
570 + $this->error = 'License key not found.';
571 + return;
572 + }
573 +
574 + $response = $this->deactivate( $license['key'] );
575 +
576 + $data = array(
577 + 'key' => '',
578 + 'status' => 'deactivate',
579 + );
580 +
581 + update_option( $this->option_key, $data, false );
582 +
583 + if ( ! $response['success'] ) {
584 + $this->error = $response['error'] ? $response['error'] : 'Unknown error occurred.';
585 + return;
586 + }
587 +
588 + $this->success = 'License deactivated successfully.';
589 + }
590 +
591 + /**
592 + * Add license menu page
593 + */
594 + private function add_menu_page() {
595 + add_menu_page(
596 + $this->menu_args['page_title'],
597 + $this->menu_args['menu_title'],
598 + $this->menu_args['capability'],
599 + $this->menu_args['menu_slug'],
600 + array( $this, 'menu_output' ),
601 + $this->menu_args['icon_url'],
602 + $this->menu_args['position']
603 + );
604 + }
605 +
606 + /**
607 + * Add submenu page
608 + */
609 + private function add_submenu_page() {
610 + add_submenu_page(
611 + $this->menu_args['parent_slug'],
612 + $this->menu_args['page_title'],
613 + $this->menu_args['menu_title'],
614 + $this->menu_args['capability'],
615 + $this->menu_args['menu_slug'],
616 + array( $this, 'menu_output' ),
617 + $this->menu_args['position']
618 + );
619 + }
620 +
621 + /**
622 + * Add submenu page
623 + */
624 + private function add_options_page() {
625 + add_options_page(
626 + $this->menu_args['page_title'],
627 + $this->menu_args['menu_title'],
628 + $this->menu_args['capability'],
629 + $this->menu_args['menu_slug'],
630 + array( $this, 'menu_output' ),
631 + $this->menu_args['position']
632 + );
633 + }
634 +
635 + /**
636 + * Schedule daily sicense checker event
637 + */
638 + public function schedule_cron_event() {
639 + if ( ! wp_next_scheduled( $this->schedule_hook ) ) {
640 + wp_schedule_event( time(), 'daily', $this->schedule_hook );
641 +
642 + wp_schedule_single_event( time() + 20, $this->schedule_hook );
643 + }
644 + }
645 +
646 + /**
647 + * Clear any scheduled hook
648 + */
649 + public function clear_scheduler() {
650 + wp_clear_scheduled_hook( $this->schedule_hook );
651 + }
652 +
653 + /**
654 + * Enable/Disable schedule
655 + */
656 + private function run_schedule() {
657 + switch ( $this->client->type ) {
658 + case 'plugin':
659 + register_activation_hook( $this->client->file, array( $this, 'schedule_cron_event' ) );
660 + register_deactivation_hook( $this->client->file, array( $this, 'clear_scheduler' ) );
661 + break;
662 +
663 + case 'theme':
664 + add_action( 'after_switch_theme', array( $this, 'schedule_cron_event' ) );
665 + add_action( 'switch_theme', array( $this, 'clear_scheduler' ) );
666 + break;
667 + }
668 + }
669 +
670 + /**
671 + * Form action URL
672 + */
673 + private function formActionUrl() {
674 + echo add_query_arg(
675 + array( 'page' => $_GET['page'] ),
676 + admin_url( basename( $_SERVER['SCRIPT_NAME'] ) )
677 + );
678 + }
679 +
680 + /**
681 + * Get input license key
682 + * @param $action
683 + * @return $license
684 + */
685 + private function get_input_license_value( $action, $license ) {
686 + if ( 'active' == $action ) {
687 + return isset( $license['key'] ) ? $license['key'] : '';
688 + }
689 +
690 + if ( 'deactive' == $action ) {
691 + $key_length = strlen( $license['key'] );
692 +
693 + return str_pad(
694 + substr( $license['key'], 0, $key_length / 2 ), $key_length, '*'
695 + );
696 + }
697 +
698 + return '';
699 + }
700 +
701 +}