From 83be388186c1f59169cf6f818763d4c79c13380c Mon Sep 17 00:00:00 2001 From: James Griffin Date: Thu, 23 Jul 2026 11:14:44 -0300 Subject: [PATCH] Point plugin metadata links at Unsupervised and Gitea Make the "By Unsupervised" author link go to https://unsupervised.ca (via a new Author URI header) and the plugin site / "View details" link point at the Gitea project instead of WordPress.org. Core's "View details" link opened a thickbox iframe against the WordPress.org plugin-information API, which 404s ("Plugin not found") for this off-directory plugin. A plugin_row_meta filter now replaces it with a new-tab link to the matching Gitea release tag page; embedding Gitea in the iframe is blocked by its X-Frame-Options anyway. Co-Authored-By: Claude Opus 4.8 --- src/Update/UpdateChecker.php | 37 +++++++++++++++++++++++++ tests/Unit/Update/UpdateCheckerTest.php | 35 +++++++++++++++++++++++ unsupervised-schedular.php | 3 +- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/Update/UpdateChecker.php b/src/Update/UpdateChecker.php index 0e61430..1d5ac80 100644 --- a/src/Update/UpdateChecker.php +++ b/src/Update/UpdateChecker.php @@ -35,6 +35,43 @@ class UpdateChecker { public function register(): void { add_filter( 'update_plugins_' . self::HOSTNAME, [ $this, 'provideUpdate' ], 10, 3 ); + add_filter( 'plugin_row_meta', [ $this, 'filterRowMeta' ], 10, 2 ); + } + + /** + * Replace core's "View details" link on the Plugins screen. + * + * Core points that link at the WordPress.org plugin-information API + * (`plugin-install.php?tab=plugin-information&plugin=…`), which 404s in a + * "Plugin not found" iframe for this off-directory plugin. We swap it for a + * direct link to the matching Gitea release tag page, opened in a new tab — + * embedding Gitea in the thickbox iframe would be blocked by its + * `X-Frame-Options: SAMEORIGIN` anyway. + * + * @param mixed $meta Row-meta links for the plugin. + * @param mixed $plugin_file Plugin file the meta belongs to. + * @return mixed The (possibly modified) row-meta array. + */ + public function filterRowMeta( mixed $meta, mixed $plugin_file ): mixed { + if ( ! is_array( $meta ) || plugin_basename( USC_PLUGIN_FILE ) !== $plugin_file ) { + return $meta; + } + + // Drop core's WordPress.org "View details" thickbox link. + $meta = array_values( + array_filter( + $meta, + static fn( $item ): bool => ! ( is_string( $item ) && str_contains( $item, 'open-plugin-details-modal' ) ) + ) + ); + + $meta[] = sprintf( + '%s', + esc_url( self::REPO_URL . '/releases/tag/v' . USC_VERSION ), + esc_html__( 'View details', 'unsupervised-schedular' ) + ); + + return $meta; } /** diff --git a/tests/Unit/Update/UpdateCheckerTest.php b/tests/Unit/Update/UpdateCheckerTest.php index 8bf0981..457b885 100644 --- a/tests/Unit/Update/UpdateCheckerTest.php +++ b/tests/Unit/Update/UpdateCheckerTest.php @@ -35,10 +35,45 @@ class UpdateCheckerTest extends TestCase public function testRegisterHooksHostnameFilter(): void { Filters\expectAdded('update_plugins_git.unsupervised.ca')->once(); + Filters\expectAdded('plugin_row_meta')->once(); (new UpdateChecker())->register(); } + public function testFilterRowMetaReplacesViewDetailsLinkForThisPlugin(): void + { + Functions\when('plugin_basename')->justReturn(self::PLUGIN_FILE); + + $meta = [ + 'Version 1.0.0', + 'View details', + ]; + + $result = (new UpdateChecker())->filterRowMeta($meta, self::PLUGIN_FILE); + + // Core's thickbox modal link is gone. + foreach ($result as $item) { + self::assertStringNotContainsString('open-plugin-details-modal', $item); + } + // Replaced with a new-tab link to the Gitea release tag for USC_VERSION (1.0.0 in tests). + self::assertStringContainsString( + UpdateChecker::REPO_URL . '/releases/tag/v1.0.0', + end($result) + ); + self::assertStringContainsString('target="_blank"', end($result)); + } + + public function testFilterRowMetaLeavesOtherPluginsUntouched(): void + { + Functions\when('plugin_basename')->justReturn(self::PLUGIN_FILE); + + $meta = ['View details']; + + $result = (new UpdateChecker())->filterRowMeta($meta, 'other-plugin/other-plugin.php'); + + self::assertSame($meta, $result); + } + public function testOffersUpdateWhenReleaseIsNewer(): void { Functions\when('plugin_basename')->justReturn(self::PLUGIN_FILE); diff --git a/unsupervised-schedular.php b/unsupervised-schedular.php index 118bd55..08c0696 100644 --- a/unsupervised-schedular.php +++ b/unsupervised-schedular.php @@ -1,12 +1,13 @@