is_implemented() ) { return new \WP_Error( 'forwp_weather_provider_not_implemented', __( 'This weather provider is not implemented yet.', '4wp-weather' ) ); } if ( ! $provider->is_ready() ) { return new \WP_Error( 'forwp_weather_not_configured', __( 'Weather provider is not configured.', '4wp-weather' ) ); } $query = null !== $location_query ? trim( $location_query ) : ''; $query = '' !== $query ? $query : null; $key = $this->build_cache_key( $provider_slug, $latitude, $longitude, $query ); $cached = get_transient( $key ); if ( false !== $cached && is_array( $cached ) ) { return $cached; } $result = $provider->fetch_current( $latitude, $longitude, $query ); if ( is_wp_error( $result ) ) { return $result; } if ( ! is_array( $result ) ) { return new \WP_Error( 'forwp_weather_bad_response', __( 'Unable to load weather data.', '4wp-weather' ) ); } set_transient( $key, $result, self::CACHE_TTL ); $this->remember_cache_key( $key ); return $result; } /** * Build transient name for provider + coordinates. * * @param string $provider_slug Provider slug. * @param float $latitude Latitude. * @param float $longitude Longitude. * @param string|null $location_query Non-null non-empty string keys cache by place name. */ private function build_cache_key( string $provider_slug, float $latitude, float $longitude, ?string $location_query = null ): string { if ( null !== $location_query && '' !== $location_query ) { $fingerprint = wp_json_encode( array( 'p' => $provider_slug, 'q' => strtolower( $location_query ), ) ); } else { $fingerprint = wp_json_encode( array( 'p' => $provider_slug, 'lat' => round( $latitude, 4 ), 'lon' => round( $longitude, 4 ), ) ); } return self::TRANSIENT_PREFIX . md5( (string) $fingerprint ); } /** * Track transient keys for CLI flush. * * @param string $transient_key Transient key. */ private function remember_cache_key( string $transient_key ): void { $keys = get_option( self::REGISTRY_OPTION, array() ); $keys = is_array( $keys ) ? $keys : array(); $keys[] = $transient_key; $keys = array_values( array_unique( array_filter( $keys ) ) ); update_option( self::REGISTRY_OPTION, $keys, false ); } /** * Delete all plugin weather transients. * * @return int Number of deleted transients. */ public static function flush_all_caches(): int { $keys = get_option( self::REGISTRY_OPTION, array() ); $keys = is_array( $keys ) ? $keys : array(); $count = 0; foreach ( $keys as $key ) { if ( is_string( $key ) && '' !== $key ) { delete_transient( $key ); ++$count; } } delete_option( self::REGISTRY_OPTION ); return $count; } }