From 94a7670c808e46e09ad42955baa3d240944959b7 Mon Sep 17 00:00:00 2001 From: Yuri Karamian Date: Sun, 25 Jan 2026 23:11:41 +0100 Subject: [PATCH] v1.0 --- update-info.json | 11 ++ .../includes/class-wpsp-updater.php | 178 ++++++++++++++++++ wp-security-pack/wp-security-pack.php | 4 +- 3 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 update-info.json create mode 100644 wp-security-pack/includes/class-wpsp-updater.php diff --git a/update-info.json b/update-info.json new file mode 100644 index 0000000..f0fe430 --- /dev/null +++ b/update-info.json @@ -0,0 +1,11 @@ +{ + "name": "WP Security Pack", + "version": "1.0", + "download_url": "https://codeberg.org/ArkHost/WP-Security-Pack/archive/v1.0.zip", + "homepage": "https://codeberg.org/ArkHost/WP-Security-Pack", + "description": "WordPress security without the nonsense. No upsells, no premium tier, no fake threat counters.", + "changelog": "

1.0

", + "requires": "5.0", + "tested": "6.9", + "requires_php": "7.4" +} diff --git a/wp-security-pack/includes/class-wpsp-updater.php b/wp-security-pack/includes/class-wpsp-updater.php new file mode 100644 index 0000000..38c9446 --- /dev/null +++ b/wp-security-pack/includes/class-wpsp-updater.php @@ -0,0 +1,178 @@ +checked ) ) { + return $transient; + } + + $remote = $this->get_remote_info(); + if ( ! $remote ) { + return $transient; + } + + $current_version = WPSP_VERSION; + if ( version_compare( $current_version, $remote->version, '<' ) ) { + $transient->response[ WPSP_PLUGIN_BASENAME ] = (object) array( + 'slug' => self::SLUG, + 'plugin' => WPSP_PLUGIN_BASENAME, + 'new_version' => $remote->version, + 'url' => $remote->homepage ?? 'https://codeberg.org/ArkHost/WP-Security-Pack', + 'package' => $remote->download_url, + 'icons' => array(), + 'banners' => array(), + ); + } + + return $transient; + } + + /** + * Plugin info for the update screen. + * + * @param false|object|array $result Result. + * @param string $action API action. + * @param object $args Arguments. + * @return false|object + */ + public function plugin_info( $result, $action, $args ) { + if ( 'plugin_information' !== $action || self::SLUG !== ( $args->slug ?? '' ) ) { + return $result; + } + + $remote = $this->get_remote_info(); + if ( ! $remote ) { + return $result; + } + + return (object) array( + 'name' => $remote->name ?? 'WP Security Pack', + 'slug' => self::SLUG, + 'version' => $remote->version, + 'author' => 'ArkHost', + 'homepage' => $remote->homepage ?? 'https://codeberg.org/ArkHost/WP-Security-Pack', + 'download_link' => $remote->download_url, + 'sections' => array( + 'description' => $remote->description ?? 'WordPress security without the nonsense.', + 'changelog' => $remote->changelog ?? '', + ), + 'requires' => $remote->requires ?? '5.0', + 'tested' => $remote->tested ?? '6.9', + 'requires_php' => $remote->requires_php ?? '7.4', + ); + } + + /** + * Fix folder name after download. + * Codeberg archives use "WP-Security-Pack" but we need "wp-security-pack". + * + * @param string $source Source path. + * @param string $remote_source Remote source path. + * @param WP_Upgrader $upgrader Upgrader instance. + * @param array $args Extra arguments. + * @return string|WP_Error + */ + public function fix_folder_name( $source, $remote_source, $upgrader, $args ) { + global $wp_filesystem; + + // Only process our plugin. + if ( ! isset( $args['plugin'] ) || WPSP_PLUGIN_BASENAME !== $args['plugin'] ) { + return $source; + } + + $correct_name = self::SLUG; + $new_source = trailingslashit( $remote_source ) . $correct_name . '/'; + + // If source already correct, return as is. + if ( trailingslashit( $source ) === $new_source ) { + return $source; + } + + // Rename folder. + if ( $wp_filesystem->move( $source, $new_source ) ) { + return $new_source; + } + + return new WP_Error( 'rename_failed', 'Could not rename plugin folder.' ); + } + + /** + * Get remote update info. + * + * @return object|false + */ + private function get_remote_info() { + $cached = get_transient( self::CACHE_KEY ); + if ( false !== $cached ) { + return $cached; + } + + $response = wp_remote_get( self::UPDATE_URL, array( + 'timeout' => 10, + 'headers' => array( 'Accept' => 'application/json' ), + ) ); + + if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { + // Cache failure for 1 hour to avoid hammering. + set_transient( self::CACHE_KEY, false, HOUR_IN_SECONDS ); + return false; + } + + $body = wp_remote_retrieve_body( $response ); + $data = json_decode( $body ); + + if ( ! $data || empty( $data->version ) ) { + set_transient( self::CACHE_KEY, false, HOUR_IN_SECONDS ); + return false; + } + + // Cache for 12 hours. + set_transient( self::CACHE_KEY, $data, 12 * HOUR_IN_SECONDS ); + + return $data; + } +} diff --git a/wp-security-pack/wp-security-pack.php b/wp-security-pack/wp-security-pack.php index 058e708..d01cef4 100644 --- a/wp-security-pack/wp-security-pack.php +++ b/wp-security-pack/wp-security-pack.php @@ -83,6 +83,7 @@ final class WP_Security_Pack { if ( is_admin() ) { require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-admin.php'; + require_once WPSP_PLUGIN_DIR . 'includes/class-wpsp-updater.php'; } } @@ -136,7 +137,8 @@ final class WP_Security_Pack { $this->components['login_protection'] = new WPSP_Login_Protection(); if ( is_admin() ) { - $this->components['admin'] = new WPSP_Admin(); + $this->components['admin'] = new WPSP_Admin(); + $this->components['updater'] = new WPSP_Updater(); } }