Making WordPress.org


Ignore:
Timestamp:
03/07/2017 01:28:40 AM (10 years ago)
Author:
iandunn
Message:

Events API: Extract country IDs from multi-word inputs to improve matching

This enables successfully matching locations for country codes in inputs like "GB" and "London GB"; and also matching country names of varying length, regardless of the city length, in inputs like "Vancouver Canada", "Santiago De Los Caballeros, Dominican Republic", and "Kaga-Bandoro, Central African Republic".

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/api.wordpress.org/public_html/events/1.0/index.php

    r5100 r5101  
    271271 * Guess the location based on a country identifier inside the given input
    272272 *
     273 * This isn't perfect because some of the country names in the database are in a format that regular
     274 * people wouldn't type -- e.g., "Venezuela, Bolvarian Republic Of" -- but this will still match a
     275 * majority of them.
     276 *
     277 * Currently, this only works with English names because that's the only data we have.
     278 *
    273279 * @param string $location_name
    274280 *
    … …  
    276282 */
    277283function guess_location_from_country( $location_name ) {
     284        // Check if they entered only the country name, e.g. "Germany" or "New Zealand"
     285        $country_code = get_country_code_from_name( $location_name );
     286        $location_word_count = str_word_count( $location_name );
     287        $location_name_parts = explode( ' ', $location_name );
     288
     289        // Check if they entered only the country code, e.g., "GB"
     290        if ( ! $country_code ) {
     291                $valid_country_codes = get_valid_country_codes();
     292
     293                if ( in_array( $location_name, $valid_country_codes, true ) ) {
     294                        $country_code = $location_name;
     295                }
     296        }
     297
    278298        /*
    279          * Check if they entered only the country name, e.g. "Germany" or "New Zealand"
    280          *
    281          * This isn't perfect because some of the country names in the database are in a format that regular
    282          * people wouldn't type -- e.g., "Venezuela, Bolvarian Republic Of" -- but this will still match a
    283          * majority of them.
    284          *
    285          * Currently, this only works with English names because that's the only data we have.
     299         * Multi-word queries may contain cities, regions, and countries, so try to extract just the country
    286300         */
    287         $location_country_code = get_country_code_from_name( $location_name );
    288 
    289         return $location_country_code;
     301        if ( ! $country_code && $location_word_count >= 2 ) {
     302                // Catch input like "Vancouver Canada"
     303                $country_id   = $location_name_parts[ $location_word_count - 1 ];
     304                $country_code = get_country_code_from_name( $country_id );
     305
     306                // Catch input like "London GB"
     307                if ( ! $country_code ) {
     308                        if ( in_array( $country_id, $valid_country_codes, true ) ) {
     309                                $country_code = $country_id;
     310                        }
     311                }
     312        }
     313
     314        if ( ! $country_code && $location_word_count >= 3 ) {
     315                // Catch input like "Santiago De Los Caballeros, Dominican Republic"
     316                $country_name = sprintf(
     317                        '%s %s',
     318                        $location_name_parts[ $location_word_count - 2 ],
     319                        $location_name_parts[ $location_word_count - 1 ]
     320                );
     321                $country_code = get_country_code_from_name( $country_name );
     322        }
     323
     324        if ( ! $country_code && $location_word_count >= 4 ) {
     325                // Catch input like "Kaga-Bandoro, Central African Republic"
     326                $country_name = sprintf(
     327                        '%s %s %s',
     328                        $location_name_parts[ $location_word_count - 3 ],
     329                        $location_name_parts[ $location_word_count - 2 ],
     330                        $location_name_parts[ $location_word_count - 1 ]
     331                );
     332                $country_code = get_country_code_from_name( $country_name );
     333        }
     334
     335        return $country_code;
     336}
     337
     338/**
     339 * Get a list of valid country codes
     340 *
     341 * @return array
     342 */
     343function get_valid_country_codes() {
     344        global $wpdb;
     345
     346        return $wpdb->get_col( "SELECT DISTINCT country FROM geoname" );
    290347}
    291348
Note: See TracChangeset for help on using the changeset viewer.