name = 'acf_city_selector';
$this->label = 'City Selector';
$this->category = esc_attr__( 'Choice', 'acf-city-selector' );
$this->defaults = array(
'show_labels' => 1,
'which_fields' => 'all',
);
$this->l10n = acfcs_get_js_translations();
parent::__construct();
$this->settings = $settings;
}
/**
* create_options()
*
* Create extra options for your field. This is rendered when editing a field.
* The value of $field['name'] can be used (like below) to save extra data to the $field
*
* @type action
* @since 3.6
* @date 23/01/13
*
* @param $field
*
* @return void
*/
function create_options( $field ) {
$field = array_merge($this->defaults, $field);
// key is needed in the field names to correctly save the data
$key = $field[ 'name' ];
$countries = acfcs_get_countries( true, false, true );
$default_country_fields = array(
'all' => esc_attr__( 'All fields [default]', 'acf-city-selector' ),
'country_only' => esc_attr__( 'Country only', 'acf-city-selector' ),
'country_state' => esc_attr__( 'Country + State/province', 'acf-city-selector' ),
'country_city' => esc_attr__( 'Country + City', 'acf-city-selector' ),
'state_city' => esc_attr__( 'State/province + City', 'acf-city-selector' ),
);
$select_options = array(
1 => esc_attr__( 'Yes', 'acf-city-selector' ),
0 => esc_attr__( 'No', 'acf-city-selector' )
);
// Create Field Options HTML
?>
|
|
'radio',
'name' => 'fields[' . $key . '][show_labels]',
'choices' => $select_options,
'value' => $field[ 'show_labels' ],
'layout' => 'horizontal',
));
?>
|
|
|
'select',
'name' => 'fields[' . $key . '][default_country]',
'choices' => $countries,
'value' => ( isset( $field[ 'default_country' ] ) ) ? $field[ 'default_country' ] : false,
'layout' => 'horizontal',
));
?>
|
|
|
'radio',
'name' => 'fields[' . $key . '][which_fields]',
'choices' => $default_country_fields,
'value' => ( isset( $field[ 'which_fields' ] ) ) ? $field[ 'which_fields' ] : 'all',
));
?>
|
defaults, $field );
$default_country = ( isset( $field[ 'default_country' ] ) && ! empty( $field[ 'default_country' ] ) ) ? $field[ 'default_country' ] : false;
$prefill_cities = array();
$prefill_states = array();
$selected_country = ( isset( $field[ 'value' ][ 'countryCode' ] ) ) ? $field[ 'value' ][ 'countryCode' ] : false;
$selected_state = ( isset( $field[ 'value' ][ 'stateCode' ] ) ) ? $field[ 'value' ][ 'stateCode' ] : false;
$selected_city = ( isset( $field[ 'value' ][ 'cityName' ] ) ) ? $field[ 'value' ][ 'cityName' ] : false;
$show_first = true;
$which_fields = ( isset( $field[ 'which_fields' ] ) ) ? $field[ 'which_fields' ] : 'all';
if ( false !== $default_country && false == $selected_country ) {
// New post with default country
if ( in_array( $which_fields, [ 'all', 'country_state', 'state_city' ] ) ) {
$prefill_states = acfcs_get_states( $default_country, $show_first, $field );
}
if ( in_array( $which_fields, [ 'country_city', 'state_city' ] ) ) {
$prefill_cities = acfcs_get_cities( $default_country, false, $field );
}
} elseif ( false !== $selected_country ) {
if ( in_array( $which_fields, [ 'all', 'country_state', 'state_city' ] ) ) {
$prefill_states = acfcs_get_states( $selected_country, $show_first, $field );
}
if ( in_array( $which_fields, [ 'all', 'country_city', 'state_city' ] ) ) {
$prefill_cities = acfcs_get_cities( $selected_country, $selected_state, $field );
}
if ( 'country_city' != $which_fields ) {
if ( false != $selected_country && false != $selected_state ) {
$selected_state = $selected_country . '-' . $selected_state;
}
}
} elseif ( false == $default_country && 'state_city' == $which_fields ) {
// no default country is set, so show warning
$error_message = esc_html__( "You haven't set a default country, so NO provinces/states and cities will be loaded.", 'acf-city-selector' );
echo sprintf( '', esc_attr( $error_message ) );
}
$prefill_values = [
'prefill_states' => $prefill_states,
'prefill_cities' => $prefill_cities,
];
if ( 'state_city' != $which_fields ) {
acfcs_render_dropdown( 'country', $field, $selected_country, $prefill_values );
}
if ( 'all' == $which_fields || strpos( $which_fields, 'state' ) !== false ) {
acfcs_render_dropdown( 'state', $field, $selected_state, $prefill_values );
}
if ( 'all' == $which_fields || strpos( $which_fields, 'city' ) !== false ) {
acfcs_render_dropdown( 'city', $field, $selected_city, $prefill_values );
}
}
/**
* input_admin_enqueue_scripts()
*
* This action is called in the admin_enqueue_scripts action on the edit screen where your field is created.
* Use this action to add CSS + JavaScript to assist your create_field() action.
*
* $info https://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts
* @type action
* @since 3.6
* @date 23/01/13
*
* @return void
*
* @TODO: DRY
*/
function input_admin_enqueue_scripts() {
$plugin_url = trailingslashit( sprintf( '%s/plugins/acf-city-selector', WP_CONTENT_URL ) );
$plugin_version = get_option( 'acfcs_version' );
wp_enqueue_script( 'acf-custom-validation', "{$plugin_url}assets/js/field-validation.js", array( 'acf-input' ), $plugin_version, false );
wp_enqueue_script( 'acf-custom-validation' );
wp_register_script( 'acfcs-init', "{$plugin_url}assets/js/init.js", array( 'jquery', 'acf-input' ), $plugin_version, false );
wp_enqueue_script( 'acfcs-init' );
wp_register_script( 'acfcs-process', "{$plugin_url}assets/js/city-selector.js", array( 'jquery', 'acf-input' ), $plugin_version, false );
wp_enqueue_script( 'acfcs-process' );
$all_info = acfcs_get_field_settings();
$js_vars[ 'ajaxurl' ] = admin_url( 'admin-ajax.php' );
$js_vars[ 'default_country' ] = ( isset( $all_info[ 'default_country' ] ) && false != $all_info[ 'default_country' ] ) ? $all_info[ 'default_country' ] : false;
$js_vars[ 'post_id' ] = 0 < get_the_ID() ? (int) get_the_ID() : false;
$js_vars[ 'show_labels' ] = ( isset( $all_info[ 'show_labels' ] ) ) ? $all_info[ 'show_labels' ] : apply_filters( 'acfcs_show_labels', true );
$js_vars[ 'use_select2' ] = ( isset( $all_info[ 'use_select2' ] ) ) ? $all_info[ 'use_select2' ] : false;
$js_vars[ 'which_fields' ] = ( isset( $all_info[ 'which_fields' ] ) ) ? $all_info[ 'which_fields' ] : 'all';
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] === 'edit' ) {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( isset( $_GET[ 'id' ] ) ) {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$post_id = (int) $_GET[ 'id' ];
} else {
$post_id = get_the_ID();
}
$fields = get_field_objects( $post_id );
$field_name = 'acf_city_selector';
if ( is_array( $fields ) && count( $fields ) > 0 ) {
foreach( $fields as $field ) {
if ( isset( $field[ 'type' ] ) && $field[ 'type' ] == 'acf_city_selector' ) {
$field_name = $field[ 'name' ];
break;
}
}
}
$post_meta = get_post_meta( $post_id, $field_name, true );
if ( ! empty( $post_meta[ 'cityName' ] ) ) {
$v4_vars = array(
'countryCode' => $post_meta[ 'countryCode' ],
'stateCode' => $post_meta[ 'stateCode' ],
'cityName' => $post_meta[ 'cityName' ],
);
$js_vars = array_merge( $js_vars, $v4_vars );
}
}
wp_localize_script( 'acfcs-process', 'city_selector_vars', $js_vars );
}
/**
* load_value()
*
* This filter is applied to the $value after it is loaded from the db
*
* @type filter
* @since 3.6
* @date 23/01/13
*
* @param $value
* @param $post_id
* @param $field
*
* @return mixed
*
* @TODO: DRY
*/
function load_value( $value, $post_id, $field ) {
$state_code = false;
$country_code = ( isset( $value[ 'countryCode' ] ) ) ? $value[ 'countryCode' ] : false;
if ( isset( $value[ 'stateCode' ] ) ) {
if ( 3 < strlen( $value[ 'stateCode' ] ) ) {
// $value[ 'stateCode' ] is longer than 3 characters, which starts with xx-
// where xx is the country code
$state_code = substr( $value[ 'stateCode' ], 3 );
} elseif ( 1 <= strlen( $value[ 'stateCode' ] ) ) {
// this is a fallback and is probably never reached
$state_code = $value[ 'stateCode' ];
}
}
if ( strlen( $country_code ) == 2 && false != $state_code ) {
global $wpdb;
$cache_key = 'country_state_' . md5( $country_code . '_' . $state_code );
$cache_group = 'cities_data';
$row = wp_cache_get( $cache_key, $cache_group );
if ( false === $row ) {
$table = $wpdb->prefix . 'cities';
$method = 'get_row';
$row = $wpdb->$method(
$wpdb->prepare(
"SELECT country, state_name FROM %i WHERE country_code = %s AND state_code = %s",
$table,
$country_code,
$state_code
)
);
// If $row is null (no match found), it caches that too to prevent repeated broken lookups (Negative Caching)
wp_cache_set( $cache_key, $row, $cache_group, 2 * HOUR_IN_SECONDS );
}
$value[ 'stateCode' ] = $state_code;
$value[ 'stateName' ] = ( isset( $row->state_name ) ) ? $row->state_name : false;
$value[ 'countryName' ] = ( isset( $row->country ) ) ? $row->country : false;
}
return $value;
}
/**
* Update value before it's changed in the database
*
* @param $value (mixed) the value found in the database
* @param $post_id (mixed) the $post_id from which the value was loaded
* @param $field (array) the field array holding all the field options
*
* @since: 1.5.0
*
* @TODO: DRY
*
* @return false|mixed
*/
function update_value( $value, $post_id, $field ) {
$required = $field[ 'required' ];
if ( 0 == $required ) {
if ( isset( $field[ 'which_fields' ] ) && 'all' == $field[ 'which_fields' ] || ! isset( $field[ 'which_fields' ] ) ) {
// if nothing is selected, set value to false
if ( empty( $value[ 'countryCode' ] ) && empty( $value[ 'stateCode' ] ) && empty( $value[ 'cityName' ] ) ) {
$value = false;
} elseif ( empty( $value[ 'stateCode' ] ) && empty( $value[ 'cityName' ] ) ) {
$value = false;
}
} elseif ( isset( $field[ 'which_fields' ] ) && 'country_only' == $field[ 'which_fields' ] ) {
if ( empty( $value[ 'countryCode' ] ) ) {
$value = false;
}
} elseif ( isset( $field[ 'which_fields' ] ) && 'country_state' == $field[ 'which_fields' ] ) {
if ( empty( $value[ 'countryCode' ] ) || empty( $value[ 'stateCode' ] ) ) {
$value = false;
}
} elseif ( isset( $field[ 'which_fields' ] ) && 'country_city' == $field[ 'which_fields' ] ) {
if ( empty( $value[ 'countryCode' ] ) || empty( $value[ 'cityName' ] ) ) {
$value = false;
}
} elseif ( isset( $field[ 'which_fields' ] ) && 'state_city' == $field[ 'which_fields' ] ) {
if ( isset( $field[ 'default_country' ] ) ) {
$value[ 'countryCode'] = $field[ 'default_country' ];
}
if ( empty( $value[ 'stateCode' ] ) || empty( $value[ 'cityName' ] ) ) {
$value = false;
}
}
} else {
// field == required
if ( isset( $field[ 'which_fields' ] ) && 'all' == $field[ 'which_fields' ] || ! isset( $field[ 'which_fields' ] ) ) {
// if nothing is selected, set value to false
if ( empty( $value[ 'countryCode' ] ) && empty( $value[ 'stateCode' ] ) && empty( $value[ 'cityName' ] ) ) {
$value = false;
} elseif ( empty( $value[ 'countryCode' ] ) || empty( $value[ 'stateCode' ] ) || empty( $value[ 'cityName' ] ) ) {
$value = false;
}
} elseif ( isset( $field[ 'which_fields' ] ) && 'country_only' == $field[ 'which_fields' ] ) {
if ( empty( $value[ 'countryCode' ] ) ) {
$value = false;
}
} elseif ( isset( $field[ 'which_fields' ] ) && 'country_state' == $field[ 'which_fields' ] ) {
if ( empty( $value[ 'countryCode' ] ) || empty( $value[ 'stateCode' ] ) ) {
$value = false;
}
} elseif ( isset( $field[ 'which_fields' ] ) && 'country_city' == $field[ 'which_fields' ] ) {
if ( empty( $value[ 'countryCode' ] ) || empty( $value[ 'cityName' ] ) ) {
$value = false;
}
} elseif ( isset( $field[ 'which_fields' ] ) && 'state_city' == $field[ 'which_fields' ] ) {
if ( isset( $field[ 'default_country' ] ) ) {
$value[ 'countryCode'] = $field[ 'default_country' ];
}
if ( empty( $value[ 'stateCode' ] ) || empty( $value[ 'cityName' ] ) ) {
$value = false;
}
}
}
return $value;
}
}
// initialize
new acf_field_city_selector( $this->settings );
endif;