16 ) { return false; } $pattern = self::pattern( $country ); if ( '' === $pattern ) { // Pays non listé : au moins un chiffre, 3–12 caractères utiles. return (bool) preg_match( '/^(?=.*\d)[A-Za-z0-9][A-Za-z0-9\s\-]{1,11}$/', $postcode ); } return (bool) preg_match( '/' . $pattern . '/u', $postcode ); } /** * Regex sans délimiteurs (pour attribut HTML pattern aussi). * * @param string $country ISO country. * @return string */ public static function pattern( $country ) { $country = strtoupper( sanitize_key( (string) $country ) ); $map = array( 'FR' => '^\d{5}$', 'BE' => '^\d{4}$', 'CH' => '^\d{4}$', 'LU' => '^\d{4}$', 'AT' => '^\d{4}$', 'DE' => '^\d{5}$', 'ES' => '^\d{5}$', 'IT' => '^\d{5}$', 'PT' => '^\d{4}(?:[-\s]?\d{3})?$', 'NL' => '^\d{4}\s?[A-Za-z]{2}$', 'PL' => '^\d{2}-\d{3}$', 'SE' => '^\d{3}\s?\d{2}$', 'DK' => '^\d{4}$', 'NO' => '^\d{4}$', 'FI' => '^\d{5}$', 'IE' => '^[A-Za-z0-9]{3}\s?[A-Za-z0-9]{4}$', 'GB' => '^[A-Za-z]{1,2}\d[A-Za-z\d]?\s?\d[A-Za-z]{2}$', 'US' => '^\d{5}(?:-?\d{4})?$', 'CA' => '^[A-Za-z]\d[A-Za-z]\s?\d[A-Za-z]\d$', ); /** * @param string $pattern Country regex without delimiters. * @param string $country ISO country. */ return (string) apply_filters( 'torlann_postcode_pattern', $map[ $country ] ?? '', $country ); } /** * Exemple affiché (placeholder / message d’erreur). * * @param string $country ISO country. * @return string */ public static function example( $country ) { $country = strtoupper( sanitize_key( (string) $country ) ); $map = array( 'FR' => '75002', 'BE' => '1000', 'CH' => '8001', 'LU' => '2340', 'AT' => '1010', 'DE' => '10115', 'ES' => '28013', 'IT' => '20121', 'PT' => '1100-053', 'NL' => '1012 PH', 'PL' => '00-001', 'SE' => '111 22', 'DK' => '1050', 'NO' => '0150', 'FI' => '00100', 'IE' => 'D02 AF30', 'GB' => 'SW1A 1AA', 'US' => '10001', 'CA' => 'H2X 1Y4', ); return (string) ( $map[ $country ] ?? '' ); } /** * Payload JS (pattern + example par pays). * * @return array */ public static function js_map() { $countries = array( 'FR', 'BE', 'CH', 'LU', 'AT', 'DE', 'ES', 'IT', 'PT', 'NL', 'PL', 'SE', 'DK', 'NO', 'FI', 'IE', 'GB', 'US', 'CA' ); $out = array(); foreach ( $countries as $code ) { $out[ $code ] = array( 'pattern' => self::pattern( $code ), 'example' => self::example( $code ), ); } return $out; } /** * @param string $postcode Raw. * @return string */ public static function normalize( $postcode ) { $postcode = trim( (string) $postcode ); $postcode = preg_replace( '/\s+/', ' ', $postcode ); return is_string( $postcode ) ? $postcode : ''; } }