From cb0308e7e42a26a95eedec427b70040d7976e50b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 24 Dec 2025 16:54:32 +0000 Subject: [PATCH 1/4] Handle a `WP_Error` instance passed through the `upgrader_source_selection` filter. Signed-off-by: John Blackbourn --- inc/packages/namespace.php | 2 +- inc/updater/class-lite.php | 15 ++++++++++----- inc/updater/class-updater.php | 10 ++++++++-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/inc/packages/namespace.php b/inc/packages/namespace.php index 9733ae4f..95d38622 100644 --- a/inc/packages/namespace.php +++ b/inc/packages/namespace.php @@ -754,7 +754,7 @@ function delete_cached_did_for_install(): void { * * This is commonly required for packages from Git hosts. * - * @param string $source Path of $source. + * @param string|WP_Error $source Path of $source, or a WP_Error object. * @param string $remote_source Path of $remote_source. * @param WP_Upgrader $upgrader An Upgrader object. * @param array $hook_extra Array of hook data. diff --git a/inc/updater/class-lite.php b/inc/updater/class-lite.php index ca54e93a..670d956f 100644 --- a/inc/updater/class-lite.php +++ b/inc/updater/class-lite.php @@ -178,18 +178,23 @@ function () { /** * Correctly rename dependency for activation. * - * @param string $source Path of $source. - * @param string $remote_source Path of $remote_source. - * @param WP_Upgrader $upgrader An Upgrader object. - * @param array $hook_extra Array of hook data. + * @param string|WP_Error $source Path of $source, or a WP_Error object. + * @param string $remote_source Path of $remote_source. + * @param WP_Upgrader $upgrader An Upgrader object. + * @param array $hook_extra Array of hook data. * * @throws TypeError If the type of $upgrader is not correct. * * @return string|WP_Error */ - public function upgrader_source_selection( string $source, string $remote_source, WP_Upgrader $upgrader, $hook_extra = null ) { + public function upgrader_source_selection( $source, string $remote_source, WP_Upgrader $upgrader, $hook_extra = null ) { global $wp_filesystem; + // Exit early for errors. + if ( is_wp_error( $source ) ) { + return $source; + } + $new_source = $source; // Exit if installing. diff --git a/inc/updater/class-updater.php b/inc/updater/class-updater.php index aa6f415b..611f6417 100644 --- a/inc/updater/class-updater.php +++ b/inc/updater/class-updater.php @@ -12,6 +12,7 @@ use stdClass; use Theme_Upgrader; use TypeError; +use WP_Error; use WP_Upgrader; /** @@ -149,7 +150,7 @@ public function load_hooks() { /** * Correctly rename dependency for activation. * - * @param string $source Path of $source. + * @param string|WP_Error $source Path of $source, or a WP_Error object. * @param string $remote_source Path of $remote_source. * @param WP_Upgrader $upgrader An Upgrader object. * @param array $hook_extra Array of hook data. @@ -158,9 +159,14 @@ public function load_hooks() { * * @return string|WP_Error */ - public function upgrader_source_selection( string $source, string $remote_source, WP_Upgrader $upgrader, $hook_extra = null ) { + public function upgrader_source_selection( $source, string $remote_source, WP_Upgrader $upgrader, $hook_extra = null ) { global $wp_filesystem; + // Exit early for errors. + if ( is_wp_error( $source ) ) { + return $source; + } + $new_source = $source; // Exit if installing. From 3ee205f81b9d8bcd52abb187567c70bb9ede255b Mon Sep 17 00:00:00 2001 From: Andy Fragen Date: Thu, 25 Dec 2025 15:47:02 -0400 Subject: [PATCH 2/4] Update transient timeout handling in class-lite.php Replaced static transient timeout with a filter-based timeout. Signed-off-by: Andy Fragen --- inc/updater/class-lite.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/inc/updater/class-lite.php b/inc/updater/class-lite.php index 670d956f..bec7adc2 100644 --- a/inc/updater/class-lite.php +++ b/inc/updater/class-lite.php @@ -136,11 +136,9 @@ public function run() { } $this->api_data->file = $this->file; - /* - * Set transient for 5 minutes as AWS sets 5 minute timeout - * for release asset redirect. - */ - set_site_transient( "git-updater-lite_{$this->file}", $this->api_data, 5 * \MINUTE_IN_SECONDS ); + // Set timeout for transient via filter. + $timeout = apply_filters( 'git_updater_lite_transient_timeout', 6 * HOUR_IN_SECONDS, $this->api_data ); + set_site_transient( "git-updater-lite_{$this->file}", $this->api_data, $timeout ); } else { if ( property_exists( $response, 'error' ) ) { return new WP_Error( 'repo-no-exist', 'Specified repo does not exist' ); From 039e287a983dd2f60debf4567cd056db34c21bed Mon Sep 17 00:00:00 2001 From: Andy Fragen Date: Fri, 26 Dec 2025 12:05:17 -0400 Subject: [PATCH 3/4] Pass $this->file as parmeter Allows for easier testing if changing timeout per package. Signed-off-by: Andy Fragen --- inc/updater/class-lite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/updater/class-lite.php b/inc/updater/class-lite.php index bec7adc2..0d3752f4 100644 --- a/inc/updater/class-lite.php +++ b/inc/updater/class-lite.php @@ -137,7 +137,7 @@ public function run() { $this->api_data->file = $this->file; // Set timeout for transient via filter. - $timeout = apply_filters( 'git_updater_lite_transient_timeout', 6 * HOUR_IN_SECONDS, $this->api_data ); + $timeout = apply_filters( 'git_updater_lite_transient_timeout', 6 * HOUR_IN_SECONDS, $this->file ); set_site_transient( "git-updater-lite_{$this->file}", $this->api_data, $timeout ); } else { if ( property_exists( $response, 'error' ) ) { From e9bc53e419cb67205dfa0a37949b12e714295623 Mon Sep 17 00:00:00 2001 From: Andy Fragen Date: Wed, 31 Dec 2025 18:47:19 -0800 Subject: [PATCH 4/4] Add filter for API URL to support pre-release versions Added a filter to modify the API URL for updates, allowing for pre-release versions. Signed-off-by: Andy Fragen --- inc/updater/class-lite.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/inc/updater/class-lite.php b/inc/updater/class-lite.php index 0d3752f4..c9c67ebb 100644 --- a/inc/updater/class-lite.php +++ b/inc/updater/class-lite.php @@ -125,6 +125,13 @@ public function run() { ); $response = get_site_transient( "git-updater-lite_{$this->file}" ); if ( ! $response ) { + /* Apply filter to API URL. + * Add `channel=development` query arg to URL to get pre-release versions. + * + * @param string $url The API URL. + * @param string $slug The plugin/theme slug + */ + $url = apply_filters( 'git_updater_lite_api_url', $url, $this->slug ); $response = wp_remote_get( $url ); if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 404 ) { return $response;