403Webshell
Server IP : 121.121.20.254  /  Your IP : 216.73.217.51
Web Server : Microsoft-IIS/10.0
System : Windows NT WEB-SERVER 10.0 build 20348 (Windows Server 2022) AMD64
User : IUSR ( 0)
PHP Version : 8.3.28
Disable Function : NONE
MySQL : ON  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  C:/inetpub/wwwroot/AIWEBSTATION/wp-content/plugins/novamira-pro/includes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : C:/inetpub/wwwroot/AIWEBSTATION/wp-content/plugins/novamira-pro/includes/licensing.php
<?php

// SPDX-FileCopyrightText: 2026 Ovation S.r.l. <dev@novamira.ai>
// SPDX-License-Identifier: AGPL-3.0-or-later

declare(strict_types=1);

namespace Novamira\Pro;

use stdClass;
use WP_Error;

if (!defined('ABSPATH')) {
    exit();
}

/**
 * @return array{
 *     plugin_base:string,
 *     plugin_slug:string,
 *     version:string,
 *     license_url:string,
 *     prefix:string,
 *     product_unique_id:string,
 *     pricing_url:string,
 *     license_page:string
 * }
 */
function license_config(): array
{
    return [
        'plugin_base' => (string) NOVAMIRA_PRO_PLUGIN_BASE,
        'plugin_slug' => NOVAMIRA_PRO_SLUG,
        'version' => NOVAMIRA_PRO_VERSION,
        'license_url' => NOVAMIRA_PRO_LICENSE_URL,
        'prefix' => NOVAMIRA_PRO_PREFIX,
        'product_unique_id' => NOVAMIRA_PRO_PRODUCT_UNIQUE_ID,
        'pricing_url' => NOVAMIRA_PRO_PRICING_URL,
        'license_page' => 'novamira-pro-license',
    ];
}

function license_config_value(string $key): string
{
    $config = license_config();
    return $config[$key] ?? '';
}

function license_option_name(string $suffix): string
{
    return license_config_value('prefix') . '_' . $suffix;
}

function license_page_slug(): string
{
    return license_config_value('license_page');
}

function license_current_domain(): string
{
    $domain = get_bloginfo('wpurl');
    return str_replace(search: ['https://', 'http://'], replace: '', subject: $domain);
}

function license_key(): string
{
    /** @var string $key */
    $key = get_option(license_option_name('license_key'), default_value: '');
    return strtolower(trim($key));
}

function license_error(): string
{
    return (string) get_option(license_option_name('license_error'), default_value: '');
}

function license_last_active_domain(): string
{
    return (string) get_option(license_option_name('license_domain'), default_value: '');
}

function license_key_last_4_digits(): string
{
    return substr(license_key(), offset: -4);
}

function license_key_masked(): string
{
    $key = license_key();
    if ($key === '') {
        return '';
    }

    return str_repeat(string: '•', times: 12) . license_key_last_4_digits();
}

function set_license_key(string $key): void
{
    update_option(license_option_name('license_key'), strtolower(trim($key)));
}

function set_license_status(string $status): void
{
    update_option(license_option_name('license_status'), $status);
}

function set_license_error(string $error): void
{
    set_license_status('inactive');
    update_option(license_option_name('license_error'), $error);
}

function set_license_last_active_domain(string $domain): void
{
    update_option(license_option_name('license_domain'), $domain);
}

function is_license_active(): bool
{
    return get_option(license_option_name('license_status'), default_value: '') === 'active';
}

function is_license_active_fresh(): bool
{
    refresh_license_status();
    return is_license_active();
}

function license_api_url(string $endpoint, array $params = []): string
{
    $url = trailingslashit(license_config_value('license_url')) . ltrim(string: $endpoint, characters: '/');

    if ($params !== []) {
        $url = add_query_arg($params, $url);
    }

    return $url;
}

function license_api_get(string $endpoint, array $params = []): array|WP_Error
{
    $response = wp_remote_get(license_api_url($endpoint, $params), [
        'headers' => ['Accept' => 'application/json'],
        'timeout' => 10,
    ]);

    if (is_wp_error($response)) {
        return $response;
    }

    $body = wp_remote_retrieve_body($response);
    $code = wp_remote_retrieve_response_code($response);

    if ($code >= 400) {
        return new WP_Error('novamira_pro_license_api_error', sprintf('API request failed with code %d', $code), [
            'status' => $code,
            'body' => $body,
        ]);
    }

    /** @var mixed $data */
    $data = json_decode($body, associative: true);
    if (!is_array($data)) {
        return new WP_Error(
            'novamira_pro_license_api_error',
            esc_html__('Invalid response from the license server.', domain: 'novamira-pro'),
            ['body' => $body],
        );
    }

    return $data;
}

