prefix . 'cities'; $query = $wpdb->prepare( "SELECT * FROM %i GROUP BY country ORDER BY country ASC", $table ); $method = 'get_results'; $results = $wpdb->$method( $query ); wp_cache_set( $cache_key, $results, $cache_group, 2 * HOUR_IN_SECONDS ); } if ( ! empty( $results ) ) { $country_results = []; foreach ( $results as $data ) { if ( isset( $data->country_code ) && isset( $data->country ) ) { $country_results[ esc_attr( $data->country_code ) ] = esc_attr( acfcs_get_country_name( strtolower( $data->country_code ) ) ); } } $countries = array_merge( $countries, $country_results ); } return $countries; } // Create an array with states based on a country code function acfcs_get_states( $country_code = false, $show_first = true, $field = false ) { $select_province_state_label = apply_filters( 'acfcs_select_province_state_label', esc_attr__( 'Select a province/state', 'acf-city-selector' ) ); $show_labels = ( isset( $field[ 'show_labels' ] ) ) ? $field[ 'show_labels' ] : true; $states = []; if ( $show_first ) { if ( $show_labels ) { $states[ '' ] = '-'; } else { $states[ '' ] = $select_province_state_label; } } if ( false != $country_code ) { global $wpdb; $table = $wpdb->prefix . 'cities'; $cache_group = 'cities_data'; $cache_key = 'states_' . md5( strtoupper( $country_code ) ); $method = 'get_results'; $results = wp_cache_get( $cache_key, $cache_group ); $state_results = []; if ( false === $results ) { if ( 'FR' == $country_code ) { $query = $wpdb->prepare( "SELECT * FROM %i WHERE country_code = %s GROUP BY state_code ORDER BY LENGTH(state_name), state_name", $table, strtoupper( $country_code ) ); } else { $query = $wpdb->prepare( "SELECT * FROM %i WHERE country_code = %s GROUP BY state_code ORDER BY state_name ASC", $table, strtoupper( $country_code ) ); } $results = $wpdb->$method( $query ); wp_cache_set( $cache_key, $results, $cache_group, 2 * HOUR_IN_SECONDS ); } if ( is_array( $results ) ) { foreach ( $results as $data ) { $state_results[ esc_attr( strtoupper( $country_code ) . '-' . $data->state_code ) ] = esc_attr( $data->state_name ); } if ( ! empty( $state_results ) ) { $states = array_merge( $states, $state_results ); } } } return $states; } // Create an array with cities for a certain country/state function acfcs_get_cities( $country_code = false, $state_code = false, $field = false ) { $cache_group = 'cities_data'; $cities = []; $city_results = []; $method = 'get_results'; $select_city_label = apply_filters( 'acfcs_select_city_label', esc_attr__( 'Select a city', 'acf-city-selector' ) ); $show_labels = ( isset( $field[ 'show_labels' ] ) ) ? $field[ 'show_labels' ] : true; if ( $show_labels ) { $cities[ '' ] = '-'; } else { $cities[ '' ] = $select_city_label; } if ( $country_code ) { global $wpdb; $table = $wpdb->prefix . 'cities'; if ( $state_code ) { if ( 3 < strlen( $state_code ) ) { $state_code = substr( $state_code, 3 ); } $cache_key = 'cities_' . md5( strtoupper( $country_code ) . '_' . strtoupper( $state_code ) ); $results = wp_cache_get( $cache_key, $cache_group ); if ( false === $results ) { $query = $wpdb->prepare( "SELECT * FROM %i WHERE country_code = %s AND state_code = %s ORDER BY state_name, city_name ASC", $table, $country_code, $state_code ); $results = $wpdb->$method( $query ); wp_cache_set( $cache_key, $results, $cache_group, 2 * HOUR_IN_SECONDS ); } } elseif ( $country_code ) { $cache_key = 'cities_' . md5( strtoupper( $country_code ) ); $results = wp_cache_get( $cache_key, $cache_group ); if ( false === $results ) { $query = $wpdb->prepare( "SELECT * FROM %i WHERE country_code = %s", $table, $country_code ); $results = $wpdb->$method( $query ); wp_cache_set( $cache_key, $results, $cache_group, 2 * HOUR_IN_SECONDS ); } } if ( ! empty( $results ) ) { foreach ( $results as $data ) { $city_results[] = [ 'city_name' => $data->city_name, ]; } } if ( ! empty( $city_results ) ) { uasort( $city_results, 'acfcs_sort_array_with_quotes' ); } foreach ( $city_results as $data ) { $city_array[ esc_attr( $data[ 'city_name' ] ) ] = esc_attr( $data[ 'city_name' ] ); } if ( isset( $city_array ) ) { $cities = array_merge( $cities, $city_array ); } } return $cities; } // Get country name by country code function acfcs_get_country_name( $country_code = false ) { if ( false != $country_code ) { $country_name = acfcs_country_i18n( strtolower( $country_code ) ); if ( is_string( $country_name ) && 2 < strlen( $country_name ) ) { return $country_name; } $cache_group = 'cities_data'; $cache_key = 'cities_' . md5( strtoupper( $country_code ) ); $method = 'get_row'; $results = wp_cache_get( $cache_key, $cache_group ); if ( false === $results ) { global $wpdb; $table = $wpdb->prefix . 'cities'; $query = $wpdb->prepare( "SELECT * FROM %i WHERE country_code = %s", $table, $country_code ); $country = $wpdb->$method( $query ); wp_cache_set( $cache_key, $results, $cache_group, 2 * HOUR_IN_SECONDS ); } if ( isset( $country->country ) ) { return $country->country; } } return $country_code; } // Checks if there are any cities in the database (for page availability) function acfcs_has_cities( $country_code = false ) { global $wpdb; $cache_group = 'cities_data'; $method = 'get_results'; $results = []; $table = $wpdb->prefix . 'cities'; if ( $country_code ) { $cache_key = 'has_cities_' . md5( strtoupper( $country_code ) ); $results = wp_cache_get( $cache_key, $cache_group ); if ( false === $results ) { $query = $wpdb->prepare( "SELECT * FROM %i WHERE country_code = %s LIMIT 1", $table, $country_code ); $results = $wpdb->$method( $query ); wp_cache_set( $cache_key, $results, $cache_group, 2 * HOUR_IN_SECONDS ); } } else { $cache_key = 'has_cities'; $results = wp_cache_get( $cache_key, $cache_group ); if ( false === $results ) { $query = $wpdb->prepare( "SELECT * FROM %i LIMIT 1", $table ); $results = $wpdb->$method( $query ); wp_cache_set( $cache_key, $results, $cache_group, 2 * HOUR_IN_SECONDS ); } } if ( count( $results ) > 0 ) { return true; } return false; } // Checks if files are uploaded function acfcs_check_if_files() { $actual_files = []; $target_dir = acfcs_upload_folder(); if ( is_dir( $target_dir ) ) { $file_index = scandir( $target_dir ); $default_excluded_files = [ '.', '..', '.DS_Store', 'debug.json', ]; $excluded_files = apply_filters( 'acfcs_exclude_files', $default_excluded_files ); if ( is_array( $file_index ) ) { foreach ( $file_index as $file ) { if ( ! in_array( $file, $excluded_files ) ) { $actual_files[] = $file; } } if ( ! empty( $actual_files ) ) { return $actual_files; } } } return $actual_files; } // Convert data from an uploaded CSV file to an array function acfcs_csv_to_array( $file_name, $upload_folder = '', $delimiter = ';', $verify = false, $max_lines = false ) { global $wp_filesystem; if ( empty( $wp_filesystem ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; WP_Filesystem(); } $upload_folder = ( ! empty( $upload_folder ) ) ? $upload_folder : acfcs_upload_folder( '/' ); $file_path = $upload_folder . $file_name; if ( $wp_filesystem->exists( $file_path ) && false !== ( $file_content = $wp_filesystem->get_contents( $file_path ) ) ) { $column_benchmark = 5; $empty_array = false; $errors = ACF_City_Selector::acfcs_errors(); $line_number = 0; $max_line_length = 500; $new_array = []; $csv_lines = explode( "\n", $file_content ); foreach ( $csv_lines as $line ) { // Skip completely empty lines to prevent false errors if ( '' === trim( $line ) ) { continue; } $line_number++; $csv_array[ 'delimiter' ] = $delimiter; // Enforce the line length filter if necessary if ( strlen( $line ) > $max_line_length ) { $line = substr( $line, 0, $max_line_length ); } // Parse the line string as CSV $csv_line = str_getcsv( $line, "{$delimiter}" ); if ( false === $csv_line || null === $csv_line[0] ) { continue; } // If column count doesn't match benchmark if ( count( $csv_line ) != $column_benchmark ) { // If column count < benchmark if ( count( $csv_line ) < $column_benchmark ) { $error_message = esc_html__( 'Since your file is not accurate anymore, the file is deleted.', 'acf-city-selector' ); /* translators: 1 line number 2 error message */ $errors->add( 'error_no_correct_columns_' . $line_number, sprintf( esc_html__( 'There are too few columns on line %1$d. %2$s', 'acf-city-selector' ), $line_number, $error_message ) ); } elseif ( count( $csv_line ) > $column_benchmark ) { // If column count > benchmark $error_message = esc_html__( 'Since your file is not accurate anymore, the file is deleted.', 'acf-city-selector' ); if ( false === $verify ) { $error_message = 'Lines 0-' . ( $line_number - 1 ) . ' are correctly imported but since your file is not accurate anymore, the file is deleted'; } /* translators: 1 line number 2 error message */ $errors->add( 'error_no_correct_columns_' . $line_number, sprintf( esc_html__( 'There are too many columns on line %1$d. %2$s', 'acf-city-selector' ), $line_number, $error_message ) ); } } if ( $errors->has_errors() ) { $empty_array = true; $new_array = []; } else { // Create a new array for each row $new_line = []; foreach ( $csv_line as $item ) { $new_line[] = $item; } if ( ! empty( $new_line ) ) { $new_array[] = $new_line; } if ( false != $max_lines ) { if ( $line_number == $max_lines ) { break; } } } } if ( $errors->has_errors() ) { $delete_check_path = acfcs_upload_folder( '/' ) . $file_name; if ( $wp_filesystem->exists( $delete_check_path ) ) { do_action( 'acfcs_delete_file', $file_name ); $csv_array[ 'error' ] = 'file_deleted'; } } /* * Don't add data if there are any errors. This to prevent rows which had no error from outputting * on the preview page. */ if ( ! empty( $new_array ) && false === $empty_array ) { $csv_array[ 'data' ] = array_values( $new_array ); } } return $csv_array; } // Verify raw csv import function acfcs_verify_csv_data( $csv_data = false, $delimiter = ";" ) { if ( false != $csv_data ) { $column_benchmark = 5; $line_number = 0; $lines = explode( "\r\n", $csv_data ); foreach ( $lines as $line ) { $line_number++; if ( ! is_array( $csv_data ) ) { $line_array = explode( $delimiter, $line ); } if ( count( $line_array ) != $column_benchmark ) { // length of a line is not correct if ( count( $line_array ) < $column_benchmark ) { /* translators: %d line number */ ACF_City_Selector::acfcs_errors()->add( 'error_no_correct_columns', sprintf( esc_html__( 'There are too few columns on line %d.', 'acf-city-selector' ), $line_number ) ); return false; } elseif ( count( $line_array ) > $column_benchmark ) { /* translators: %d line number */ ACF_City_Selector::acfcs_errors()->add( 'error_no_correct_columns', sprintf( esc_html__( 'There are too many columns on line %d.', 'acf-city-selector' ), $line_number ) ); return false; } } $column_counter = 0; foreach( $line_array as $element ) { $column_counter++; if ( $column_counter == 4 ) { if ( 2 != strlen( $element ) ) { /* translators: %d line number */ ACF_City_Selector::acfcs_errors()->add( 'error_wrong_country_length', sprintf( esc_html__( 'The length of the country abbreviation on line %d is incorrect.', 'acf-city-selector' ), $line_number ) ); return false; } } } $validated_data[] = $line_array; } return $validated_data; } return false; } // Get packages through WP_Http function acfcs_get_packages( $endpoint = 'single' ) { $url = sprintf( '%s/wp-json/countries/v1/%s', ACFCS_WEBSITE_URL, $endpoint ); $request = new WP_Http; $result = $request->request( $url, [ 'method' => 'GET' ] ); if ( 200 == $result[ 'response' ][ 'code' ] ) { $response = json_decode( $result[ 'body' ] ); return $response; } return []; } // Get country info for debug function acfcs_get_countries_info() { global $wpdb; $acfcs_info = []; $cache_group = 'cities_data'; $cache_key = 'country_codes'; $method = 'get_results'; $results = wp_cache_get( $cache_key, $cache_group ); $table = $wpdb->prefix . 'cities'; if ( false === $results ) { $query = $wpdb->prepare( "SELECT country_code FROM %i GROUP BY country_code ORDER BY country_code ASC", $table ); $results = $wpdb->$method( $query ); wp_cache_set( $cache_key, $results, $cache_group, 2 * HOUR_IN_SECONDS ); } if ( is_array( $results ) ) { foreach ( $results as $data ) { if ( isset( $data->country_code ) ) { $country_code = $data->country_code; $cache_key = 'country_info_' . md5( strtoupper( $country_code ) ); $sub_results = wp_cache_get( $cache_key, $cache_group ); if ( false === $sub_results ) { $query = $wpdb->prepare( "SELECT * FROM %i WHERE country_code = %s ORDER BY country_code ASC", $table, $country_code ); $sub_results = $wpdb->$method( $query ); wp_cache_set( $cache_key, $sub_results, $cache_group, 2 * HOUR_IN_SECONDS ); $acfcs_info[ $country_code ] = [ 'country_code' => $country_code, 'count' => count( $sub_results ), 'name' => acfcs_get_country_name( $country_code ), ]; } } } } return $acfcs_info; } // Search an array which contains quotes like "'t Veld" function acfcs_sort_array_with_quotes( $a, $b ) { return strnatcasecmp( acfcs_custom_sort_with_quotes( $a[ 'city_name' ] ), acfcs_custom_sort_with_quotes( $b[ 'city_name' ] ) ); } // Sort with quotes function acfcs_custom_sort_with_quotes( $city ) { // strip quote marks if ( strpos( $city, "'s" ) !== false ) { $city = trim( $city, '\'s ' ); $city = preg_replace( '/^\s*\'s \s+/i', '', $city ); } elseif ( strpos( $city, "'t" ) !== false ) { $city = trim( $city, '\'t ' ); $city = preg_replace( '/^\s*\'t \s+/i', '', $city ); } return $city; } // Render select in ACF field function acfcs_render_dropdown( $type, $field, $stored_value, $prefill_values ) { $acfcs_dropdown = 'acfcs__dropdown'; $city_label = apply_filters( 'acfcs_select_city_label', esc_attr__( 'Select a city', 'acf-city-selector' ) ); $countries = acfcs_get_countries( true, $field ); $country_label = apply_filters( 'acfcs_select_country_label', esc_attr__( 'Select a country', 'acf-city-selector' ) ); $default_country = ( isset( $field[ 'default_country' ] ) && ! empty( $field[ 'default_country' ] ) ) ? $field[ 'default_country' ] : false; $default_value = false; $field_id = $field[ 'id' ]; $field_name = $field[ 'name' ]; $prefill_cities = $prefill_values[ 'prefill_cities' ]; $prefill_states = $prefill_values[ 'prefill_states' ]; $province_state_label = apply_filters( 'acfcs_select_province_state_label', esc_attr__( 'Select a province/state', 'acf-city-selector' ) ); $selected_selected = ' selected="selected"'; $show_labels = ( isset( $field[ 'show_labels' ] ) ) ? $field[ 'show_labels' ] : true; $use_select2 = ( isset( $field[ 'use_select2' ] ) ) ? $field[ 'use_select2' ] : false; $dropdown_class = ( true == $use_select2 ) ? 'select2 ' . $acfcs_dropdown : $acfcs_dropdown; $data_label_value = ( true == $show_labels ) ? '1' : '0'; $which_fields = ( isset( $field[ 'which_fields' ] ) ) ? $field[ 'which_fields' ] : 'all'; switch( $type ) { case 'country': $default_value = $default_country; $field_label = $country_label; $field_suffix = 'countryCode'; $modifier = 'countries'; $selected_value = esc_attr( $stored_value ); $values = $countries; break; case 'state': $field_label = $province_state_label; $field_suffix = 'stateCode'; $modifier = 'states'; $selected_value = esc_attr( $stored_value ); $values = $prefill_states; break; case 'city': $field_label = $city_label; $field_suffix = 'cityName'; $modifier = 'cities'; $selected_value = esc_attr( $stored_value ); $values = $prefill_cities; break; } $dropdown_class = $dropdown_class . ' ' . $acfcs_dropdown . '--' . $modifier; ?>
| %s | ', esc_attr( $column ) ); } echo ''; echo ''; foreach ( $csv_data as $line ) { echo '
|---|
| %s | ', esc_attr( stripslashes( htmlspecialchars( $column ) ) ) ); } echo '