class-wc-validation.php 4.96 KB
Newer Older
imac's avatar
imac committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

/**
 * Contains Validation functions
 *
 * @class    WC_Validation
 * @version  2.4.0
 * @package  WooCommerce/Classes
 * @category Class
 * @author   WooThemes
 */
class WC_Validation {

	/**
	 * Validates an email using WordPress native is_email function.
	 *
	 * @param   string	$email Email address to validate.
	 * @return  bool
	 */
	public static function is_email( $email ) {
		return is_email( $email );
	}

	/**
	 * Validates a phone number using a regular expression.
	 *
	 * @param   string	$phone Phone number to validate.
	 * @return  bool
	 */
	public static function is_phone( $phone ) {
		if ( 0 < strlen( trim( preg_replace( '/[\s\#0-9_\-\+\/\(\)]/', '', $phone ) ) ) ) {
			return false;
		}

		return true;
	}

	/**
	 * Checks for a valid postcode.
	 *
	 * @param   string	$postcode Postcode to validate.
	 * @param	string	$country Country to validate the postcode for.
	 * @return  bool
	 */
	public static function is_postcode( $postcode, $country ) {
		if ( strlen( trim( preg_replace( '/[\s\-A-Za-z0-9]/', '', $postcode ) ) ) > 0 ) {
			return false;
		}

		switch ( $country ) {
			case 'AT' :
				$valid = (bool) preg_match( '/^([0-9]{4})$/', $postcode );
				break;
			case 'BR' :
				$valid = (bool) preg_match( '/^([0-9]{5})([-])?([0-9]{3})$/', $postcode );
				break;
			case 'CH' :
				$valid = (bool) preg_match( '/^([0-9]{4})$/i', $postcode );
				break;
			case 'DE' :
				$valid = (bool) preg_match( '/^([0]{1}[1-9]{1}|[1-9]{1}[0-9]{1})[0-9]{3}$/', $postcode );
				break;
			case 'ES' :
			case 'FR' :
				$valid = (bool) preg_match( '/^([0-9]{5})$/i', $postcode );
				break;
			case 'GB' :
				$valid = self::is_GB_postcode( $postcode );
				break;
			case 'JP' :
				$valid = (bool) preg_match( '/^([0-9]{3})([-])([0-9]{4})$/', $postcode );
				break;
			case 'PT' :
				$valid = (bool) preg_match( '/^([0-9]{4})([-])([0-9]{3})$/', $postcode );
				break;
			case 'US' :
				$valid = (bool) preg_match( '/^([0-9]{5})(-[0-9]{4})?$/i', $postcode );
				break;
			case 'CA' :
				// CA Postal codes cannot contain D,F,I,O,Q,U and cannot start with W or Z. https://en.wikipedia.org/wiki/Postal_codes_in_Canada#Number_of_possible_postal_codes
				$valid = (bool) preg_match( '/^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])([\ ])?(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$/i', $postcode );
				break;
			case 'PL':
				$valid = (bool) preg_match( '/^([0-9]{2})([-])([0-9]{3})$/', $postcode );
				break;

			default :
				$valid = true;
				break;
		}

		return apply_filters( 'woocommerce_validate_postcode', $valid, $postcode, $country );
	}

	/**
	 * Check if is a GB postcode.
	 *
	 * @author John Gardner
	 * @param  string $to_check A postcode
	 * @return bool
	 */
	public static function is_GB_postcode( $to_check ) {

		// Permitted letters depend upon their position in the postcode.
		// https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation
		$alpha1 = "[abcdefghijklmnoprstuwyz]"; // Character 1
		$alpha2 = "[abcdefghklmnopqrstuvwxy]"; // Character 2
		$alpha3 = "[abcdefghjkpstuw]";         // Character 3 == ABCDEFGHJKPSTUW
		$alpha4 = "[abehmnprvwxy]";            // Character 4 == ABEHMNPRVWXY
		$alpha5 = "[abdefghjlnpqrstuwxyz]";    // Character 5 != CIKMOV

		$pcexp = array();

		// Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA
		$pcexp[0] = '/^(' . $alpha1 . '{1}' . $alpha2 . '{0,1}[0-9]{1,2})([0-9]{1}' . $alpha5 . '{2})$/';

		// Expression for postcodes: ANA NAA
		$pcexp[1] = '/^(' . $alpha1 . '{1}[0-9]{1}' . $alpha3 . '{1})([0-9]{1}' . $alpha5 . '{2})$/';

		// Expression for postcodes: AANA NAA
		$pcexp[2] = '/^(' . $alpha1 . '{1}' . $alpha2 . '[0-9]{1}' . $alpha4 . ')([0-9]{1}' . $alpha5 . '{2})$/';

		// Exception for the special postcode GIR 0AA
		$pcexp[3] = '/^(gir)(0aa)$/';

		// Standard BFPO numbers
		$pcexp[4] = '/^(bfpo)([0-9]{1,4})$/';

		// c/o BFPO numbers
		$pcexp[5] = '/^(bfpo)(c\/o[0-9]{1,3})$/';

		// Load up the string to check, converting into lowercase and removing spaces
		$postcode = strtolower( $to_check );
		$postcode = str_replace( ' ', '', $postcode );

		// Assume we are not going to find a valid postcode
		$valid = false;

		// Check the string against the six types of postcodes
		foreach ( $pcexp as $regexp ) {
			if ( preg_match( $regexp, $postcode, $matches ) ) {
				// Remember that we have found that the code is valid and break from loop
				$valid = true;
				break;
			}
		}

		return $valid;
	}

	/**
	 * Format the postcode according to the country and length of the postcode.
	 *
	 * @param   string	$postcode Postcode to format.
	 * @param	string	$country Country to format the postcode for.
	 * @return  string	Formatted postcode.
	 */
	public static function format_postcode( $postcode, $country ) {
		return wc_format_postcode( $postcode, $country );
	}

	/**
	 * format_phone function.
	 *
	 * @param mixed $tel Phone number to format.
	 * @return string
	 */
	public static function format_phone( $tel ) {
		return wc_format_phone_number( $tel );
	}
}