function license_wp_version(): string
{
    return get_bloginfo('version');
}

function license_request_params(string $action, string $domain): array
{
    return [
        'woo_sl_action' => $action,
        'licence_key' => license_key(),
        'product_unique_id' => license_config_value('product_unique_id'),
        'domain' => $domain,
        'api_version' => '1.1',
        'wp-version' => license_wp_version(),
        'version' => license_config_value('version'),
        'is_multisite' => is_multisite(),
        'php' => PHP_VERSION,
    ];
}

function license_remote_status_check(string $domain): array|false
{
    $response = license_api_get('api.php', license_request_params('status-check', $domain));
    if (is_wp_error($response)) {
        return false;
    }

    /** @var mixed $status */
    $status = $response[0] ?? null;
    return is_array($status) ? $status : false;
}

function license_should_attempt_auto_activation(array $response): bool
{
    /** @var mixed $status_code */
    $status_code = $response['status_code'] ?? '';
    /** @var mixed $license_status */
    $license_status = $response['license_status'] ?? '';

    if (!is_string($status_code) || !is_string($license_status)) {
        return false;
    }

    return in_array($status_code, ['s205', 's215'], strict: true) && $license_status === 'expired';
}

function handle_license_status_response(array|false $response, string $domain): bool
{
    if ($response === false) {
        return false;
    }

    /** @var mixed $message */
    $message = $response['message'] ?? esc_html__('Unknown license server response.', domain: 'novamira-pro');
    if (!is_string($message)) {
        $message = esc_html__('Unknown license server response.', domain: 'novamira-pro');
    }

    /** @var mixed $status_code */
    $status_code = $response['status_code'] ?? '';
    if (!is_string($status_code)) {
        set_license_error($message);
        return false;
    }

    if ($status_code === 'e002') {
        set_license_error($message);
        return false;
    }

    if (in_array($status_code, ['s203', 'e204'], strict: true)) {
        set_license_error($message . ' (domain: ' . $domain . ')');
        return false;
    }

    if (!in_array($status_code, ['s205', 's215'], strict: true)) {
        set_license_error($message);
        return false;
    }

    if (license_should_attempt_auto_activation($response)) {
        set_license_error($message);
        return true;
    }

    set_license_status('active');
    set_license_last_active_domain(license_current_domain());
    update_option(license_option_name('license_error'), value: '');

    return false;
}

function refresh_license_status(): void
{
    if (license_key() === '') {
        set_license_error(esc_html__('No license key entered.', domain: 'novamira-pro'));
        return;
    }

    $domain = license_current_domain();
    $response = license_remote_status_check($domain);
    handle_license_status_response($response, $domain);
}

function refresh_and_repair_license_status(): void
{
    if (license_key() === '') {
        refresh_license_status();
        return;
    }

    $domain = license_current_domain();
    $response = license_remote_status_check($domain);
    $should_activate = handle_license_status_response($response, $domain);

    if ($should_activate) {
        activate_license();
    }
}

function license_request_message(string $action): string
{
    $response = license_api_get('api.php', license_request_params($action, license_current_domain()));

    if (is_wp_error($response)) {
        return esc_html__("Couldn't reach the license server. Try again in a few minutes.", domain: 'novamira-pro');
    }

    /** @var mixed $data */
    $data = reset($response);
    if (is_array($data) && is_string($data['message'] ?? null)) {
        return $data['message'];
    }

    return esc_html__('Unknown response from the license server.', domain: 'novamira-pro');
}

function license_is_staging_response(): bool
{
    $domain = license_current_domain();
    $response = license_remote_status_check($domain);

    if ($response === false) {
        return false;
    }

    return ($response['staging'] ?? '') === 'yes';
}

/** @return array{0:bool,1:string} */
function activate_license(): array
{
    $message = license_request_message('activate');
    $success = is_license_active_fresh();
    clear_update_cache();

    return [$success, $message];
}

/** @return array{0:bool,1:string} */
function activate_new_license_key(string $key): array
{
    set_license_key($key);
    return activate_license();
}

