$prefix_value ) { $one_match = FALSE; foreach ( $url['query'] as $url_keyword => $url_value ) { if ( $prefix_keyword === jr_v1_substr( $url_keyword, 0, jr_v1_strlen( $prefix_keyword ) ) ) { if ( $prefix_value === jr_v1_substr( $url_value, 0, jr_v1_strlen( $prefix_value ) ) ) { $one_match = TRUE; } } } /* All Prefix Queries must match. */ if ( FALSE === $one_match ) { return FALSE; } } $match = TRUE; } } else { /* Paths must exactly match if Prefix specifies Query */ if ( array() === $prefix['query'] ) { /* No Query in Prefix, so check Path for Prefix match */ $match = ( $prefix['path'] === jr_v1_substr( $url['path'], 0, jr_v1_strlen( $prefix['path'] ) ) ); } else { $match = FALSE; } } } else { if ( ( '' === $prefix['path'] ) && ( array() === $prefix['query'] ) ) { /* No Path or Query in Prefix, so check Host for Prefix match */ $match = ( $prefix['host'] === jr_v1_substr( $url['host'], 0, jr_v1_strlen( $prefix['host'] ) ) ); } else { /* Hosts must exactly match if Prefix specifies Path or Query */ $match = FALSE; } } return $match; } } /** * Standardize a URL into an array of values that can be accurately compared with another * * Preps URL, by removing any UTF Left-to-right Mark (LRM), usually found as a suffix, * translating the URL to lower-case, removing prefix http[s]//:[www.], * any embedded index.php and any trailing slash or #bookmark, * and breaks up ?keyword=value queries into array elements. * * Structure/Elements of Array returned: * [host] - domain.com - www. is removed, but all other subdomains are included * [path] - /dir/file.ext * [query] - any Queries (e.g. - "?kw=val&kw2=val2") broken up as follows: * [$keyword] => $value with preceding equals sign, only if equals sign was present * To simplify processing of this Array, zero length strings and empty arrays are used, * rather than NULL entries or missing array elements. * * @param string $url URL to create an array from, in special format for accurate comparison * @return array array of standardized attributes of the URL (see structure above) */ if ( !function_exists( 'jr_v1_prep_url' ) ) { function jr_v1_prep_url( $url ) { /* Handle troublesome %E2%80%8E UTF Left-to-right Mark (LRM) suffix first. */ if ( FALSE === jr_v1_stripos( $url, '%E2%80%8E' ) ) { if ( FALSE === jr_v1_stripos( rawurlencode( $url ), '%E2%80%8E' ) ) { $url_clean = $url; } else { $url_clean = rawurldecode( str_ireplace( '%E2%80%8E', '', rawurlencode( $url ) ) ); /* mb_str_ireplace() does not exist because str_ireplace() is binary-safe. */ } } else { $url_clean = str_ireplace( '%E2%80%8E', '', $url ); } $url_clean = trim( $url_clean ); /* parse_url(), especially before php Version 5.4.7, has a history of problems when Scheme is not present, especially for LocalHost as a Host, so add a prefix of http:// if :// is not found */ if ( FALSE === jr_v1_strpos( $url_clean, '://' ) ) { $url_clean = "http://$url_clean"; } $parse_array = parse_url( jr_v1_strtolower( $url_clean ) ); /* Get rid of URL components that do not matter to us in our comparison of URLs */ foreach ( array( 'scheme', 'port', 'user', 'pass', 'fragment' ) as $component ) { unset ( $parse_array[$component] ); } /* Remove www. from host */ if ( 'www.' === jr_v1_substr( $parse_array['host'], 0, 4 ) ) { $parse_array['host'] = jr_v1_substr( $parse_array['host'], 4 ); } if ( isset( $parse_array['path'] ) ) { /* Remove any index.php occurences in path, since these can be spurious in IIS and perhaps other environments. */ $parse_array['path'] = str_replace( 'index.php', '', $parse_array['path'] ); /* Remove leading and trailing slashes from path */ $parse_array['path'] = trim( $parse_array['path'], "/\\" ); } else { $parse_array['path'] = ''; } /* Take /?keyword=value&keyword=value URL query parameters and break them up into array( keyword => value, keyword => value ) */ if ( isset( $parse_array['query'] ) ) { $parms = explode( '&', $parse_array['query'] ); $parse_array['query'] = array(); foreach( $parms as $parm ) { if ( FALSE === ( $cursor = jr_v1_strpos( $parm, '=' ) ) ) { $parse_array['query'][$parm] = ''; } else { /* Include the Equals Sign ("=") as the first character of the Query Value to differentiate between a URL Prefix with a Query Keyword followed by an Equals Sign, and one without. For example, "address" would match address2=abc, while "address=" would not. */ $parse_array['query'][jr_v1_substr( $parm, 0, $cursor + 1 )] = jr_v1_substr( $parm, $cursor + 1 ); } } } else { $parse_array['query'] = array(); } return $parse_array; } } /** * Sanitize a URL * * Preps URL, by removing any UTF Left-to-right Mark (LRM), usually found as a suffix, * and then checks if URL is blank. * * @param string $url URL * @return string/bool Sanitized URL; bool FALSE if invalid URL; * zero length string if URL not specified */ if ( !function_exists( 'jr_v1_sanitize_url' ) ) { function jr_v1_sanitize_url( $url ) { /* Handle troublesome %E2%80%8E UTF Left-to-right Mark (LRM) suffix first. */ if ( FALSE === stripos( $url, '%E2%80%8E' ) ) { if ( FALSE === stripos( rawurlencode( $url ), '%E2%80%8E' ) ) { $url_clean = $url; } else { $url_clean = rawurldecode( str_ireplace( '%E2%80%8E', '', rawurlencode( $url ) ) ); } } else { $url_clean = str_ireplace( '%E2%80%8E', '', $url ); } $url_clean = trim( $url_clean ); if ( empty( $url_clean ) ) { return ''; } /* Add a prefix of http:// if :// is not found and be sure scheme is http: or https: */ if ( FALSE === strpos( $url_clean, '://' ) ) { if ( is_ssl() || ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) ) { $s = 's'; } else { $s = ''; } $url_clean = "http$s://$url_clean"; } else { if ( !in_array( strtolower( parse_url( $url_clean, PHP_URL_SCHEME ) ), array( 'http', 'https' ) ) ) { return FALSE; } } return $url_clean; } } ?>