PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / trunk
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization vtrunk
4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 2.5.5 2.5.6 2.5.7 3.0.0 3.0.1 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.11.0 3.11.1 3.11.2 3.11.3 3.12.0 All 135 releases
← All changes | vendor/codeinwp/themeisle-sdk/src/Modules/Licenser.php +185 -57 3.11.3 → trunk View file →
@@ -137,13 +137,13 @@
137 137 public function license_view() {
138 138 $status = $this->get_license_status();
139 139 $value = $this->license_key;
140 140
141 - $activate_string = apply_filters( $this->product->get_key() . '_lc_activate_string', 'Activate' );
142 - $deactivate_string = apply_filters( $this->product->get_key() . '_lc_deactivate_string', 'Deactivate' );
143 - $valid_string = apply_filters( $this->product->get_key() . '_lc_valid_string', 'Valid' );
144 - $invalid_string = apply_filters( $this->product->get_key() . '_lc_invalid_string', 'Invalid' );
145 - $license_message = apply_filters( $this->product->get_key() . '_lc_license_message', 'Enter your license from %s purchase history in order to get %s updates' );
141 + $activate_string = apply_filters( $this->product->get_key() . '_lc_activate_string', Loader::$labels['licenser']['activate'] );
142 + $deactivate_string = apply_filters( $this->product->get_key() . '_lc_deactivate_string', Loader::$labels['licenser']['deactivate'] );
143 + $valid_string = apply_filters( $this->product->get_key() . '_lc_valid_string', Loader::$labels['licenser']['valid'] );
144 + $invalid_string = apply_filters( $this->product->get_key() . '_lc_invalid_string', Loader::$labels['licenser']['invalid'] );
145 + $license_message = apply_filters( $this->product->get_key() . '_lc_license_message', Loader::$labels['licenser']['notice'] );
146 146 $error_message = $this->get_error();
147 147 ?>
148 148 <style type="text/css">
149 149 input.themeisle-sdk-text-input-valid {
@@ -264,8 +264,25 @@
264 264 return isset( $license_data->license ) ? $license_data : false;
265 265 }
266 266
267 267 /**
268 + * Get license hash.
269 + *
270 + * @param string $key Product key.
271 + *
272 + * @return bool|string
273 + */
274 + public static function create_license_hash( $key ) {
275 + $data = self::get_license_data( $key );
276 +
277 + if ( ! $data ) {
278 + return false;
279 + }
280 +
281 + return isset( $data->key ) ? wp_hash( $data->key ) : false;
282 + }
283 +
284 + /**
268 285 * Check if license is valid.
269 286 *
270 287 * @param string $product_file Product basefile.
271 288 *
@@ -360,11 +377,11 @@
360 377 return false;
361 378 }
362 379
363 380 $status = $this->get_license_status( true );
364 - $no_activations_string = apply_filters( $this->product->get_key() . '_lc_no_activations_string', 'No more activations left for %s. You need to upgrade your plan in order to use %s on more websites. If you need assistance, please get in touch with %s staff.' );
365 - $no_valid_string = apply_filters( $this->product->get_key() . '_lc_no_valid_string', 'In order to benefit from updates and support for %s, please add your license code from your <a href="%s" target="_blank">purchase history</a> and validate it <a href="%s">here</a>. ' );
366 - $expired_license_string = apply_filters( $this->product->get_key() . '_lc_expired_string', 'Your %s\'s License Key has expired. In order to continue receiving support and software updates you must <a href="%s" target="_blank">renew</a> your license key.' );
381 + $no_activations_string = apply_filters( $this->product->get_key() . '_lc_no_activations_string', Loader::$labels['licenser']['no_activations'] );
382 + $no_valid_string = apply_filters( $this->product->get_key() . '_lc_no_valid_string', sprintf( Loader::$labels['licenser']['inactive'], '%s', '<a href="%s" target="_blank">', '</a>', '<a href="%s">', '</a>' ) );
383 + $expired_license_string = apply_filters( $this->product->get_key() . '_lc_expired_heading_string', Loader::$labels['licenser']['expired'] );
367 384 // No activations left for this license.
368 385 if ( 'valid' != $status && $this->check_activation() ) {
369 386 ?>
370 387 <div class="error">
@@ -385,14 +402,74 @@
385 402 }
386 403
387 404 // Invalid license key.
388 405 if ( 'active_expired' === $status ) {
406 + // Check if the notice was dismissed.
407 + $dismiss_option_key = $this->product->get_key() . '_expired_notice_dismissed';
408 + if ( get_option( $dismiss_option_key, false ) ) {
409 + return false;
410 + }
411 +
412 + $license_data = get_option( $this->product->get_key() . '_license_data', '' );
413 + $expiration_date = '';
414 + if ( is_object( $license_data ) && isset( $license_data->expires ) ) {
415 + $timestamp = strtotime( (string) $license_data->expires );
416 + if ( false !== $timestamp ) {
417 + $expiration_date = gmdate( 'F j, Y', $timestamp );
418 + }
419 + }
420 +
421 + $discount_config = apply_filters( $this->product->get_key() . '_lc_renew_discount', false );
422 +
423 + if ( is_array( $discount_config ) && isset( $discount_config['url'] ) && isset( $discount_config['renew_button'] ) ) {
424 + $renew_url = $discount_config['url'];
425 + $renew_button = $discount_config['renew_button'];
426 + } else {
427 + $renew_url = apply_filters( $this->product->get_key() . '_lc_renew_url', $this->renew_url() );
428 + $renew_button = apply_filters( $this->product->get_key() . '_lc_renew_button_string', Loader::$labels['licenser']['renew_license'] );
429 + }
430 +
431 + $learn_more_url = apply_filters( $this->product->get_key() . '_lc_learn_more_url', $this->get_api_url() );
432 + $learn_more_button = apply_filters( $this->product->get_key() . '_lc_learn_more_button_string', Loader::$labels['licenser']['learn_more'] );
433 + $notice_message = apply_filters( $this->product->get_key() . '_lc_expired_notice_message', Loader::$labels['licenser']['expired_notice'] );
434 +
435 + $expired_date_string = apply_filters( $this->product->get_key() . '_lc_expired_date_string', sprintf( Loader::$labels['licenser']['expired_date'], esc_html( $expiration_date ) ) );
436 + $heading = apply_filters( $this->product->get_key() . '_lc_expired_heading_string', sprintf( Loader::$labels['licenser']['expired'], $this->product->get_name() ) );
437 + $notice_id = $this->product->get_key() . '_expired_notice';
389 438 ?>
390 - <div class="error">
391 - <p>
392 - <strong><?php echo sprintf( wp_kses_data( $expired_license_string ), esc_attr( $this->product->get_name() . ' ' . $this->product->get_type() ), esc_url( $this->get_api_url() . '?license=' . $this->license_key ) ); ?> </strong>
439 + <div class="notice notice-warning notice-alt is-dismissible themeisle-sdk-license-notice" id="<?php echo esc_attr( $notice_id ); ?>" data-notice-id="<?php echo esc_attr( $notice_id ); ?>" style="position: relative; border-left: 4px solid #d63638; padding: 12px; background-color: #fff;">
440 + <p style="margin: 0.5em 0; font-size: 13px;">
441 + <strong><?php echo wp_kses_post( $heading ); ?></strong>
442 + · <?php echo esc_html( $expired_date_string ); ?>
393 443 </p>
444 + <p style="margin: 0.5em 0 1em 0; font-size: 13px;">
445 + <?php echo esc_html( $notice_message ); ?>
446 + </p>
447 + <p style="margin: 0.5em 0;">
448 + <a href="<?php echo esc_url( $renew_url ); ?>" class="button button-primary" target="_blank" rel="noopener noreferrer">
449 + <?php echo esc_html( $renew_button ); ?>
450 + </a>
451 + <a href="<?php echo esc_url( $learn_more_url ); ?>" class="button" target="_blank" rel="noopener noreferrer" style="border: none; background-color: transparent;">
452 + <?php echo esc_html( $learn_more_button ); ?>
453 + </a>
454 + </p>
394 455 </div>
456 + <script type="text/javascript">
457 + jQuery(document).ready(function($) {
458 + $('#<?php echo esc_js( $notice_id ); ?>').on('click', '.notice-dismiss', function(e) {
459 + const noticeId = '<?php echo esc_js( $notice_id ); ?>';
460 + $.ajax({
461 + url: ajaxurl,
462 + type: 'POST',
463 + data: {
464 + action: 'themeisle_sdk_dismiss_license_notice',
465 + notice_id: noticeId,
466 + nonce: '<?php echo esc_js( wp_create_nonce( 'themeisle_sdk_dismiss_license_notice' ) ); ?>'
467 + }
468 + });
469 + });
470 + });
471 + </script>
395 472 <?php
396 473
397 474 return false;
398 475 }
@@ -525,17 +602,17 @@
525 602 * @return bool|\WP_Error
526 603 */
527 604 public function do_license_process( $license, $action = 'toggle' ) {
528 605 if ( strlen( $license ) < 10 ) {
529 - return new \WP_Error( 'themeisle-license-invalid-format', 'Invalid license.' );
606 + return new \WP_Error( 'themeisle-license-invalid-format', Loader::$labels['licenser']['invalid_msg'] );
530 607 }
531 608 $status = $this->get_license_status();
532 609
533 610 if ( 'valid' === $status && 'activate' === $action ) {
534 - return new \WP_Error( 'themeisle-license-already-active', 'License is already active.' );
611 + return new \WP_Error( 'themeisle-license-already-active', Loader::$labels['licenser']['already_active'] );
535 612 }
536 613 if ( 'valid' !== $status && 'deactivate' === $action ) {
537 - return new \WP_Error( 'themeisle-license-already-deactivate', 'License not active.' );
614 + return new \WP_Error( 'themeisle-license-already-deactivate', Loader::$labels['licenser']['not_active'] );
538 615 }
539 616
540 617 if ( 'toggle' === $action ) {
541 618 $action = ( 'valid' !== $status ? ( 'activate' ) : ( 'deactivate' ) );
@@ -561,15 +638,15 @@
561 638 }
562 639
563 640 // make sure the response came back okay.
564 641 if ( is_wp_error( $response ) ) {
565 - return new \WP_Error( 'themeisle-license-500', sprintf( 'ERROR: Failed to connect to the license service. Please try again later. Reason: %s', $response->get_error_message() ) );
642 + return new \WP_Error( 'themeisle-license-500', sprintf( Loader::$labels['licenser']['error_notice'], $response->get_error_message() ) );
566 643 }
567 644
568 645 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
569 646
570 647 if ( ! is_object( $license_data ) ) {
571 - return new \WP_Error( 'themeisle-license-404', 'ERROR: Failed to validate license. Please try again in one minute.' );
648 + return new \WP_Error( 'themeisle-license-404', Loader::$labels['licenser']['error_notice2'] );
572 649 }
573 650 if ( 'check' === $action ) {
574 651 return $license_data;
575 652 }
@@ -600,9 +677,9 @@
600 677 }
601 678 update_option( $this->product->get_key() . '_license_data', $license_data );
602 679 set_transient( $this->product->get_key() . '_license_data', $license_data, 12 * HOUR_IN_SECONDS );
603 680 if ( 'activate' === $action && 'valid' !== $license_data->license ) {
604 - return new \WP_Error( 'themeisle-license-invalid', 'ERROR: Invalid license provided.' );
681 + return new \WP_Error( 'themeisle-license-invalid', Loader::$labels['licenser']['error_invalid'] );
605 682 }
606 683
607 684 // Remove the versions transient upon activation so that newer version for rollback can be acquired.
608 685 $versions_cache = $this->product->get_cache_key();
@@ -635,9 +712,9 @@
635 712 if ( ! isset( $_POST[ $this->product->get_key() . '_btn_trigger' ] ) ) {
636 713 return;
637 714 }
638 715 if ( ! isset( $_POST[ $this->product->get_key() . 'nonce_field' ] )
639 - || ! wp_verify_nonce( $_POST[ $this->product->get_key() . 'nonce_field' ], $this->product->get_key() . 'nonce' ) //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
716 + || ! wp_verify_nonce( $_POST[ $this->product->get_key() . 'nonce_field' ], $this->product->get_key() . 'nonce' ) //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
640 717 ) {
641 718 return;
642 719 }
643 720 if ( ! current_user_can( 'manage_options' ) ) {
@@ -685,20 +762,18 @@
685 762 if ( false === $api_response || ! isset( $api_response->new_version ) ) {
686 763 return;
687 764 }
688 765 $update_url = wp_nonce_url( 'update.php?action=upgrade-theme&amp;theme=' . urlencode( $this->product->get_slug() ), 'upgrade-theme_' . $this->product->get_slug() );
689 - $update_message = apply_filters( 'themeisle_sdk_license_update_message', 'Updating this theme will lose any customizations you have made. Cancel to stop, OK to update.' );
766 + $update_message = apply_filters( 'themeisle_sdk_license_update_message', Loader::$labels['licenser']['update_license'] );
690 767 $update_onclick = ' onclick="if ( confirm(\'' . esc_js( $update_message ) . '\') ) {return true;}return false;"';
691 768 if ( version_compare( $this->product->get_version(), $api_response->new_version, '<' ) ) {
692 769 echo '<div id="update-nag">';
693 770 printf(
694 - '<strong>%1$s %2$s</strong> is available. <a href="%3$s" class="thickbox" title="%4s">Check out what\'s new</a> or <a href="%5$s"%6$s>update now</a>.',
695 - esc_attr( $theme->get( 'Name' ) ),
696 - esc_attr( $api_response->new_version ),
697 - esc_url( sprintf( '%s&TB_iframe=true&amp;width=1024&amp;height=800', $this->product->get_changelog() ) ),
698 - esc_attr( $theme->get( 'Name' ) ),
699 - esc_url( $update_url ),
700 - $update_onclick // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Already escaped.
771 + esc_html( Loader::$labels['licenser']['notice_update'] ),
772 + '<strong>' . esc_attr( $theme->get( 'Name' ) ) . ' ' . esc_attr( $api_response->new_version ) . '</strong>',
773 + '<a href="' . esc_url( sprintf( '%s&TB_iframe=true&amp;width=1024&amp;height=800', $this->product->get_changelog() ) ) . '" class="thickbox" title="' . esc_attr( $theme->get( 'Name' ) ) . '">',
774 + '</a>',
775 + '<a href="' . esc_url( $update_url ) . '" ' . $update_onclick . '>' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Already escaped.
701 776 );
702 777 echo '</div>';
703 778 echo '<div id="' . esc_attr( $this->product->get_slug() ) . '_changelog" style="display:none;">';
704 779 echo wp_kses_data( wpautop( $api_response->sections['changelog'] ) );
@@ -727,8 +802,9 @@
727 802 return $value;
728 803 }
729 804
730 805 $value->response[ $this->product->get_slug() ] = $update_data;
806 +
731 807 return $value;
732 808 }
733 809
734 810 /**
@@ -827,17 +903,21 @@
827 903 $this->do_check = true;
828 904
829 905 return $_transient_data;
830 906 }
907 + $this->product->setup_from_fileheaders();
831 908 $api_response = $this->api_request();
832 909 if ( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
910 + $plugin = $this->product->get_slug() . '/' . $this->product->get_file();
833 911 if ( ! isset( $api_response->plugin ) ) {
834 - $api_response->plugin = $this->product->get_slug() . '/' . $this->product->get_file();
912 + $api_response->plugin = $plugin;
835 913 }
836 914 if ( version_compare( $this->product->get_version(), $api_response->new_version, '<' ) ) {
837 - $_transient_data->response[ $this->product->get_slug() . '/' . $this->product->get_file() ] = $api_response;
915 + $_transient_data->response[ $plugin ] = $api_response;
916 + unset( $_transient_data->no_update[ $plugin ] );
838 917 } else {
839 - $_transient_data->no_update[ $this->product->get_slug() . '/' . $this->product->get_file() ] = $api_response;
918 + $_transient_data->no_update[ $plugin ] = $api_response;
919 + unset( $_transient_data->response[ $plugin ] );
840 920 }
841 921 }
842 922
843 923 return $_transient_data;
@@ -909,9 +989,9 @@
909 989 * @return bool Should we load the module?
910 990 */
911 991 public function can_load( $product ) {
912 992
913 - if ( $product->is_wordpress_available() ) {
993 + if ( ! $product->requires_license() ) {
914 994 return false;
915 995 }
916 996
917 997 return ( apply_filters( $product->get_key() . '_enable_licenser', true ) === true );
@@ -958,41 +1038,61 @@
958 1038 }
959 1039
960 1040 add_action( 'admin_head', [ $this, 'auto_activate' ] );
961 1041 if ( $this->product->is_plugin() ) {
962 - add_filter(
963 - 'pre_set_site_transient_update_plugins',
964 - [
965 - $this,
966 - 'pre_set_site_transient_update_plugins_filter',
967 - ]
968 - );
969 - add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
970 - add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 ); //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args
971 - if ( ! self::is_valid( $product->get_basefile() ) ) {
1042 + if ( ! $product->is_wordpress_available() ) {
972 1043 add_filter(
973 - 'plugin_action_links_' . plugin_basename( $product->get_basefile() ),
974 - function ( $actions ) {
975 - if ( $this->get_license_status( true ) !== self::STATUS_ACTIVE_EXPIRED ) {
976 - return $actions;
1044 + 'pre_set_site_transient_update_plugins',
1045 + [
1046 + $this,
1047 + 'pre_set_site_transient_update_plugins_filter',
1048 + ]
1049 + );
1050 + add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
1051 + add_filter( //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args
1052 + 'http_request_args',
1053 + array(
1054 + $this,
1055 + 'http_request_args',
1056 + ),
1057 + 10,
1058 + 2
1059 + );
1060 + if ( ! self::is_valid( $product->get_basefile() ) ) {
1061 + add_filter(
1062 + 'plugin_action_links_' . plugin_basename( $product->get_basefile() ),
1063 + function ( $actions ) {
1064 + if ( $this->get_license_status( true ) !== self::STATUS_ACTIVE_EXPIRED ) {
1065 + return $actions;
1066 + }
1067 + $new_actions['deactivate'] = $actions['deactivate'];
1068 + $new_actions['renew_link'] = '<a style="color:#d63638" href="' . esc_url( $this->renew_url() ) . '" target="_blank" rel="external noopener noreferrer">' . esc_html( Loader::$labels['licenser']['renew_cta'] ) . '</a>';
1069 +
1070 + return $new_actions;
977 1071 }
978 - $new_actions['deactivate'] = $actions['deactivate'];
979 - $new_actions['renew_link'] = '<a style="color:#d63638" href="' . esc_url( $this->renew_url() ) . '" target="_blank" rel="external noopener noreferrer">Renew license to update</a>';
980 -
981 - return $new_actions;
982 - }
983 - );
1072 + );
1073 + }
984 1074 }
985 1075
986 1076 return $this;
987 1077 }
988 1078 if ( $this->product->is_theme() ) {
989 - add_filter( 'site_transient_update_themes', array( &$this, 'theme_update_transient' ) );
990 - add_action( 'delete_site_transient_update_themes', array( &$this, 'delete_theme_update_transient' ) );
991 - add_action( 'load-update-core.php', array( &$this, 'delete_theme_update_transient' ) );
992 - add_action( 'load-themes.php', array( &$this, 'delete_theme_update_transient' ) );
993 - add_action( 'load-themes.php', array( &$this, 'load_themes_screen' ) );
994 - add_filter( 'http_request_args', array( $this, 'disable_wporg_update' ), 5, 2 ); //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args
1079 + if ( ! $product->is_wordpress_available() ) {
1080 + add_filter( 'site_transient_update_themes', array( &$this, 'theme_update_transient' ) );
1081 + add_action( 'delete_site_transient_update_themes', array( &$this, 'delete_theme_update_transient' ) );
1082 + add_action( 'load-update-core.php', array( &$this, 'delete_theme_update_transient' ) );
1083 + add_action( 'load-themes.php', array( &$this, 'delete_theme_update_transient' ) );
1084 + add_action( 'load-themes.php', array( &$this, 'load_themes_screen' ) );
1085 + add_filter( //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args
1086 + 'http_request_args',
1087 + array(
1088 + $this,
1089 + 'disable_wporg_update',
1090 + ),
1091 + 5,
1092 + 2
1093 + );
1094 + }
995 1095
996 1096 return $this;
997 1097
998 1098 }
@@ -1008,11 +1108,37 @@
1008 1108 add_action( 'admin_init', array( $this, 'process_license' ) );
1009 1109 add_action( 'admin_init', array( $this, 'product_valid' ), 99999999 );
1010 1110 add_action( 'admin_notices', array( $this, 'show_notice' ) );
1011 1111 add_filter( $this->product->get_key() . '_license_status', array( $this, 'get_license_status' ) );
1112 + add_action( 'wp_ajax_themeisle_sdk_dismiss_license_notice', array( $this, 'dismiss_license_notice' ) );
1012 1113 }
1013 1114
1014 1115 /**
1116 + * Handle AJAX request to dismiss the license notice.
1117 + */
1118 + public function dismiss_license_notice() {
1119 + if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( $_POST['nonce'] ), 'themeisle_sdk_dismiss_license_notice' ) ) {
1120 + wp_send_json_error( 'Invalid nonce' );
1121 + }
1122 +
1123 + if ( ! current_user_can( 'manage_options' ) ) {
1124 + wp_send_json_error( 'Insufficient permissions' );
1125 + }
1126 +
1127 + $notice_id = isset( $_POST['notice_id'] ) ? sanitize_text_field( $_POST['notice_id'] ) : '';
1128 +
1129 + if ( empty( $notice_id ) ) {
1130 + wp_send_json_error( 'Missing notice ID' );
1131 + }
1132 +
1133 + // Save the dismissal option.
1134 + $dismiss_option_key = $notice_id . '_dismissed';
1135 + update_option( $dismiss_option_key, true );
1136 +
1137 + wp_send_json_success();
1138 + }
1139 +
1140 + /**
1015 1141 * Check license on filesystem.
1016 1142 *
1017 1143 * @return mixed License key.
1018 1144 */
@@ -1033,10 +1159,12 @@
1033 1159 }
1034 1160 if ( ! isset( $content->key ) ) {
1035 1161 return false;
1036 1162 }
1163 +
1037 1164 return $content->key;
1038 1165 }
1166 +
1039 1167 /**
1040 1168 * Run license activation on plugin activate.
1041 1169 */
1042 1170 public function auto_activate() {
@@ -1084,9 +1212,9 @@
1084 1212 */
1085 1213 public function autoactivate_notice() {
1086 1214 ?>
1087 1215 <div class="notice notice-success is-dismissible">
1088 - <p><?php echo sprintf( '<strong>%s</strong> has been successfully activated using <strong>%s</strong> license !', esc_attr( $this->product->get_name() ), esc_attr( str_repeat( '*', 20 ) . substr( $this->license_local, - 10 ) ) ); ?></p>
1216 + <p><?php echo sprintf( esc_html( Loader::$labels['licenser']['autoactivate_notice'] ), '<strong>' . esc_attr( $this->product->get_name() ) . '</strong>', '<strong>' . esc_attr( str_repeat( '*', 20 ) . substr( $this->license_local, - 10 ) ) . '</strong>' ); ?></p>
1089 1217 </div>
1090 1218 <?php
1091 1219 }
1092 1220