/** @return array{0:bool,1:string} */
function deactivate_license(): array
{
    $message = license_request_message('deactivate');
    $success = !is_license_active_fresh();

    if (license_is_staging_response()) {
        set_license_key('');
        refresh_license_status();
        $success = true;
        $message = esc_html__('License deactivated on this site.', domain: 'novamira-pro');
    }

    clear_update_cache();

    return [$success, $message];
}

function update_transient_key(): string
{
    return license_config_value('plugin_slug') . '_update_checker';
}

function clear_update_cache(): void
{
    delete_transient(update_transient_key());
}

function fetch_remote_update_data(): array|false
{
    if (!is_license_active() || license_key() === '') {
        return false;
    }

    /** @var mixed $cached */
    $cached = get_transient(update_transient_key());
    if (is_array($cached)) {
        /** @var mixed $cached_item */
        $cached_item = $cached[0] ?? null;
        return is_array($cached_item) ? $cached_item : false;
    }

    $response = license_api_get('info.php', [
        'domain' => license_current_domain(),
        'version' => license_config_value('version'),
        'licence_key' => license_key(),
        'beta' => 'false',
    ]);

    if (is_wp_error($response)) {
        set_transient(update_transient_key(), [false], expiration: 10_800);
        return false;
    }

    set_transient(update_transient_key(), [$response], expiration: 43_200);
    return $response;
}

function plugins_api(mixed $result, string $action, object $args): mixed
{
    if ($action !== 'plugin_information') {
        return $result;
    }

    /** @var mixed $requested_slug */
    $requested_slug = $args->slug ?? '';
    if (!is_string($requested_slug)) {
        return $result;
    }

    $valid_slugs = [license_config_value('plugin_slug'), license_config_value('plugin_base')];
    if (!in_array($requested_slug, $valid_slugs, strict: true)) {
        return $result;
    }

    $remote_data = fetch_remote_update_data();
    if ($remote_data === false) {
        return $result;
    }

    return build_plugin_details($remote_data);
}

function build_plugin_details(array $remote_data): stdClass
{
    $details = new stdClass();
    $details->name = $remote_data['name'] ?? '';
    $details->slug = $remote_data['slug'] ?? license_config_value('plugin_slug');
    $details->version = $remote_data['version'] ?? '';
    $details->tested = $remote_data['tested'] ?? '';
    $details->requires = $remote_data['requires'] ?? '';
    $details->author = $remote_data['author'] ?? '';
    $details->author_profile = $remote_data['author_profile'] ?? '';
    $details->download_link = $remote_data['download_url'] ?? '';
    $details->trunk = $remote_data['download_url'] ?? '';
    $details->requires_php = $remote_data['requires_php'] ?? '';
    $details->last_updated = $remote_data['last_updated'] ?? '';
    $details->sections = plugin_details_sections($remote_data['sections'] ?? null);
    $details->banners = plugin_details_banners($remote_data['banners'] ?? null);

    return $details;
}

function plugin_details_sections(mixed $sections): array
{
    if (!is_array($sections)) {
        return [];
    }

    return [
        'description' => $sections['description'] ?? '',
        'installation' => $sections['installation'] ?? '',
        'changelog' => $sections['changelog'] ?? '',
    ];
}

function plugin_details_banners(mixed $banners): array
{
    if (!is_array($banners)) {
        return [];
    }

    return [
        'low' => $banners['low'] ?? '',
        'high' => $banners['high'] ?? '',
    ];
}

function check_update_availability(mixed $updates): mixed
{
    if (!$updates instanceof stdClass) {
        return $updates;
    }

    $plugin_base = license_config_value('plugin_base');
    /** @var mixed $updates_response */
    $updates_response = $updates->response ?? [];
    if (!is_array($updates_response)) {
        $updates_response = [];
    }

    if (!is_license_active()) {
        unset($updates_response[$plugin_base]);
        $updates->response = $updates_response;
        add_action(
            'in_plugin_update_message-' . $plugin_base,
            callback: __NAMESPACE__ . '\\render_update_error_message',
            priority: 10,
            accepted_args: 2,
        );
        return $updates;
    }

    $remote_data = fetch_remote_update_data();
    if ($remote_data === false) {
        return $updates;
    }

    if (!update_requirements_met($remote_data)) {
        return $updates;
    }

    $version = (string) $remote_data['version'];

    $update_info = build_update_info($plugin_base, $version, $remote_data);
    $updates_response[$plugin_base] = $update_info;
    $updates->response = $updates_response;
    return $updates;
}

