commit ab882a7333880a25f539903e1e3fee5ead5707fb Author: Ronny Grobel Date: Mon Apr 13 21:50:16 2026 +0200 Initial plugin commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b6e650 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +Thumbs.db +*.zip diff --git a/kgv-updater.php b/kgv-updater.php new file mode 100644 index 0000000..9923590 --- /dev/null +++ b/kgv-updater.php @@ -0,0 +1,322 @@ + 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'default' => '', + ) + ); + + register_setting( + 'kgv_updater_settings', + self::OPTION_HOST, + array( + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'default' => 'git.apex-project.de', + ) + ); + } + + public function register_settings_page() { + add_options_page( + 'KGV Updater', + 'KGV Updater', + 'manage_options', + 'kgv-updater', + array( $this, 'render_settings_page' ) + ); + } + + public function render_settings_page() { + if ( ! current_user_can( 'manage_options' ) ) { + return; + } + ?> +
+

KGV Updater

+

Prueft KGV-Plugins mit Update URI auf neue Versionen in Gitea.

+
+ + + + + + + + + + + + +
+
+ checked ) || ! is_object( $transient ) ) { + return $transient; + } + + $plugins = $this->get_managed_plugins(); + + foreach ( $plugins as $plugin_file => $plugin_data ) { + $current_version = isset( $plugin_data['Version'] ) ? $plugin_data['Version'] : ''; + $repo_url = isset( $plugin_data['UpdateURI'] ) ? $plugin_data['UpdateURI'] : ''; + $release = $this->get_release_data( $repo_url ); + + if ( empty( $release['version'] ) ) { + continue; + } + + if ( version_compare( $release['version'], $current_version, '>' ) ) { + $transient->response[ $plugin_file ] = (object) array( + 'id' => $repo_url, + 'slug' => dirname( $plugin_file ), + 'plugin' => $plugin_file, + 'new_version' => $release['version'], + 'url' => $repo_url, + 'package' => $release['package'], + 'tested' => get_bloginfo( 'version' ), + ); + } else { + $transient->no_update[ $plugin_file ] = (object) array( + 'id' => $repo_url, + 'slug' => dirname( $plugin_file ), + 'plugin' => $plugin_file, + 'new_version' => $current_version, + 'url' => $repo_url, + 'package' => '', + ); + } + } + + return $transient; + } + + public function plugins_api( $result, $action, $args ) { + if ( 'plugin_information' !== $action || empty( $args->slug ) ) { + return $result; + } + + $plugins = $this->get_managed_plugins(); + + foreach ( $plugins as $plugin_file => $plugin_data ) { + if ( dirname( $plugin_file ) !== $args->slug ) { + continue; + } + + $repo_url = isset( $plugin_data['UpdateURI'] ) ? $plugin_data['UpdateURI'] : ''; + $release = $this->get_release_data( $repo_url ); + + return (object) array( + 'name' => $plugin_data['Name'], + 'slug' => dirname( $plugin_file ), + 'version' => ! empty( $release['version'] ) ? $release['version'] : $plugin_data['Version'], + 'author' => $plugin_data['AuthorName'], + 'homepage' => $repo_url, + 'section' => array( + 'description' => ! empty( $plugin_data['Description'] ) ? $plugin_data['Description'] : 'KGV Plugin aus Gitea.', + ), + 'download_link' => ! empty( $release['package'] ) ? $release['package'] : '', + ); + } + + return $result; + } + + private function get_managed_plugins() { + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + $plugins = get_plugins(); + $host = $this->get_gitea_host(); + $managed = array(); + + foreach ( $plugins as $plugin_file => $plugin_data ) { + if ( plugin_basename( __FILE__ ) === $plugin_file ) { + continue; + } + + $update_uri = isset( $plugin_data['UpdateURI'] ) ? trim( (string) $plugin_data['UpdateURI'] ) : ''; + $name = isset( $plugin_data['Name'] ) ? (string) $plugin_data['Name'] : ''; + + if ( '' === $update_uri || 0 !== strpos( $name, 'KGV' ) ) { + continue; + } + + $uri_host = wp_parse_url( $update_uri, PHP_URL_HOST ); + if ( empty( $uri_host ) || $uri_host !== $host ) { + continue; + } + + $managed[ $plugin_file ] = $plugin_data; + } + + return $managed; + } + + private function get_release_data( $repo_url ) { + $cache_key = 'kgv_updater_release_' . md5( $repo_url ); + $cached = get_site_transient( $cache_key ); + + if ( is_array( $cached ) ) { + return $cached; + } + + $repo = $this->parse_repo_url( $repo_url ); + if ( empty( $repo ) ) { + return array(); + } + + $headers = array( + 'Accept' => 'application/json', + 'User-Agent' => 'KGV-Updater/1.0', + ); + + $token = trim( (string) get_option( self::OPTION_TOKEN, '' ) ); + if ( '' !== $token ) { + $headers['Authorization'] = 'token ' . $token; + } + + $release_api = sprintf( + '%s/api/v1/repos/%s/%s/releases/latest', + $repo['origin'], + rawurlencode( $repo['owner'] ), + rawurlencode( $repo['name'] ) + ); + + $response = wp_remote_get( + $release_api, + array( + 'timeout' => 12, + 'headers' => $headers, + ) + ); + + $tag = ''; + if ( ! is_wp_error( $response ) && 200 === (int) wp_remote_retrieve_response_code( $response ) ) { + $body = json_decode( wp_remote_retrieve_body( $response ), true ); + $tag = isset( $body['tag_name'] ) ? (string) $body['tag_name'] : ''; + } + + if ( '' === $tag ) { + $tags_api = sprintf( + '%s/api/v1/repos/%s/%s/tags?page=1&limit=1', + $repo['origin'], + rawurlencode( $repo['owner'] ), + rawurlencode( $repo['name'] ) + ); + + $tag_response = wp_remote_get( + $tags_api, + array( + 'timeout' => 12, + 'headers' => $headers, + ) + ); + + if ( ! is_wp_error( $tag_response ) && 200 === (int) wp_remote_retrieve_response_code( $tag_response ) ) { + $body = json_decode( wp_remote_retrieve_body( $tag_response ), true ); + if ( is_array( $body ) && ! empty( $body[0]['name'] ) ) { + $tag = (string) $body[0]['name']; + } + } + } + + if ( '' === $tag ) { + return array(); + } + + $data = array( + 'version' => ltrim( $tag, 'vV' ), + 'tag' => $tag, + 'package' => sprintf( + '%s/%s/%s/archive/%s.zip', + $repo['origin'], + $repo['owner'], + $repo['name'], + rawurlencode( $tag ) + ), + ); + + set_site_transient( $cache_key, $data, HOUR_IN_SECONDS ); + + return $data; + } + + private function parse_repo_url( $repo_url ) { + $parts = wp_parse_url( $repo_url ); + if ( empty( $parts['host'] ) || empty( $parts['path'] ) ) { + return array(); + } + + $path = trim( $parts['path'], '/' ); + $bits = explode( '/', $path ); + if ( count( $bits ) < 2 ) { + return array(); + } + + $owner = $bits[0]; + $name = preg_replace( '/\.git$/', '', $bits[1] ); + $scheme = ! empty( $parts['scheme'] ) ? $parts['scheme'] : 'https'; + + return array( + 'origin' => $scheme . '://' . $parts['host'], + 'owner' => $owner, + 'name' => $name, + ); + } + + private function get_gitea_host() { + $host = trim( (string) get_option( self::OPTION_HOST, 'git.apex-project.de' ) ); + return '' !== $host ? $host : 'git.apex-project.de'; + } +} + +KGV_Updater::instance(); diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..cd6bd9a --- /dev/null +++ b/readme.txt @@ -0,0 +1,16 @@ +KGV Updater - WordPress Plugin + +Beschreibung: +KGV Updater prueft KGV-Plugins mit Update URI gegen Gitea-Repositories und stellt Updates im WordPress-Backend bereit. + +Voraussetzung: +- Plugins besitzen eine gueltige `Update URI` auf dem Gitea-Server. + +Installation: +1. Plugin in `wp-content/plugins/KGV-Updater/` ablegen +2. In WordPress aktivieren +3. Unter `Einstellungen > KGV Updater` optional Host/Token eintragen + +Hinweis: +- Fuer private Repositories wird ein Gitea Token benoetigt. +- Die Pruefergebnisse werden kurzfristig gecacht.