文件操作 - license.php
返回文件管理
返回主菜单
删除本文件
文件: /storage/v12552/stanleysteamer/public_html/wp-content/themes/bricks/includes/license.php
编辑文件内容
<?php namespace Bricks; if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly class License { public static $license_key = ''; public static $license_status = ''; public static $remote_base_url = 'https://my.bricksbuilder.io/api/commerce/'; public function __construct() { self::$license_key = get_option( 'bricks_license_key', false ); add_filter( 'pre_set_site_transient_update_themes', [ $this, 'check_for_update' ] ); add_action( 'wp_ajax_bricks_activate_license', [ $this, 'activate_license' ] ); add_action( 'wp_ajax_bricks_deactivate_license', [ $this, 'deactivate_license' ] ); add_action( 'wp_ajax_bricks_revalidate_license', [ $this, 'revalidate_license' ] ); add_action( 'admin_notices', [ $this, 'admin_notices_license_activation' ] ); add_action( 'admin_notices', [ $this, 'admin_notices_license_mismatch' ] ); } /** * Check remotely if newer version of Bricks is available * * @param string $transient Transient for WordPress theme updates. */ public static function check_for_update( $transient ) { // 'checked' is an array with all installed themes and their version numbers if ( empty( $transient->checked ) ) { return $transient; } $license_key = self::$license_key; if ( ! $license_key ) { return $transient; } // Installed theme data $theme_data = wp_get_theme(); $installed_version = $theme_data->Version; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase // Check if Bricks is parent theme (i.e. Bricks child theme in use) if ( wp_get_theme()->parent() ) { $installed_version = wp_get_theme()->parent()->get( 'Version' ); } // Build theme update request URL with license_key and domain parameters $update_url = add_query_arg( [ 'license_key' => $license_key, 'domain' => get_site_url(), 'time' => time(), // To avoid caching remote response 'installed_version' => $installed_version, ], self::$remote_base_url . 'download/get_update_data' ); $request = Helpers::remote_get( $update_url ); // Check if remote GET request has been successful (better than using is_wp_error) if ( wp_remote_retrieve_response_code( $request ) !== 200 ) { return $transient; } $request = json_decode( wp_remote_retrieve_body( $request ), true ); // Check remotely if newer version of Bricks is available $latest_version = isset( $request['new_version'] ) ? $request['new_version'] : $installed_version; $newer_version_available = version_compare( $latest_version, $installed_version, '>' ); if ( $newer_version_available ) { // Save Bricks-specific update data in transient $transient->response['bricks'] = $request; } return $transient; } /** * Check if a license API response indicates the remote server is temporarily unavailable. * * @param array|\WP_Error $response Remote response object. * @param int $response_code Remote response status code. * @param mixed $response_body Decoded remote response body. * * @return bool */ private static function remote_response_is_unavailable( $response, $response_code, $response_body ) { if ( is_wp_error( $response ) ) { return true; } if ( in_array( $response_code, [ 408, 429 ], true ) || $response_code >= 500 ) { return true; } return $response_code === 200 && $response_body === null; } /** * Check if the current request may preserve a locally stored license during a temporary remote outage. * * @param string $license_key License key being validated. * * @return bool */ private static function can_preserve_license_on_remote_error( $license_key ) { if ( ! self::$license_key ) { return false; } return hash_equals( (string) self::$license_key, (string) $license_key ); } /** * Check license status when loading builder * * @see template_redirect */ public static function license_is_valid() { // Skip license check for builder iframe (check happens in builder panel) if ( bricks_is_builder_iframe() ) { return true; } // Return: No license key found in db options table if ( ! self::$license_key ) { return false; } // Valid license status' return in_array( self::get_license_status(), [ 'active', // Active license 'processed', // Order processed 'canceled', // Subscription cancelled, but not 'refunded' (@since 2.0) 'past_due', // Payment past due (subscription) 'error_remote', // Remote server error (bricksbuilder.io) ], true ); } /** * Get license status (stored locally in transient: bricks_license_status) * * If transient has expired (after 168h, or after 48h for temporary remote errors) then get it remotely from Bricks server. * * @return array */ public static function get_license_status() { $license_key = self::$license_key; if ( ! $license_key ) { return false; } // Check license transient (temporary remote errors expire after 48 hours, all other statuses after 168 hours) $transient_timeout = get_option( '_transient_timeout_bricks_license_status' ); $transient_timeout_in_hours = ( intval( $transient_timeout ) - time() ) / 60 / 60; $license_status = get_transient( 'bricks_license_status' ); // No valid transient found: Get license status remotely if ( ! $transient_timeout || $transient_timeout_in_hours > 168 || false === $license_status ) { delete_transient( 'bricks_license_status' ); $url = add_query_arg( [ 'license_key' => $license_key, 'site' => get_site_url(), 'version' => BRICKS_VERSION, 'time' => time(), // Avoid getting a cached remote response ], self::$remote_base_url . 'license/get_status' ); $response = Helpers::remote_get( $url ); $response_code = is_wp_error( $response ) ? 0 : wp_remote_retrieve_response_code( $response ); // Get status from remote response body $response_body = is_wp_error( $response ) ? null : json_decode( wp_remote_retrieve_body( $response ), true ); if ( is_array( $response_body ) && isset( $response_body['status'] ) ) { $license_status = $response_body['status']; } // Treat unavailable license server responses as a temporary remote error. if ( ! $license_status && self::remote_response_is_unavailable( $response, $response_code, $response_body ) ) { $license_status = 'error_remote'; } // Save license status in transient. self::set_license_status( $license_status ); } // Invalid license: Activate license on server (avoid having to deactivate & reactivate license for cloned sites, etc.) $invalid_license = ! in_array( $license_status, [ 'active', // Active license 'processed', // Order processed 'past_due', // Payment past due (subscription) 'error_remote', // Remote server error (bricksbuilder.io) ], true ); if ( $invalid_license ) { $license_status = self::activate_license(); return $license_status; } return $license_status; } /** * Save license status in transient. * * Temporary remote errors expire after 48 hours. All other statuses expire after 168 hours. */ public static function set_license_status( $license_status ) { $expiration_time = $license_status === 'error_remote' ? 48 * HOUR_IN_SECONDS : 168 * HOUR_IN_SECONDS; set_transient( 'bricks_license_status', $license_status, $expiration_time ); } /** * Activate license under "Bricks > License" (AJAX call on "Activate license" click) * * Also runs via PHP in 'get_license_status' to avoid having to deactivate & reactivate license (when cloning staging site, etc.) * * @return array */ public static function activate_license() { $license_key = self::$license_key; $is_ajax = bricks_is_ajax_call(); if ( $is_ajax ) { Ajax::verify_nonce( 'bricks-nonce-admin' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'verify_request: Sorry, you are not allowed to perform this action.' ); } if ( ! empty( $_POST['licenseKey'] ) ) { $license_key = sanitize_text_field( $_POST['licenseKey'] ); } } // Remove all HTML tags from license key $license_key = $license_key ? trim( $license_key ) : ''; $license_key = $license_key ? html_entity_decode( $license_key ) : ''; $license_key = $license_key ? wp_strip_all_tags( $license_key ) : ''; // Return: No license key found/submitted if ( ! $license_key ) { if ( $is_ajax ) { wp_send_json_error( [ 'message' => esc_html__( 'Invalid license key.', 'bricks' ) ] ); } else { return; } } // Send HTTP request to activate license $response = Helpers::remote_post( self::$remote_base_url . 'license/activate_license', [ 'sslverify' => false, 'timeout' => 30, 'body' => [ 'license_key' => $license_key, 'site' => get_site_url(), 'version' => BRICKS_VERSION, ], ] ); $response_code = is_wp_error( $response ) ? 0 : wp_remote_retrieve_response_code( $response ); $response_body = is_wp_error( $response ) ? null : json_decode( wp_remote_retrieve_body( $response ), true ); // Keep the saved license usable if the license server is temporarily unavailable. if ( self::remote_response_is_unavailable( $response, $response_code, $response_body ) ) { if ( self::can_preserve_license_on_remote_error( $license_key ) ) { self::set_license_status( 'error_remote' ); if ( $is_ajax ) { wp_send_json_success( [ 'message' => esc_html__( 'The license server temporarily unavailable. Your saved license is used locally and validation will occur within 48 hours. You can also re-validate the license manually.', 'bricks' ), 'status' => 'error_remote', ] ); } else { return 'error_remote'; } } if ( $is_ajax ) { wp_send_json_error( [ 'message' => esc_html__( 'License server temporarily unavailable. Please try activating your license again later.', 'bricks' ), ] ); } else { return; } } $license_status = false; if ( $response_code !== 200 ) { // Handle CloudFlare 403 "Forbidden" response if ( $response_code === 403 ) { $license_status = 'active'; } // Handle Imunify360 415 "Unsupported Media Type" response (@since 2.0.2) elseif ( $response_code === 415 ) { $license_status = 'active'; } // Return error elseif ( $is_ajax ) { wp_send_json_error( [ 'code' => $response_code, 'message' => wp_remote_retrieve_response_message( $response ), 'response' => $response, ] ); } else { return; } } if ( is_array( $response_body ) && isset( $response_body['status'] ) ) { $license_status = $response_body['status']; } // Return remote error if ( is_array( $response_body ) && isset( $response_body['type'] ) && $response_body['type'] === 'error' && isset( $response_body['message'] ) ) { if ( $is_ajax ) { wp_send_json_error( [ 'message' => wp_kses_post( $response_body['message'] ), 'response' => $response_body, 'code' => $response_code, ] ); } else { return; } } // Return if no license status was sent back if ( ! $license_status ) { if ( $is_ajax ) { wp_send_json_error( [ 'message' => esc_html__( 'No license for provided license key found.', 'bricks' ), 'response' => $response_body, 'code' => $response_code, ] ); } else { return; } } // Save license key in db options table update_option( 'bricks_license_key', $license_key ); // Save license status in transient. self::set_license_status( $license_status ); if ( $is_ajax ) { wp_send_json_success( [ 'message' => esc_html__( 'License activated.', 'bricks' ), 'status' => $license_status, ] ); } else { return $license_status; } } /** * Deactivate license * * @return void * * @since 1.0 */ public static function deactivate_license() { Ajax::verify_nonce( 'bricks-nonce-admin' ); // Only a user with full access can deactivate the license (@since 1.5.4) if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'verify_request: Sorry, you are not allowed to perform this action.' ); } // Deactivate license $response = Helpers::remote_post( self::$remote_base_url . 'license/deactivate_license', [ 'sslverify' => false, 'timeout' => 30, 'body' => [ 'license_key' => self::$license_key, 'site' => get_site_url(), 'version' => BRICKS_VERSION, ], ] ); delete_option( 'bricks_license_key' ); delete_transient( 'bricks_license_status' ); } /** * Re-validate license * * Clears the license status transient and re-validates the license without deactivating it. * * @since 2.1.3 * @return void */ public static function revalidate_license() { Ajax::verify_nonce( 'bricks-nonce-admin' ); // Only a user with full access can re-validate the license if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'verify_request: Sorry, you are not allowed to perform this action.' ); } // Return: No license key found if ( ! self::$license_key ) { wp_send_json_error( [ 'message' => esc_html__( 'No license key found.', 'bricks' ) ] ); } // Clear the license status transient to force re-validation delete_transient( 'bricks_license_status' ); // Re-validate the license using the existing activate_license logic $license_status = self::activate_license(); // If activate_license returns a status (non-AJAX call), send it as success if ( $license_status ) { wp_send_json_success( [ 'message' => esc_html__( 'License re-validated successfully.', 'bricks' ), 'status' => $license_status, ] ); } } /** * Admin notice to activate license * * @return null/string */ public static function admin_notices_license_activation() { // Show license key admin notice only to user roles which are allowed to use the builder if ( ! Capabilities::current_user_can_use_builder() ) { return; } // Don't show license admin notice on license page itself if ( get_current_screen()->id === 'bricks_page_bricks-license' ) { return; } // Check if license has been activated by checking for license key $license_key = self::$license_key; // Check: License activated (local) if ( isset( $license_key ) && ! empty( $license_key ) ) { return; } ?> <div class="notice notice-info notice-license-activation"> <div class="content-wrapper"> <h4 class="title"> <?php // translators: %s is the name of the theme. echo sprintf( esc_html__( 'Welcome to %s', 'bricks' ), 'Bricks' ); ?> </h4> <p><?php echo esc_html__( 'Activate your license to edit with Bricks, receive one-click updates, and access to all community templates.', 'bricks' ); ?></p> </div> <a class="button button-primary" href="<?php echo esc_url( BRICKS_ADMIN_PAGE_URL_LICENSE ); ?>"><?php esc_html_e( 'Activate license', 'bricks' ); ?></a> </div> <?php } /** * Admin notice to activate license * * @return null/string */ public static function admin_notices_license_mismatch() { // Show license key admin notice only to user roles which are allowed to use the builder if ( ! Capabilities::current_user_can_use_builder() ) { return; } // Don't show license admin notice on license page itself if ( get_current_screen()->id === 'bricks_page_bricks-license' ) { return; } // Check for license issue status. $license_status = get_transient( 'bricks_license_status' ); $license_notice_class = 'notice-error'; $license_error_title = false; $license_error_description = false; switch ( $license_status ) { case 'license_key_invalid': $license_error_title = esc_html__( 'Error: Invalid license key', 'bricks' ); $license_error_description = esc_html__( 'Your provided license key is invalid. Please deactivate and then reactivate your license.', 'bricks' ); break; case 'website_inactive': $license_error_title = esc_html__( 'Error: License mismatch', 'bricks' ); $license_error_description = esc_html__( 'Your website does not match your license key. Please deactivate and then reactivate your license.', 'bricks' ); break; case 'error_remote': $license_notice_class = 'notice-warning'; $license_error_title = esc_html__( 'License server unavailable', 'bricks' ); $license_error_description = esc_html__( 'The license server temporarily unavailable. Your saved license is used locally and validation will occur within 48 hours. You can also re-validate the license manually.', 'bricks' ); break; } if ( $license_error_title && $license_error_description ) { ?> <div class="notice <?php echo esc_attr( $license_notice_class ); ?> notice-license-mismatch"> <div class="content-wrapper"> <h4 class="title"><?php echo esc_html( $license_error_title ); ?></h4> <p><?php echo esc_html( $license_error_description ); ?></p> </div> </div> <?php } } }
修改文件时间
将文件时间修改为当前时间的前一年
删除文件