function update_requirements_met(array $remote_data): bool
{
    /** @var mixed $version */
    $version = $remote_data['version'] ?? null;
    /** @var mixed $requires */
    $requires = $remote_data['requires'] ?? null;
    /** @var mixed $requires_php */
    $requires_php = $remote_data['requires_php'] ?? null;

    if (!is_string($version) || !is_string($requires) || !is_string($requires_php)) {
        return false;
    }

    if (!version_compare(license_config_value('version'), $version, operator: '<')) {
        return false;
    }

    if (!version_compare(license_wp_version(), $requires, operator: '>=')) {
        return false;
    }

    if (!version_compare(PHP_VERSION, $requires_php, operator: '>=')) {
        return false;
    }

    return true;
}

function build_update_info(string $plugin_base, string $version, array $remote_data): stdClass
{
    $update_info = new stdClass();
    $update_info->slug = $plugin_base;
    $update_info->plugin = $plugin_base;
    $update_info->new_version = $version;
    $update_info->tested = $remote_data['tested'] ?? '';
    $update_info->package = $remote_data['download_url'] ?? '';

    return $update_info;
}

function render_update_error_message(mixed $plugin_data = null, mixed $response = null): void
{
    unset($plugin_data, $response);
    printf('&nbsp;<strong>%s</strong>', esc_html__('License inactive.', domain: 'novamira-pro'));
}

function add_manual_check_link(array $plugin_meta, string $plugin_file, array $plugin_data, string $status): array
{
    unset($plugin_data, $status);

    if ($plugin_file !== license_config_value('plugin_base')) {
        return $plugin_meta;
    }

    if (!is_license_active()) {
        return $plugin_meta;
    }

    $url = wp_nonce_url(
        admin_url('admin-ajax.php?action=check_' . license_config_value('prefix') . '_updates'),
        action: 'novamira_pro_update_check',
    );
    $plugin_meta[] = sprintf(
        '<a href="%s">%s</a>',
        esc_url($url),
        esc_html__('Check for updates', domain: 'novamira-pro'),
    );

    return $plugin_meta;
}

function process_manual_update_check(): void
{
    if (!novamira_min_version_satisfied() || !\novamira_current_user_can_manage()) {
        wp_die(esc_html__('You are not allowed to check updates.', domain: 'novamira-pro'));
    }

    check_admin_referer('novamira_pro_update_check');

    clear_update_cache();
    check_update_availability(get_site_transient('update_plugins'));
    wp_safe_redirect(admin_url('plugins.php'));
    exit();
}

/**
 * Notice ids that support a persistent, per-domain dismiss.
 *
 * @return list<string>
 */
function license_dismissible_notice_ids(): array
{
    return ['license-needed', 'domain-mismatch'];
}

/**
 * User-meta key under which a notice's dismiss is stored.
 */
function license_notice_dismiss_meta_key(string $id): string
{
    return license_config_value('prefix') . '_notice_dismissed_' . str_replace(search: '-', replace: '_', subject: $id);
}

/**
 * Has the current user dismissed this notice for the current domain?
 *
 * The dismiss is stored per-domain (the meta value is the domain it was
 * dismissed on), so cloning the database onto a different domain re-shows the
 * notice once instead of inheriting a stale dismiss from another site.
 */
function license_notice_dismissed(string $id): bool
{
    /** @var mixed $value */
    $value = get_user_meta(get_current_user_id(), key: license_notice_dismiss_meta_key($id), single: true);

    return is_string($value) && $value !== '' && $value === license_current_domain();
}

/**
 * Persist a per-domain dismiss for a license notice. Hooked on admin_init.
 */
function handle_license_notice_dismiss(): void
{
    /** @var mixed $raw */
    $raw = $_POST['novamira_pro_dismiss_notice'] ?? null;
    if (!is_string($raw)) {
        return;
    }

    $id = sanitize_key(wp_unslash($raw));
    if (!in_array($id, license_dismissible_notice_ids(), strict: true)) {
        return;
    }

    if (!novamira_min_version_satisfied() || !\novamira_current_user_can_manage()) {
        return;
    }

    check_admin_referer('novamira_pro_dismiss_notice_' . $id);

    update_user_meta(
        get_current_user_id(),
        meta_key: license_notice_dismiss_meta_key($id),
        meta_value: license_current_domain(),
    );

    $referer = wp_get_referer();
    wp_safe_redirect($referer !== false ? $referer : admin_url());
    exit();
}

