From 535dbda6b48171f8115b455e54790de94d97d42a Mon Sep 17 00:00:00 2001 From: Murilo Ijanc Date: Sun, 26 Jul 2026 16:41:48 -0300 Subject: Initial import --- includes/class-cepis-woo-lookup.php | 170 ++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 includes/class-cepis-woo-lookup.php (limited to 'includes/class-cepis-woo-lookup.php') diff --git a/includes/class-cepis-woo-lookup.php b/includes/class-cepis-woo-lookup.php new file mode 100644 index 0000000..47e3f16 --- /dev/null +++ b/includes/class-cepis-woo-lookup.php @@ -0,0 +1,170 @@ +, retry_after:?int} + */ + public static function resolve( string $cep ): array { + $cached = get_transient( self::CACHE_PREFIX . $cep ); + + if ( is_array( $cached ) ) { + return isset( $cached['miss'] ) + ? self::not_found() + : array( + 'status' => 200, + 'body' => $cached, + 'retry_after' => null, + ); + } + + try { + $address = self::client()->lookup( $cep ); + } catch ( Cepis\CepNotFoundException ) { + set_transient( self::CACHE_PREFIX . $cep, array( 'miss' => true ), self::MISS_TTL ); + + return self::not_found(); + } catch ( Cepis\InvalidCepException ) { + return array( + 'status' => 400, + 'body' => array( + 'erro' => 'cep_invalido', + 'mensagem' => 'CEP deve ter 8 dígitos', + ), + 'retry_after' => null, + ); + } catch ( Cepis\RateLimitedException $e ) { + return array( + 'status' => 429, + 'body' => array( + 'erro' => 'limite', + 'mensagem' => 'Muitas consultas em pouco tempo', + ), + 'retry_after' => null === $e->retryAfter ? null : (int) $e->retryAfter, + ); + } catch ( Cepis\CepisException ) { + return array( + 'status' => 502, + 'body' => array( + 'erro' => 'interno', + 'mensagem' => 'falha interna', + ), + 'retry_after' => null, + ); + } + + $body = $address->raw; + set_transient( self::CACHE_PREFIX . $cep, $body, self::HIT_TTL ); + + return array( + 'status' => 200, + 'body' => $body, + 'retry_after' => null, + ); + } + + /** + * Drop every cached answer. + * + * Used by the settings screen when the API root changes, since answers from + * one instance say nothing about another. + */ + public static function flush(): void { + global $wpdb; + + $like = $wpdb->esc_like( '_transient_' . self::CACHE_PREFIX ) . '%'; + + $names = $wpdb->get_col( + $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", $like ) + ); + + foreach ( (array) $names as $name ) { + delete_transient( substr( (string) $name, strlen( '_transient_' ) ) ); + } + } + + /** + * The client, built once per request. + */ + private static function client(): Cepis\Client { + static $client = null; + + if ( null === $client ) { + $client = new Cepis\Client( + baseUrl: Cepis_Woo_Options::base_url(), + timeout: 5.0, + maxAttempts: 2, + totalTimeout: 8.0, + userAgent: 'cepis-woocommerce/' . CEPIS_WOO_VERSION . ' (+https://cep.is)', + transport: new Cepis_Woo_Transport(), + ); + } + + return $client; + } + + /** + * The API's own 404 body, reproduced so the browser cannot tell the two + * modes apart. + * + * @return array{status:int, body:array, retry_after:?int} + */ + private static function not_found(): array { + return array( + 'status' => 404, + 'body' => array( + 'erro' => 'cep_nao_encontrado', + 'mensagem' => 'CEP não existe na base do DNE', + ), + 'retry_after' => null, + ); + } +} -- cgit v1.3