plugin_basename = plugin_basename(dirname(dirname(__FILE__)) . '/twilio-wp-plugin.php'); $this->current_version = defined('TWP_VERSION') ? TWP_VERSION : '0.0.0'; $this->gitea_api_url = $this->gitea_base_url . '/api/v1/repos/' . $this->gitea_repo . '/releases/latest'; } /** * Initialize updater hooks */ public function init() { // Hook into WordPress update checks add_filter('pre_set_site_transient_update_plugins', array($this, 'check_for_update')); add_filter('plugins_api', array($this, 'plugin_info'), 10, 3); // Add settings page for manual check add_action('admin_init', array($this, 'register_settings')); // Add update check to admin notices if (get_option('twp_auto_update_enabled', '1') === '1') { add_action('admin_init', array($this, 'maybe_auto_check_updates')); } } /** * Register auto-update settings */ public function register_settings() { register_setting('twp_settings', 'twp_auto_update_enabled'); register_setting('twp_settings', 'twp_gitea_repo'); register_setting('twp_settings', 'twp_gitea_token'); // Optional for private repos } /** * Check for updates periodically */ public function maybe_auto_check_updates() { $last_check = get_option('twp_last_update_check', 0); $check_interval = 12 * HOUR_IN_SECONDS; // Check every 12 hours if (time() - $last_check > $check_interval) { update_option('twp_last_update_check', time()); // Force WordPress to check for updates wp_clean_plugins_cache(); } } /** * Check for plugin updates */ public function check_for_update($transient) { if (empty($transient->checked)) { return $transient; } // Get Gitea repo from settings if available $custom_repo = get_option('twp_gitea_repo', ''); if (!empty($custom_repo)) { $this->gitea_repo = $custom_repo; $this->gitea_api_url = $this->gitea_base_url . '/api/v1/repos/' . $this->gitea_repo . '/releases/latest'; } $update_info = $this->get_latest_release(); if ($update_info && version_compare($this->current_version, $update_info->version, '<')) { $plugin_data = array( 'id' => 'twilio-wp-plugin', 'slug' => $this->plugin_slug, 'plugin' => $this->plugin_basename, 'new_version' => $update_info->version, 'url' => $update_info->homepage, 'package' => $update_info->download_url, 'tested' => '6.8', 'requires' => '5.8', 'requires_php' => '7.4', 'icons' => array(), 'banners' => array(), 'compatibility' => new stdClass(), ); $transient->response[$this->plugin_basename] = (object) $plugin_data; error_log("TWP Auto-Updater: New version {$update_info->version} available (current: {$this->current_version})"); } else { error_log("TWP Auto-Updater: No updates available (current: {$this->current_version})"); } return $transient; } /** * Get plugin information for update screen */ public function plugin_info($false, $action, $args) { if ($action !== 'plugin_information') { return $false; } if (!isset($args->slug) || $args->slug !== $this->plugin_slug) { return $false; } $update_info = $this->get_latest_release(); if (!$update_info) { return $false; } $plugin_info = new stdClass(); $plugin_info->name = 'Twilio WP Plugin'; $plugin_info->slug = $this->plugin_slug; $plugin_info->version = $update_info->version; $plugin_info->author = 'Joshua Knapp'; $plugin_info->homepage = $update_info->homepage; $plugin_info->download_link = $update_info->download_url; $plugin_info->requires = '5.8'; $plugin_info->tested = '6.8'; $plugin_info->requires_php = '7.4'; $plugin_info->last_updated = $update_info->release_date; $plugin_info->downloaded = 10; $plugin_info->sections = array( 'description' => '

Twilio WordPress Plugin for call management and mobile app support.

', 'changelog' => '
' . esc_html($update_info->changelog) . '
', 'installation' => '

Upload the plugin to your WordPress site and activate it.

' ); return $plugin_info; } /** * Get latest release information from Gitea */ private function get_latest_release() { // Check cache first (1 hour) $cache_key = 'twp_latest_release'; $cached = get_transient($cache_key); if ($cached !== false) { return $cached; } // Use cURL for Gitea API $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->gitea_api_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json')); curl_setopt($ch, CURLOPT_USERAGENT, 'WordPress/Twilio-WP-Plugin-Updater'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Add Gitea token if configured (for private repos) $gitea_token = get_option('twp_gitea_token', ''); if (!empty($gitea_token)) { curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Accept: application/json', 'Authorization: token ' . $gitea_token )); } $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if (!$response || $http_code !== 200) { error_log("TWP Auto-Updater: Gitea API returned status $http_code"); return false; } $release = json_decode($response); if (!$release || !isset($release->tag_name)) { error_log('TWP Auto-Updater: Invalid release data from Gitea'); return false; } // Parse release information $version = ltrim($release->tag_name, 'v'); // Remove 'v' prefix if present $download_url = null; // Find the zip asset if (isset($release->assets) && is_array($release->assets)) { foreach ($release->assets as $asset) { if (strpos($asset->name, '.zip') !== false) { $download_url = $asset->browser_download_url; break; } } } // Fallback to zipball if no asset found if (!$download_url) { $download_url = $release->zipball_url; } // Format changelog $changelog = !empty($release->body) ? $release->body : 'No changelog provided for this release.'; // Handle empty changelog if (empty(trim($changelog))) { $changelog = "Version " . $version . "\n\n" . "Released on " . date('F j, Y', strtotime($release->published_at)) . "\n\n" . "* Updated plugin files"; } $update_info = (object) array( 'version' => $version, 'download_url' => $download_url, 'homepage' => $this->gitea_base_url . '/' . $this->gitea_repo, 'release_date' => $release->published_at, 'description' => $changelog, 'changelog' => $changelog ); // Cache for 1 hour set_transient($cache_key, $update_info, HOUR_IN_SECONDS); return $update_info; } /** * Manual update check (for admin page) */ public function manual_check_for_updates() { // Clear cache delete_transient('twp_latest_release'); update_option('twp_last_update_check', 0); // Force WordPress to check wp_clean_plugins_cache(); delete_site_transient('update_plugins'); $update_info = $this->get_latest_release(); if (!$update_info) { return array( 'success' => false, 'message' => 'Failed to check for updates. Please check your internet connection and Gitea repository settings.' ); } if (version_compare($this->current_version, $update_info->version, '<')) { return array( 'success' => true, 'update_available' => true, 'current_version' => $this->current_version, 'latest_version' => $update_info->version, 'message' => "Update available: Version {$update_info->version}. Go to Plugins page to update." ); } else { return array( 'success' => true, 'update_available' => false, 'current_version' => $this->current_version, 'message' => 'You are running the latest version.' ); } } /** * Get current update status */ public function get_update_status() { $update_info = $this->get_latest_release(); return array( 'current_version' => $this->current_version, 'latest_version' => $update_info ? $update_info->version : 'Unknown', 'update_available' => $update_info && version_compare($this->current_version, $update_info->version, '<'), 'last_check' => get_option('twp_last_update_check', 0), 'auto_update_enabled' => get_option('twp_auto_update_enabled', '1') === '1' ); } }