/**
 * Render a warning notice with a persistent, per-domain dismiss control.
 *
 * @param string $id      One of license_dismissible_notice_ids().
 * @param string $message Notice body; may contain anchor markup.
 */
function render_dismissible_license_notice(string $id, string $message): void
{ ?>
    <div class="notice notice-warning">
        <p><?php echo wp_kses_post($message); ?></p>
        <form method="post" style="margin:0 0 8px;">
            <?php wp_nonce_field('novamira_pro_dismiss_notice_' . $id); ?>
            <?php wp_referer_field(); ?>
            <input type="hidden" name="novamira_pro_dismiss_notice" value="<?php echo esc_attr($id); ?>">
            <button type="submit" class="button button-small"><?php esc_html_e(
                'Dismiss',
                domain: 'novamira-pro',
            ); ?></button>
        </form>
    </div>
    <?php }

function render_activation_advisor(): void
{
    // Version gate first: the capability helper lives in the base plugin, so it
    // must not be called until we know the base meets Pro's required version.
    if (!is_admin() || !novamira_min_version_satisfied() || !\novamira_current_user_can_manage()) {
        return;
    }

    if (($_GET['page'] ?? null) === license_page_slug()) {
        return;
    }

    if (is_license_active()) {
        return;
    }

    // When a key exists but is bound to another domain, the domain-mismatch
    // notice speaks instead — never stack both on the same screen.
    $last_domain = license_last_active_domain();
    if (license_key() !== '' && $last_domain !== '' && $last_domain !== license_current_domain()) {
        return;
    }

    if (license_notice_dismissed('license-needed')) {
        return;
    }

    $license_url = admin_url('admin.php?page=' . license_page_slug());
    $pricing_url = license_config_value('pricing_url');

    render_dismissible_license_notice('license-needed', sprintf(
        /* translators: 1: open activate link, 2: close activate link, 3: open pricing link, 4: close pricing link */
        esc_html__('Novamira Pro needs a license. %1$sActivate yours%2$s or %3$sget one%4$s.', domain: 'novamira-pro'),
        '<a href="' . esc_url($license_url) . '">',
        '</a>',
        '<a href="' . esc_url($pricing_url) . '" target="_blank" rel="noopener noreferrer">',
        '</a>',
    ));
}

function render_domain_mismatch_notice(): void
{
    // Version gate first: the capability helper lives in the base plugin, so it
    // must not be called until we know the base meets Pro's required version.
    if (!is_admin() || !novamira_min_version_satisfied() || !\novamira_current_user_can_manage()) {
        return;
    }

    if (($_GET['page'] ?? null) === license_page_slug()) {
        return;
    }

    if (license_key() === '') {
        return;
    }

    if (is_license_active()) {
        return;
    }

    $last_domain = license_last_active_domain();
    if ($last_domain === '' || $last_domain === license_current_domain()) {
        return;
    }

    if (license_notice_dismissed('domain-mismatch')) {
        return;
    }

    $license_url = admin_url('admin.php?page=' . license_page_slug());

    render_dismissible_license_notice('domain-mismatch', sprintf(
        /* translators: 1: open license-page link, 2: close license-page link */
        esc_html__(
            'Novamira Pro license is tied to a different site. %1$sOpen the license page%2$s and reactivate it here.',
            domain: 'novamira-pro',
        ),
        '<a href="' . esc_url($license_url) . '">',
        '</a>',
    ));
}

function register_license_menu(): void
{
    $capability = function_exists('\\novamira_manage_capability') ? \novamira_manage_capability() : 'manage_options';

    add_submenu_page(
        parent_slug: 'novamira-connect',
        page_title: __('Novamira License', domain: 'novamira-pro'),
        menu_title: __('License', domain: 'novamira-pro'),
        capability: $capability,
        menu_slug: license_page_slug(),
        callback: __NAMESPACE__ . '\\render_license_page',
    );
}

function maybe_redirect_license_slug(): void
{
    if (!is_admin()) {
        return;
    }

    if (($_GET['page'] ?? null) === license_page_slug()) {
        return;
    }

    $request_uri = $_SERVER['REQUEST_URI'] ?? '';
    if ($request_uri === '') {
        return;
    }

    /** @var mixed $path */
    $path = wp_parse_url($request_uri, PHP_URL_PATH);
    if (!is_string($path)) {
        return;
    }

    if (basename($path) !== license_page_slug()) {
        return;
    }

    wp_safe_redirect(admin_url('admin.php?page=' . license_page_slug()));
    exit();
}

