plugin = plugin_basename(MAHAK_AUTHENTICATE_BRIDGE_FILE); $this->slug = dirname($this->plugin); } public static function boot(): void { if (self::$instance !== null) { return; } self::$instance = new self(); add_filter('pre_set_site_transient_update_plugins', [self::$instance, 'addUpdate']); add_filter('plugins_api', [self::$instance, 'addPluginInformation'], 20, 3); add_action('admin_post_'.self::CHECK_ACTION, [self::$instance, 'checkNow']); } public function addUpdate($transient) { if (!is_object($transient) || empty($transient->checked)) { return $transient; } $update = $this->availableUpdate(); if ($update !== null) { if (!isset($transient->response) || !is_array($transient->response)) { $transient->response = []; } $transient->response[$this->plugin] = $update; } return $transient; } public function addPluginInformation($result, string $action, $args) { if ($action !== 'plugin_information' || ($args->slug ?? '') !== $this->slug) { return $result; } $release = $this->latestRelease(); if (is_wp_error($release)) { return $result; } $package = $this->releasePackage($release); if ($package === null) { return $result; } return (object) [ 'name' => 'Mahak Authenticate Bridge', 'slug' => $this->slug, 'version' => $this->releaseVersion($release), 'author' => 'Dabestaniha', 'homepage' => $release['html_url'] ?? 'https://mahgit.ir/dabestaniha/mahak-authenticate-bridge', 'download_link' => $package, 'requires_php' => '7.4', 'sections' => [ 'description' => 'Authenticate WordPress users via JSON Web Tokens from the Mahakiha application.', 'changelog' => nl2br(esc_html((string) ($release['body'] ?? ''))), ], ]; } public function checkNow(): void { if (!current_user_can('update_plugins')) { wp_die(esc_html__('Sorry, you are not allowed to update plugins.')); } check_admin_referer(self::CHECK_ACTION); delete_site_transient(self::RELEASE_CACHE); delete_site_transient('update_plugins'); wp_update_plugins(); wp_safe_redirect(add_query_arg( ['page' => config('mahak.settings-page'), 'update-checked' => '1'], admin_url('options-general.php') )); exit; } public static function renderUpdatePanel(): void { if (self::$instance === null || !current_user_can('update_plugins')) { return; } $updater = self::$instance; $release = $updater->latestRelease(); echo '
'.sprintf( esc_html__('Installed version: %s'), ''.esc_html(MAHAK_AUTHENTICATE_BRIDGE_VERSION).'' ).'
'; if (is_wp_error($release)) { echo ''.esc_html($release->get_error_message()).'
'.sprintf(esc_html__('Version %s is available.'), esc_html($update->new_version)).'
'; $updateUrl = wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin&plugin='.rawurlencode($updater->plugin)), 'upgrade-plugin_'.$updater->plugin ); echo ''; } else { echo ''.esc_html__('You are using the latest available version.').'
'; } } echo ''; } private function availableUpdate(?array $release = null): ?object { $release = $release ?? $this->latestRelease(); if (is_wp_error($release)) { return null; } $version = $this->releaseVersion($release); $package = $this->releasePackage($release); if ($version === '' || $package === null || !version_compare($version, MAHAK_AUTHENTICATE_BRIDGE_VERSION, '>')) { return null; } return (object) [ 'id' => $release['html_url'] ?? self::API_URL, 'slug' => $this->slug, 'plugin' => $this->plugin, 'new_version' => $version, 'url' => $release['html_url'] ?? '', 'package' => $package, 'requires_php' => '7.4', ]; } private function latestRelease() { $cached = get_site_transient(self::RELEASE_CACHE); if (is_array($cached)) { return $cached; } $response = wp_remote_get(self::API_URL, [ 'headers' => [ 'Accept' => 'application/json', 'User-Agent' => 'Mahak-Authenticate-Bridge/'.MAHAK_AUTHENTICATE_BRIDGE_VERSION, ], 'timeout' => 10, ]); if (is_wp_error($response)) { return new \WP_Error('mahak_update_request_failed', 'Could not contact Mahgit to check for plugin updates.'); } if (wp_remote_retrieve_response_code($response) !== 200) { return new \WP_Error('mahak_update_response_invalid', 'No published plugin release is currently available on Mahgit.'); } $release = json_decode(wp_remote_retrieve_body($response), true); if (!is_array($release) || !empty($release['draft']) || !empty($release['prerelease'])) { return new \WP_Error('mahak_update_release_invalid', 'Mahgit returned invalid plugin release information.'); } if ($this->releaseVersion($release) === '' || $this->releasePackage($release) === null) { return new \WP_Error( 'mahak_update_asset_missing', 'The latest Mahgit release does not contain a valid mahak-authenticate-bridge.zip package.' ); } set_site_transient(self::RELEASE_CACHE, $release, 6 * HOUR_IN_SECONDS); return $release; } private function releaseVersion(array $release): string { return ltrim((string) ($release['tag_name'] ?? ''), 'vV'); } private function releasePackage(array $release): ?string { foreach (($release['assets'] ?? []) as $asset) { if (($asset['name'] ?? '') !== self::RELEASE_ASSET) { continue; } $url = esc_url_raw((string) ($asset['browser_download_url'] ?? '')); $path = (string) wp_parse_url($url, PHP_URL_PATH); if ( $url !== '' && wp_parse_url($url, PHP_URL_SCHEME) === 'https' && wp_parse_url($url, PHP_URL_HOST) === 'mahgit.ir' && strpos($path, '/dabestaniha/mahak-authenticate-bridge/releases/download/') === 0 ) { return $url; } } return null; } }