plugin_file = $plugin_file; $this->plugin_slug = basename($plugin_file, '.php'); $this->license_key = $license_key; $this->update_server = trailingslashit($update_server); // Get plugin version from header if (!function_exists('get_plugin_data')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $plugin_data = get_plugin_data($plugin_file); $this->version = $plugin_data['Version']; $this->transient_key = 'wpdd_update_' . $this->plugin_slug; // Initialize hooks $this->init_hooks(); // Add settings page if requested if (isset($args['add_settings_page']) && $args['add_settings_page']) { $this->add_settings_page(); } } /** * Initialize WordPress hooks */ private function init_hooks() { add_filter('pre_set_site_transient_update_plugins', array($this, 'check_for_update')); add_filter('plugins_api', array($this, 'plugin_info'), 10, 3); add_filter('upgrader_pre_download', array($this, 'maybe_download_package'), 10, 3); // Clean up transients on plugin activation/deactivation register_activation_hook($this->plugin_file, array($this, 'delete_transients')); register_deactivation_hook($this->plugin_file, array($this, 'delete_transients')); } /** * Check for plugin updates */ public function check_for_update($transient) { if (empty($transient->checked)) { return $transient; } // Get cached update info $update_cache = get_transient($this->transient_key); if ($update_cache !== false) { if (isset($update_cache->update_available) && $update_cache->update_available) { $transient->response[$this->plugin_file] = $update_cache; } return $transient; } // Check for update from server $update_info = $this->request_update_info(); if ($update_info && isset($update_info['update_available']) && $update_info['update_available']) { $plugin_data = array( 'slug' => $this->plugin_slug, 'plugin' => $this->plugin_file, 'new_version' => $update_info['version'], 'url' => $update_info['url'], 'package' => $update_info['package'], 'tested' => $update_info['tested'], 'requires' => $update_info['requires'], 'requires_php' => $update_info['requires_php'], 'compatibility' => new stdClass() ); $update_cache = (object) $plugin_data; $update_cache->update_available = true; // Cache for 12 hours set_transient($this->transient_key, $update_cache, 12 * HOUR_IN_SECONDS); $transient->response[$this->plugin_file] = $update_cache; } else { // No update available - cache negative result for 12 hours $update_cache = new stdClass(); $update_cache->update_available = false; set_transient($this->transient_key, $update_cache, 12 * HOUR_IN_SECONDS); } return $transient; } /** * Provide plugin information for the update screen */ public function plugin_info($false, $action, $args) { if ($action !== 'plugin_information' || $args->slug !== $this->plugin_slug) { return $false; } $update_info = $this->request_update_info(); if (!$update_info) { return $false; } return (object) array( 'slug' => $this->plugin_slug, 'name' => $update_info['name'] ?? $this->plugin_slug, 'version' => $update_info['version'] ?? $this->version, 'author' => $update_info['author'] ?? '', 'homepage' => $update_info['url'] ?? '', 'requires' => $update_info['requires'] ?? '5.0', 'tested' => $update_info['tested'] ?? get_bloginfo('version'), 'requires_php' => $update_info['requires_php'] ?? '7.0', 'download_link' => $update_info['package'] ?? '', 'sections' => array( 'changelog' => $update_info['changelog'] ?? '', 'description' => $update_info['description'] ?? '' ), 'banners' => array(), 'icons' => array() ); } /** * Handle package download with license validation */ public function maybe_download_package($reply, $package, $upgrader) { // Check if this is our plugin's package if (strpos($package, $this->update_server) === false || strpos($package, $this->plugin_slug) === false) { return $reply; } // Validate license before download $license_valid = $this->validate_license(); if (!$license_valid) { return new WP_Error('license_invalid', __('Your license key is invalid or expired. Please update your license key.')); } return $reply; } /** * Request update information from server */ private function request_update_info() { $url = $this->update_server . "wp-json/wpdd/v1/check-update/{$this->plugin_slug}"; $url = add_query_arg(array( 'license_key' => $this->license_key, 'version' => $this->version, 'site_url' => home_url() ), $url); $response = wp_remote_get($url, array( 'timeout' => 15, 'headers' => array( 'User-Agent' => 'WPDD-Updater/' . $this->version . '; ' . home_url() ) )); if (is_wp_error($response)) { error_log('WPDD Updater: Failed to check for updates - ' . $response->get_error_message()); return false; } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (!$data || !isset($data['success'])) { error_log('WPDD Updater: Invalid response from update server'); return false; } if (!$data['success']) { if (isset($data['error'])) { error_log('WPDD Updater: ' . $data['error'] . ' - ' . ($data['message'] ?? '')); } return false; } return $data; } /** * Validate license with server */ public function validate_license() { if (empty($this->license_key)) { return false; } $url = $this->update_server . 'wp-json/wpdd/v1/validate-license'; $response = wp_remote_post($url, array( 'timeout' => 15, 'body' => array( 'license_key' => $this->license_key, 'product_slug' => $this->plugin_slug, 'site_url' => home_url() ), 'headers' => array( 'User-Agent' => 'WPDD-Updater/' . $this->version . '; ' . home_url() ) )); if (is_wp_error($response)) { return false; } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); return $data && isset($data['success']) && $data['success']; } /** * Activate license */ public function activate_license($license_key = null) { if ($license_key) { $this->license_key = $license_key; } if (empty($this->license_key)) { return array( 'success' => false, 'message' => __('Please enter a license key.') ); } $url = $this->update_server . 'wp-json/wpdd/v1/activate-license'; $response = wp_remote_post($url, array( 'timeout' => 15, 'body' => array( 'license_key' => $this->license_key, 'site_url' => home_url(), 'site_name' => get_bloginfo('name'), 'wp_version' => get_bloginfo('version'), 'php_version' => PHP_VERSION ), 'headers' => array( 'User-Agent' => 'WPDD-Updater/' . $this->version . '; ' . home_url() ) )); if (is_wp_error($response)) { return array( 'success' => false, 'message' => $response->get_error_message() ); } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (!$data) { return array( 'success' => false, 'message' => __('Invalid response from server.') ); } return $data; } /** * Deactivate license */ public function deactivate_license() { if (empty($this->license_key)) { return array( 'success' => false, 'message' => __('No license key to deactivate.') ); } $url = $this->update_server . 'wp-json/wpdd/v1/deactivate-license'; $response = wp_remote_post($url, array( 'timeout' => 15, 'body' => array( 'license_key' => $this->license_key, 'site_url' => home_url() ), 'headers' => array( 'User-Agent' => 'WPDD-Updater/' . $this->version . '; ' . home_url() ) )); if (is_wp_error($response)) { return array( 'success' => false, 'message' => $response->get_error_message() ); } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); return $data ?: array( 'success' => false, 'message' => __('Invalid response from server.') ); } /** * Add a simple settings page for license management */ private function add_settings_page() { add_action('admin_menu', array($this, 'add_license_menu')); add_action('admin_init', array($this, 'handle_license_actions')); } /** * Add license menu page */ public function add_license_menu() { add_options_page( sprintf(__('%s License', 'default'), $this->plugin_slug), sprintf(__('%s License', 'default'), $this->plugin_slug), 'manage_options', $this->plugin_slug . '-license', array($this, 'render_license_page') ); } /** * Handle license activation/deactivation */ public function handle_license_actions() { if (!current_user_can('manage_options')) { return; } $option_key = $this->plugin_slug . '_license_key'; if (isset($_POST['activate_license'])) { if (!wp_verify_nonce($_POST['license_nonce'], 'wpdd_license_nonce')) { return; } $license_key = sanitize_text_field($_POST['license_key']); $result = $this->activate_license($license_key); if ($result['success']) { update_option($option_key, $license_key); $this->license_key = $license_key; add_settings_error('wpdd_license', 'activated', $result['message'], 'updated'); } else { add_settings_error('wpdd_license', 'activation_failed', $result['message'], 'error'); } } if (isset($_POST['deactivate_license'])) { if (!wp_verify_nonce($_POST['license_nonce'], 'wpdd_license_nonce')) { return; } $result = $this->deactivate_license(); if ($result['success']) { delete_option($option_key); $this->license_key = ''; add_settings_error('wpdd_license', 'deactivated', $result['message'], 'updated'); } else { add_settings_error('wpdd_license', 'deactivation_failed', $result['message'], 'error'); } } } /** * Render license management page */ public function render_license_page() { $option_key = $this->plugin_slug . '_license_key'; $license_key = get_option($option_key, ''); $license_status = $this->validate_license(); ?>

plugin_slug)); ?>

transient_key); delete_site_transient('update_plugins'); } } } // End class exists check