function add_plugin_action_links(array $links): array
{
    $links['license'] = sprintf(
        '<a href="%s">%s</a>',
        esc_url(admin_url('admin.php?page=' . license_page_slug())),
        esc_html__('License', domain: 'novamira-pro'),
    );

    return $links;
}

/** @return array{type:string,message:string}|null */
function license_notice_from_post(): ?array
{
    if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
        return null;
    }

    check_admin_referer('novamira_pro_license');

    $action = $_POST['novamira_pro_license_action'] ?? null;
    if (!is_string($action)) {
        return null;
    }

    if ($action === 'refresh') {
        refresh_and_repair_license_status();
        if (is_license_active()) {
            return ['type' => 'success', 'message' => __('License status refreshed.', domain: 'novamira-pro')];
        }

        $error = license_error();
        if ($error !== '') {
            return ['type' => 'warning', 'message' => $error];
        }

        return ['type' => 'warning', 'message' => __('License is not active.', domain: 'novamira-pro')];
    }

    if ($action === 'activate') {
        $raw_key = $_POST['license_key'] ?? '';
        if (is_array($raw_key)) {
            $raw_key = '';
        }

        $license_key = sanitize_text_field(wp_unslash($raw_key));
        // Empty field means "reactivate the stored key" — the UI hides the
        // input behind a "Change" toggle so the masked key isn't overwritten.
        $activation_result = $license_key === '' ? activate_license() : activate_new_license_key($license_key);
        [$success, $message] = $activation_result;
        if ($success) {
            return [
                'type' => 'success',
                'message' => __('License activated on this site.', domain: 'novamira-pro'),
            ];
        }

        return ['type' => 'error', 'message' => $message];
    }

    if ($action !== 'deactivate') {
        return null;
    }

    $deactivation_result = deactivate_license();
    [$success, $message] = $deactivation_result;
    if ($success) {
        return [
            'type' => 'success',
            'message' => __('License deactivated on this site.', domain: 'novamira-pro'),
        ];
    }

    return ['type' => 'error', 'message' => $message];
}

function render_license_dependency_notice(): void
{
    $message = sprintf(
        /* translators: 1: open link tag to the Novamira download page, 2: close link tag. */
        esc_html__(
            'Novamira Pro requires the Novamira plugin to be installed and activated. %1$sDownload it for free%2$s.',
            domain: 'novamira-pro',
        ),
        '<a href="https://novamira.ai/download" target="_blank" rel="noopener noreferrer">',
        '</a>',
    );

    if (defined('NOVAMIRA_VERSION')) {
        $message = sprintf(
            '%s <a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
            esc_html(sprintf(
                /* translators: 1: installed Novamira version, 2: minimum required version. */
                __(
                    'Novamira Pro requires Novamira %2$s or newer. The installed version is %1$s — please update Novamira to continue.',
                    domain: 'novamira-pro',
                ),
                (string) constant('NOVAMIRA_VERSION'),
                NOVAMIRA_PRO_MIN_NOVAMIRA_VERSION,
            )),
            esc_url('https://novamira.ai/download'),
            esc_html__('Download the latest Novamira version', domain: 'novamira-pro'),
        );
    }

    ?>
        <div class="wrap">
            <h1><?php esc_html_e('Novamira License', domain: 'novamira-pro'); ?></h1>
            <?php wp_admin_notice($message, ['type' => 'error', 'additional_classes' => ['inline']]); ?>
        </div>
        <?php
}

function render_license_page(): void
{
    if (!novamira_min_version_satisfied()) {
        render_license_dependency_notice();
        return;
    }

    render_license_ui();
}

