*/ class Cf7_States_Cities_Public { const REST_NAMESPACE = 'cf7-states-cities/v1'; /** * The ID of this plugin. * * @since 1.0.0 * @access private * @var string $plugin_name The ID of this plugin. */ private $plugin_name; /** * The version of this plugin. * * @since 1.0.0 * @access private * @var string $version The current version of this plugin. */ private $version; /** * Initialize the class and set its properties. * * @since 1.0.0 * @param string $plugin_name The name of the plugin. * @param string $version The version of this plugin. */ public function __construct( $plugin_name, $version ) { $this->plugin_name = $plugin_name; $this->version = $version; } /** * Register the JavaScript for the public-facing side of the site. * * @since 1.0.0 */ public function enqueue_scripts() { wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/cf7-states-cities-public.js', array( 'jquery' ), $this->version, false ); wp_localize_script( $this->plugin_name, 'cf7_states_cities', array( 'rest_base' => get_rest_url( null, self::REST_NAMESPACE ), ) ); } /** * Register REST API routes provided by the plugin * * @since 1.0.0 */ public function register_rest_api_routes() { register_rest_route( self::REST_NAMESPACE, '/states', array( 'methods' => 'GET', 'callback' => array( $this, 'get_states' ), ) ); register_rest_route( self::REST_NAMESPACE, '/cities', array( 'methods' => 'GET', 'callback' => array( $this, 'get_cities' ), ) ); } /** * Get all the states * * @since 1.0.0 */ public function get_states() { return require( plugin_dir_path( __FILE__ ) . '../data/states.php' ); } /** * Get all the cities or the cities filtered by state * * @param WP_REST_Request $request * @since 1.0.0 */ public function get_cities(WP_REST_Request $request) { $cities = require( plugin_dir_path( __FILE__ ) . '../data/cities.php' ); $state = $request->get_param( 'state' ); if ( !$state ) { return $cities; } $states = require( plugin_dir_path( __FILE__ ) . '../data/states.php' ); $state_id = array_search( $state, $states ); if ( $state_id === false ) { return array(); } return array_filter( $cities, function( $city_id ) use ( $state_id ) { return substr( (string) $city_id, 0, 2 ) === (string) $state_id; }, ARRAY_FILTER_USE_KEY ); } /** * Add the state, state*, city and city* CF7 form tags * * @since 1.0.0 */ public function add_form_tags() { wpcf7_add_form_tag( array( 'state', 'state*', 'city', 'city*'), array( $this, 'form_tag_handler' ), array( 'name-attr' => true, 'selectable-values' => true, ) ); } /** * The state and city form tags handler * * @param $tag * @since 1.0.0 */ public function form_tag_handler( $tag ) { if ( empty( $tag->name ) ) { return ''; } $validation_error = wpcf7_get_validation_error( $tag->name ); $class = wpcf7_form_controls_class( $tag->type ); if ( $validation_error ) { $class .= ' wpcf7-not-valid'; } $atts = array(); $atts['class'] = $tag->get_class_option( $class ); $atts['id'] = $tag->get_id_option(); $atts['tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true ); if ( $tag->is_required() ) { $atts['aria-required'] = 'true'; } $atts['aria-invalid'] = $validation_error ? 'true' : 'false'; $multiple = $tag->has_option( 'multiple' ); $include_blank = $tag->has_option( 'include_blank' ); $first_as_label = $tag->has_option( 'first_as_label' ); if ( $tag->has_option( 'size' ) ) { $size = $tag->get_option( 'size', 'int', true ); if ( $size ) { $atts['size'] = $size; } elseif ( $multiple ) { $atts['size'] = 4; } else { $atts['size'] = 1; } } if ($tag->type === 'state' || $tag->type === 'state*') { $states = require( plugin_dir_path( __FILE__ ) . '../data/states.php' ); $tag->values = $states; $tag->labels = $states; } else { $tag->values = array(); $tag->keys = array(); } $values = $tag->values; $labels = $tag->labels; $default_choice = $tag->get_default_option( null, array( 'multiple' => $multiple, 'shifted' => $include_blank, ) ); if ( $include_blank or empty( $values ) ) { array_unshift( $labels, '---' ); array_unshift( $values, '' ); } elseif ( $first_as_label ) { $values[0] = ''; } $html = ''; $hangover = wpcf7_get_hangover( $tag->name ); foreach ( $values as $key => $value ) { if ( $hangover ) { $selected = in_array( $value, (array) $hangover, true ); } else { $selected = in_array( $value, (array) $default_choice, true ); } $item_atts = array( 'value' => $value, 'selected' => $selected ? 'selected' : '', ); $item_atts = wpcf7_format_atts( $item_atts ); $label = isset( $labels[$key] ) ? $labels[$key] : $value; $html .= sprintf( '', $item_atts, esc_html( $label ) ); } if ( $multiple ) { $atts['multiple'] = 'multiple'; } $atts['name'] = $tag->name . ( $multiple ? '[]' : '' ); $atts = wpcf7_format_atts( $atts ); $html = sprintf( '%4$s', sanitize_html_class( $tag->name ), $atts, $html, $validation_error ); return $html; } /** * The state and city tags validator * * @since 1.0.0 */ public function validation_filter( $result, $tag ) { $name = $tag->name; if ( isset( $_POST[$name] ) and is_array( $_POST[$name] ) ) { foreach ( $_POST[$name] as $key => $value ) { if ( '' === $value ) { unset( $_POST[$name][$key] ); } } } $empty = ! isset( $_POST[$name] ) || empty( $_POST[$name] ) && '0' !== $_POST[$name]; if ( $tag->is_required() and $empty ) { $result->invalidate( $tag, wpcf7_get_message( 'invalid_required' ) ); } if ( $tag->type === 'state' || $tag->type === 'state*' ) { $states = require( plugin_dir_path( __FILE__ ) . '../data/states.php' ); if ( !in_array( $_POST[$name], $states ) ) { $result->invalidate( $tag, wpcf7_get_message( 'invalid_state' ) ); } } if ( $tag->type === 'city' || $tag->type === 'city*' ) { $cities = require( plugin_dir_path( __FILE__ ) . '../data/cities.php' ); if ( !in_array( $_POST[$name], $cities ) ) { $result->invalidate( $tag, wpcf7_get_message( 'invalid_city' ) ); } } return $result; } /** * The state and city tags error messages * * @since 1.0.0 */ public function text_messages( $messages ) { $messages = array_merge( $messages, array( 'invalid_state' => array( 'description' => __( "State that the sender entered is invalid", 'cf7-states-cities' ), 'default' => __( "The state entered is invalid.", 'cf7-states-cities' ), ), 'invalid_city' => array( 'description' => __( "City that the sender entered is invalid", 'cf7-states-cities' ), 'default' => __( "The city entered is invalid.", 'cf7-states-cities' ), ), ) ); return $messages; } }