Initial plugin commit
This commit is contained in:
322
kgv-updater.php
Normal file
322
kgv-updater.php
Normal file
@@ -0,0 +1,322 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: KGV Updater
|
||||
* Plugin URI: https://apex-project.de/
|
||||
* Description: Aktualisiert KGV-Plugins direkt aus den Gitea-Repositories.
|
||||
* Version: 1.0.0
|
||||
* Author: Ronny Grobel
|
||||
* Text Domain: kgv-updater
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
final class KGV_Updater {
|
||||
const OPTION_TOKEN = 'kgv_updater_gitea_token';
|
||||
const OPTION_HOST = 'kgv_updater_gitea_host';
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function __construct() {
|
||||
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'inject_updates' ) );
|
||||
add_filter( 'plugins_api', array( $this, 'plugins_api' ), 10, 3 );
|
||||
add_action( 'admin_menu', array( $this, 'register_settings_page' ) );
|
||||
add_action( 'admin_init', array( $this, 'register_settings' ) );
|
||||
}
|
||||
|
||||
public function register_settings() {
|
||||
register_setting(
|
||||
'kgv_updater_settings',
|
||||
self::OPTION_TOKEN,
|
||||
array(
|
||||
'type' => '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;
|
||||
}
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1>KGV Updater</h1>
|
||||
<p>Prueft KGV-Plugins mit <code>Update URI</code> auf neue Versionen in Gitea.</p>
|
||||
<form method="post" action="options.php">
|
||||
<?php settings_fields( 'kgv_updater_settings' ); ?>
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><label for="kgv_updater_gitea_host">Gitea Host</label></th>
|
||||
<td>
|
||||
<input type="text" id="kgv_updater_gitea_host" name="<?php echo esc_attr( self::OPTION_HOST ); ?>" value="<?php echo esc_attr( $this->get_gitea_host() ); ?>" class="regular-text" />
|
||||
<p class="description">Standard: <code>git.apex-project.de</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="kgv_updater_gitea_token">Gitea Token</label></th>
|
||||
<td>
|
||||
<input type="password" id="kgv_updater_gitea_token" name="<?php echo esc_attr( self::OPTION_TOKEN ); ?>" value="<?php echo esc_attr( get_option( self::OPTION_TOKEN, '' ) ); ?>" class="regular-text" autocomplete="new-password" />
|
||||
<p class="description">Nur noetig fuer private Repositories.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php submit_button(); ?>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function inject_updates( $transient ) {
|
||||
if ( empty( $transient->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();
|
||||
Reference in New Issue
Block a user