__( 'Not allowed.', 'viator-collector' ) ) ); } $query = isset( $_POST['q'] ) ? sanitize_text_field( wp_unslash( $_POST['q'] ) ) : ''; $map = ( new VC_API() )->get_destination_map(); if ( is_wp_error( $map ) ) { wp_send_json_error( array( 'message' => $map->get_error_message() ) ); } $needle = strtolower( $query ); $results = array(); foreach ( (array) $map as $id => $name ) { if ( '' === $query || false !== strpos( strtolower( $name ), $needle ) ) { $results[] = array( 'id' => (string) $id, 'name' => $name, ); if ( count( $results ) >= 40 ) { break; } } } // Suggested URL slug for the Viator Structure screen: keep an existing // term's slug so live /tour-destination/{slug}/ links still resolve // (and 301), otherwise WordPress's own slug for the name. $existing = array(); if ( $results ) { $terms = get_terms( array( 'taxonomy' => 'viator_destination', 'hide_empty' => false, 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery array( 'key' => '_vc_viator_destination_id', 'value' => array_column( $results, 'id' ), 'compare' => 'IN', ), ), ) ); foreach ( is_wp_error( $terms ) ? array() : $terms as $term ) { $existing[ (string) get_term_meta( $term->term_id, '_vc_viator_destination_id', true ) ] = $term->slug; } } foreach ( $results as &$result ) { $result['slug'] = isset( $existing[ $result['id'] ] ) ? $existing[ $result['id'] ] : sanitize_title( $result['name'] ); } unset( $result ); wp_send_json_success( array( 'results' => $results ) ); } public static function defaults() { return array( 'api_key' => '', 'api_base_url' => 'https://api.viator.com/partner', 'language' => 'en-US', 'currency' => 'USD', 'timeout' => 20, 'default_post_status' => 'publish', 'contact_email' => '', 'hero_image' => '', 'hero_image_id' => 0, 'single_hero_figure_id' => 0, 'hero_slides' => '', 'crawl_destinations' => '', 'rate_limit_per_minute' => 25, 'products_per_page' => 50, 'pages_per_run' => 10, 'fetch_full_detail' => 0, 'detail_batch_size' => 15, 'log_every' => 10, 'automatic_sync' => 0, 'debug_logging' => 0, ); } public static function admin_menu() { add_options_page( __( 'Viator Collector', 'viator-collector' ), __( 'Viator Collector', 'viator-collector' ), 'manage_options', 'viator-collector', array( __CLASS__, 'render_page' ) ); } public static function register_settings() { register_setting( 'vc_settings_group', 'vc_settings', array( 'type' => 'array', 'sanitize_callback' => array( __CLASS__, 'sanitize_settings' ), 'default' => self::defaults(), ) ); } public static function sanitize_settings( $input ) { $input = is_array( $input ) ? $input : array(); $defaults = self::defaults(); $output = array( 'api_key' => sanitize_text_field( $input['api_key'] ?? '' ), 'api_base_url' => esc_url_raw( $input['api_base_url'] ?? $defaults['api_base_url'] ), 'language' => sanitize_text_field( $input['language'] ?? 'en-US' ), 'currency' => strtoupper( sanitize_text_field( $input['currency'] ?? 'USD' ) ), 'timeout' => max( 5, absint( $input['timeout'] ?? 20 ) ), 'default_post_status' => sanitize_key( $input['default_post_status'] ?? 'publish' ), 'contact_email' => sanitize_email( $input['contact_email'] ?? '' ), 'hero_image' => esc_url_raw( $input['hero_image'] ?? '' ), 'hero_image_id' => absint( $input['hero_image_id'] ?? 0 ), 'single_hero_figure_id' => absint( $input['single_hero_figure_id'] ?? 0 ), 'hero_slides' => self::sanitize_id_list( $input['hero_slides'] ?? '' ), 'crawl_destinations' => self::sanitize_id_list( $input['crawl_destinations'] ?? '' ), 'rate_limit_per_minute' => max( 1, min( 60, absint( $input['rate_limit_per_minute'] ?? 25 ) ) ), 'products_per_page' => max( 1, min( 50, absint( $input['products_per_page'] ?? 50 ) ) ), 'pages_per_run' => max( 1, min( 100, absint( $input['pages_per_run'] ?? 10 ) ) ), 'fetch_full_detail' => ! empty( $input['fetch_full_detail'] ) ? 1 : 0, 'detail_batch_size' => max( 1, min( 25, absint( $input['detail_batch_size'] ?? 15 ) ) ), 'log_every' => max( 1, min( 1000, absint( $input['log_every'] ?? 10 ) ) ), 'automatic_sync' => ! empty( $input['automatic_sync'] ) ? 1 : 0, 'debug_logging' => ! empty( $input['debug_logging'] ) ? 1 : 0, ); if ( ! in_array( $output['default_post_status'], array( 'publish', 'draft', 'pending' ), true ) ) { $output['default_post_status'] = 'publish'; } return $output; } public static function render_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } $options = wp_parse_args( vc_get_option( '', array() ), self::defaults() ); $notice = isset( $_GET['vc_notice'] ) ? sanitize_text_field( wp_unslash( $_GET['vc_notice'] ) ) : ''; $status = VC_Cron::status(); ?>