function render_license_ui(): void
{
    if (!\novamira_current_user_can_manage()) {
        return;
    }

    $notice = license_notice_from_post();
    refresh_and_repair_license_status();

    $is_active = is_license_active();
    $license_key = license_key();
    $license_error = license_error();
    $license_domain = license_last_active_domain();
    $status_class = $is_active ? 'is-active' : 'is-inactive';
    $status_label = $is_active ? __('Active', domain: 'novamira-pro') : __('Inactive', domain: 'novamira-pro');
    $submit_action = $is_active ? 'deactivate' : 'activate';
    $submit_label = $is_active
        ? __('Deactivate', domain: 'novamira-pro')
        : __('Save and activate', domain: 'novamira-pro');
    $submit_class = $is_active ? 'button button-secondary' : 'button button-primary';

    $status_message = __('Activate your license to get Novamira Pro updates on this site.', domain: 'novamira-pro');
    if ($is_active) {
        $status_message = sprintf(
            __('Your license ending in %s is active for this site.', domain: 'novamira-pro'),
            license_key_last_4_digits(),
        );
    }
    if (!$is_active && $license_error !== '') {
        $status_message = $license_error;
    }

    if (function_exists('novamira_render_admin_header')) {
        novamira_render_admin_header();
    }

    ?>
    <div class="wrap">
        <h1><?php esc_html_e('Novamira License', domain: 'novamira-pro'); ?></h1>
        <style>
            .novamira-pro-license-grid { display:grid; gap:20px; grid-template-columns:minmax(0, 2fr) minmax(280px, 1fr); max-width:1100px; }
            .novamira-pro-license-card { background:#fff; border:1px solid #dcdcde; border-radius:12px; padding:24px; box-shadow:0 1px 2px rgba(0,0,0,.04); }
            .novamira-pro-license-card h2 { margin-top:0; }
            .novamira-pro-license-status { display:inline-flex; align-items:center; gap:8px; padding:6px 12px; border-radius:999px; font-weight:600; }
            .novamira-pro-license-status.is-active { background:#edf7ed; color:#0a5c1b; }
            .novamira-pro-license-status.is-inactive { background:#fcf0f1; color:#8a2424; }
            .novamira-pro-license-input { width:100%; max-width:420px; font-family:monospace; }
            .novamira-pro-license-meta { margin:16px 0 0; color:#50575e; }
            .novamira-pro-license-actions { display:flex; gap:12px; align-items:center; flex-wrap:wrap; }
            .novamira-pro-license-key-display { display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
            .novamira-pro-license-key-mask { display:inline-block; padding:6px 12px; background:#f0f0f1; border:1px solid #dcdcde; border-radius:6px; font-family:monospace; letter-spacing:2px; }
            @media screen and (max-width: 900px) { .novamira-pro-license-grid { grid-template-columns:1fr; } }
        </style>
        <?php if ($notice !== null) {
            $notice_type = $notice['type'];
            $notice_message = $notice['message'];
            ?>
            <div class="notice notice-<?php echo esc_attr($notice_type); ?> is-dismissible"><p><?php echo
                esc_html($notice_message)
            ; ?></p></div>
        <?php
        } ?>
        <div class="novamira-pro-license-grid">
            <section class="novamira-pro-license-card">
                <h2><?php esc_html_e('Activation', domain: 'novamira-pro'); ?></h2>
                <p><span class="novamira-pro-license-status <?php echo esc_attr($status_class); ?>"><?php echo
                    esc_html($status_label)
                ; ?></span></p>
                <form method="post" action="">
                    <?php wp_nonce_field('novamira_pro_license'); ?>
                    <p><label for="novamira-pro-license-key"><strong><?php esc_html_e(
                        'License key',
                        domain: 'novamira-pro',
                    ); ?></strong></label></p>
                    <?php if ($license_key !== '') { ?>
                        <p class="novamira-pro-license-key-display" data-novamira-pro-license-display>
                            <code class="novamira-pro-license-key-mask"><?php echo
                                esc_html(license_key_masked())
                            ; ?></code>
                            <button type="button" class="button-link" data-novamira-pro-license-change><?php esc_html_e(
                                'Change',
                                domain: 'novamira-pro',
                            ); ?></button>
                        </p>
                    <?php } ?>
                    <p data-novamira-pro-license-editor<?php echo $license_key !== '' ? ' hidden' : ''; ?>>
                        <input
                            id="novamira-pro-license-key"
                            class="regular-text novamira-pro-license-input"
                            type="text"
                            name="license_key"
                            value=""
                            autocomplete="off"
                            autocapitalize="off"
                            autocorrect="off"
                            spellcheck="false"
                            placeholder="<?php echo
                                esc_attr(
                                    $license_key !== ''
                                        ? __('Enter a new license key', domain: 'novamira-pro')
                                        : __('Enter your license key', domain: 'novamira-pro'),
                                )
                            ; ?>"
                        >
                    </p>
                    <div class="novamira-pro-license-actions">
                        <button type="submit" name="novamira_pro_license_action" value="<?php echo
                            esc_attr($submit_action)
                        ; ?>" class="<?php echo esc_attr($submit_class); ?>"><?php echo
                            esc_html($submit_label)
                        ; ?></button>
                        <button type="submit" name="novamira_pro_license_action" value="refresh" class="button-link"><?php esc_html_e(
                            'Refresh status',
                            domain: 'novamira-pro',
                        ); ?></button>
                    </div>
                </form>
                <div class="novamira-pro-license-meta">
                    <p><?php echo esc_html($status_message); ?></p>
                    <?php if ($license_domain !== '') { ?>
                        <p><strong><?php esc_html_e(
                            'Last active domain:',
                            domain: 'novamira-pro',
                        ); ?></strong> <code><?php echo esc_html($license_domain); ?></code></p>
                    <?php } ?>
                </div>
            </section>

            <aside class="novamira-pro-license-card">
                <h2><?php esc_html_e('Updates', domain: 'novamira-pro'); ?></h2>
                <p><?php esc_html_e(
                    'Updates arrive in the Plugins screen once your license is active on this site.',
                    domain: 'novamira-pro',
                ); ?></p>
                <p><?php esc_html_e('Releases are served directly by Dynamic.ooo.', domain: 'novamira-pro'); ?></p>
                <p><a class="button button-secondary" href="<?php echo
                    esc_url(license_config_value('pricing_url'))
                ; ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e(
                    'Get a license',
                    domain: 'novamira-pro',
                ); ?></a></p>
            </aside>
        </div>
        <script>
            (function () {
                var button = document.querySelector('[data-novamira-pro-license-change]');
                if (button === null) {
                    return;
                }
                button.addEventListener('click', function () {
                    var display = document.querySelector('[data-novamira-pro-license-display]');
                    var editor = document.querySelector('[data-novamira-pro-license-editor]');
                    if (display === null || editor === null) {
                        return;
                    }
                    display.hidden = true;
                    editor.hidden = false;
                    var input = editor.querySelector('input');
                    if (input !== null) {
                        input.focus();
                    }
                });
            })();
        </script>
    </div>
    <?php
}

function license_cron_hook(): string
{
    return license_config_value('prefix') . '_check_license_cron';
}

// Self-healing cron scheduler: re-adds the event if the site has none queued.
// Without this a one-time status check at activation would hold "active"
// forever, even after the license expired or was revoked upstream.
function schedule_license_cron(): void
{
    $hook = license_cron_hook();
    if (wp_next_scheduled($hook) === false) {
        wp_schedule_event(time(), recurrence: 'daily', hook: $hook);
    }
}

function unschedule_license_cron(): void
{
    wp_clear_scheduled_hook(license_cron_hook());
}

function boot_license(): void
{
    add_action('admin_init', callback: __NAMESPACE__ . '\\maybe_redirect_license_slug');
    add_action('admin_init', callback: __NAMESPACE__ . '\\schedule_license_cron');
    add_action('admin_init', callback: __NAMESPACE__ . '\\handle_license_notice_dismiss');
    add_action(license_cron_hook(), callback: __NAMESPACE__ . '\\refresh_and_repair_license_status');
    add_action('admin_menu', callback: __NAMESPACE__ . '\\register_license_menu', priority: 100);
    add_action('admin_notices', callback: __NAMESPACE__ . '\\render_activation_advisor');
    add_action('admin_notices', callback: __NAMESPACE__ . '\\render_domain_mismatch_notice');
    add_filter('site_transient_update_plugins', callback: __NAMESPACE__ . '\\check_update_availability');
    add_filter('plugins_api', callback: __NAMESPACE__ . '\\plugins_api', priority: 20, accepted_args: 3);
    add_action('upgrader_process_complete', callback: __NAMESPACE__ . '\\clear_update_cache', priority: 10);
    add_filter('plugin_row_meta', callback: __NAMESPACE__ . '\\add_manual_check_link', priority: 20, accepted_args: 4);
    add_filter(
        'plugin_action_links_' . license_config_value('plugin_base'),
        callback: __NAMESPACE__ . '\\add_plugin_action_links',
    );
    add_action(
        'wp_ajax_check_' . license_config_value('prefix') . '_updates',
        callback: __NAMESPACE__ . '\\process_manual_update_check',
    );
}

Youez - 2016 - github.com/yon3zu
LinuXploit