This commit is contained in:
Javier Casares 2026-03-28 07:59:52 +00:00
commit ddaaff71ad
23 changed files with 879 additions and 798 deletions

View file

@ -60,7 +60,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
/**
* Plugin headers.
*
* @var array
* @var array<string, mixed>
*/
private array $plugin_data;
@ -105,7 +105,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
/**
* Get plugin headers.
*
* @return array Plugin data.
* @return array<string, mixed> Plugin data.
*/
private function get_plugin_data(): array {
if ( ! function_exists( 'get_plugin_data' ) ) {
@ -125,7 +125,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
*/
private function build_json_url(): string {
// Try Gitea Plugin URI (format: "OWNER/REPO" or full URL).
if ( ! empty( $this->plugin_data['Gitea Plugin URI'] ) ) {
if ( ! empty( $this->plugin_data['Gitea Plugin URI'] ) && is_string( $this->plugin_data['Gitea Plugin URI'] ) ) {
$gitea_uri = $this->plugin_data['Gitea Plugin URI'];
// If it's already a full URL, use it.
@ -141,7 +141,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
}
// Fallback: try to extract from Plugin URI.
if ( ! empty( $this->plugin_data['PluginURI'] ) ) {
if ( ! empty( $this->plugin_data['PluginURI'] ) && is_string( $this->plugin_data['PluginURI'] ) ) {
$plugin_uri = $this->plugin_data['PluginURI'];
if ( str_contains( $plugin_uri, 'git.robotstxt.es' ) ) {
return rtrim( $plugin_uri, '/' ) . '/raw/branch/main/update.json';
@ -160,7 +160,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
* @return object The modified transient.
*/
public function inject_update_info( $transient ) {
if ( ! is_object( $transient ) ) {
if ( ! ( $transient instanceof stdClass ) ) {
$transient = new stdClass();
}
@ -183,7 +183,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
return $transient;
}
if ( version_compare( $remote['version'], $current_version, '>' ) ) {
if ( is_string( $current_version ) && is_string( $remote['version'] ) && version_compare( $remote['version'], $current_version, '>' ) ) {
$update = (object) array(
'slug' => $remote['slug'] ?? $this->plugin_slug,
'plugin' => $this->plugin_basename,
@ -204,11 +204,11 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
/**
* Provide "View details" modal content.
*
* @param false|object|array $result The result object or array.
* @param string $action The type of information being requested.
* @param object $args Plugin API arguments.
* @param false|object|array<string, mixed> $result The result object or array.
* @param string $action The type of information being requested.
* @param object $args Plugin API arguments.
*
* @return false|object The plugin information object or false.
* @return false|object|array<string, mixed> The plugin information object or false.
*/
public function provide_plugin_details( $result, string $action, object $args ) {
if ( 'plugin_information' !== $action ) {
@ -245,7 +245,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
/**
* Get remote data with caching and HMAC signature verification.
*
* @return array Remote data.
* @return array<string, mixed> Remote data.
*/
private function get_remote_data(): array {
$cached = get_site_transient( $this->cache_key );
@ -255,7 +255,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
if ( is_array( $cached ) && isset( $cached['signature'], $cached['data'] ) ) {
$expected_sig = hash_hmac( 'sha256', $this->cache_key . serialize( $cached['data'] ), AUTH_SALT );
if ( hash_equals( $expected_sig, $cached['signature'] ) ) {
if ( is_string( $cached['signature'] ) && hash_equals( $expected_sig, $cached['signature'] ) ) {
// Signature valid, return data.
return is_array( $cached['data'] ) ? $cached['data'] : array();
}
@ -283,7 +283,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
set_site_transient( $this->cache_key, $remote ?: array(), 6 * HOUR_IN_SECONDS );
}
return is_array( $remote ) ? $remote : array();
return $remote;
}
// Legacy cache format without signature (backward compatibility).
@ -293,7 +293,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
/**
* Fetch JSON from remote URL.
*
* @return array Decoded JSON data.
* @return array<string, mixed> Decoded JSON data.
*/
private function fetch_json(): array {
$response = wp_remote_get(
@ -324,18 +324,18 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
/**
* Check compatibility.
*
* @param array $remote Remote data.
* @param array<string, mixed> $remote Remote data.
*
* @return bool True if compatible.
*/
private function is_compatible( array $remote ): bool {
if ( ! empty( $remote['requires_php'] ) ) {
if ( ! empty( $remote['requires_php'] ) && is_string( $remote['requires_php'] ) ) {
if ( version_compare( PHP_VERSION, $remote['requires_php'], '<' ) ) {
return false;
}
}
if ( ! empty( $remote['requires'] ) ) {
if ( ! empty( $remote['requires'] ) && is_string( $remote['requires'] ) ) {
if ( version_compare( get_bloginfo( 'version' ), $remote['requires'], '<' ) ) {
return false;
}
@ -355,7 +355,7 @@ if ( ! class_exists( 'Robotstxt_Updater' ) ) {
}
// This is a cache clear request - now verify nonce.
$nonce_raw = filter_input( INPUT_GET, '_wpnonce', FILTER_UNSAFE_RAW );
$nonce_raw = filter_input( INPUT_GET, '_wpnonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
$nonce = $nonce_raw ? sanitize_text_field( wp_unslash( $nonce_raw ) ) : '';
if ( ! wp_verify_nonce( $nonce, 'robotstxt_clear_update_cache' ) ) {