|
|
@@ -0,0 +1,684 @@
|
|
|
+<?php
|
|
|
+/**
|
|
|
+ * Plugin Name: EKSRelay API
|
|
|
+ * Description: Dedykowane REST API dla EKSRelay – get_car_data i get_product_compatibility.
|
|
|
+ * Otwarte endpointy REST (bez autoryzacji) – odpowiedniki nopriv AJAX.
|
|
|
+ * Wdróż ten plik na serwer WP jako: /wp-content/mu-plugins/eksrelay_api.php
|
|
|
+ * Version: 1.0.0
|
|
|
+ */
|
|
|
+
|
|
|
+if ( ! defined( 'ABSPATH' ) ) {
|
|
|
+ exit;
|
|
|
+}
|
|
|
+
|
|
|
+// ═══════════════════════════════════════════════════════════════════
|
|
|
+// Rejestracja tras REST
|
|
|
+// ═══════════════════════════════════════════════════════════════════
|
|
|
+
|
|
|
+add_action( 'rest_api_init', function () {
|
|
|
+ register_rest_route( 'eksrelay/v1', '/car-data', [
|
|
|
+ 'methods' => 'POST',
|
|
|
+ 'callback' => 'eksrelay_car_data',
|
|
|
+ 'permission_callback' => '__return_true',
|
|
|
+ ] );
|
|
|
+
|
|
|
+ register_rest_route( 'eksrelay/v1', '/product-compatibility', [
|
|
|
+ 'methods' => 'POST',
|
|
|
+ 'callback' => 'eksrelay_product_compatibility',
|
|
|
+ 'permission_callback' => '__return_true',
|
|
|
+ ] );
|
|
|
+} );
|
|
|
+
|
|
|
+// ═══════════════════════════════════════════════════════════════════
|
|
|
+// Handler: POST /wp-json/eksrelay/v1/car-data
|
|
|
+//
|
|
|
+// Body JSON: { car_year, car_brand?, car_model?, car_engine? }
|
|
|
+// ═══════════════════════════════════════════════════════════════════
|
|
|
+
|
|
|
+function eksrelay_car_data( WP_REST_Request $request ) {
|
|
|
+ $body = $request->get_json_params() ?: [];
|
|
|
+
|
|
|
+ if ( empty( $body['car_year'] ) ) {
|
|
|
+ return [ 'error' => 'car_year jest wymagany' ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $car_year = intval( sanitize_text_field( $body['car_year'] ) );
|
|
|
+ $has_brand = ! empty( $body['car_brand'] );
|
|
|
+ $has_model = ! empty( $body['car_model'] );
|
|
|
+ $car_brand = false;
|
|
|
+ $car_model = false;
|
|
|
+
|
|
|
+ if ( ! $has_brand && ! $has_model ) {
|
|
|
+ return [ 'error' => 'car_brand lub car_model jest wymagany' ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // ── Tylko brand, bez modelu ──────────────────────────────────────
|
|
|
+ if ( $has_brand && ! $has_model ) {
|
|
|
+ $car_brand = eksrelay_replace_ascii( trim( sanitize_text_field( $body['car_brand'] ) ) );
|
|
|
+ $termIds = get_terms( [ 'name__like' => $car_brand, 'parent' => 0, 'fields' => 'ids' ] );
|
|
|
+
|
|
|
+ if ( count( $termIds ) === 1 ) {
|
|
|
+ $car_models = eksrelay_models_for_brand_year( $termIds, $car_year );
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_model', 'options' => $car_models, 'filtered' => false ];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_brand', 'options' => eksrelay_all_brands(), 'filtered' => false ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // ── Tylko model, bez brandu ─────────────────────────────────────
|
|
|
+ if ( $has_model && ! $has_brand ) {
|
|
|
+ $car_model = eksrelay_replace_ascii( trim( sanitize_text_field( $body['car_model'] ) ) );
|
|
|
+ $termIds = get_terms( [ 'name__like' => $car_model, 'fields' => 'ids' ] );
|
|
|
+
|
|
|
+ // exact match → auto-wybierz
|
|
|
+ foreach ( $termIds as $tid ) {
|
|
|
+ $term = get_term_by( 'id', $tid, 'car_model' );
|
|
|
+ if ( $term && eksrelay_replace_ascii( $term->name ) === $car_model ) {
|
|
|
+ $termIds = [ $term->term_id ];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( count( $termIds ) === 1 ) {
|
|
|
+ $term = get_term( $termIds[0] );
|
|
|
+ if ( ! is_wp_error( $term ) && $term->parent !== 0 ) {
|
|
|
+ $parent = get_term( $term->parent );
|
|
|
+ if ( ! is_wp_error( $parent ) ) {
|
|
|
+ $car_brand = $parent->name;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return [ 'error' => 'nie znaleziono takiego modelu', 'car_model' => $car_model ];
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $models = [];
|
|
|
+ foreach ( $termIds as $tid ) {
|
|
|
+ $t = get_term_by( 'id', $tid, 'car_model' );
|
|
|
+ if ( $t ) {
|
|
|
+ $models[] = $t->name;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ( $models ) {
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_model', 'options' => $models, 'filtered' => true ];
|
|
|
+ }
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_brand', 'options' => eksrelay_all_brands(), 'filtered' => false ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ── Mamy oba ────────────────────────────────────────────────────
|
|
|
+ if ( ! $car_brand ) {
|
|
|
+ $car_brand = eksrelay_replace_ascii( trim( sanitize_text_field( $body['car_brand'] ) ) );
|
|
|
+ }
|
|
|
+ if ( ! $car_model ) {
|
|
|
+ $car_model = eksrelay_replace_ascii( trim( sanitize_text_field( $body['car_model'] ) ) );
|
|
|
+ }
|
|
|
+ $car_engine = eksrelay_replace_ascii( trim( sanitize_text_field( $body['car_engine'] ?? '' ) ) );
|
|
|
+
|
|
|
+ $termIds = get_terms( [ 'name__like' => $car_brand, 'fields' => 'ids' ] );
|
|
|
+ $termIds2 = get_terms( [ 'name__like' => $car_model, 'fields' => 'ids' ] );
|
|
|
+
|
|
|
+ if ( ! count( $termIds ) ) {
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_brand', 'options' => eksrelay_all_brands(), 'filtered' => false ];
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ! count( $termIds2 ) ) {
|
|
|
+ if ( count( $termIds ) === 1 ) {
|
|
|
+ $car_models = eksrelay_models_for_brand_year( $termIds, $car_year );
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_model', 'options' => $car_models, 'filtered' => false ];
|
|
|
+ }
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_brand', 'options' => eksrelay_all_brands(), 'filtered' => false ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $query = new WP_Query( [
|
|
|
+ 'post_type' => 'car',
|
|
|
+ 'posts_per_page' => -1,
|
|
|
+ 'tax_query' => [
|
|
|
+ 'relation' => 'AND',
|
|
|
+ [ 'taxonomy' => 'car_model', 'field' => 'id', 'terms' => $termIds ],
|
|
|
+ [ 'taxonomy' => 'car_model', 'field' => 'id', 'terms' => $termIds2 ],
|
|
|
+ [ 'taxonomy' => 'car_production_year', 'field' => 'slug', 'terms' => (string) $car_year ],
|
|
|
+ ],
|
|
|
+ ] );
|
|
|
+
|
|
|
+ $cars = $query->get_posts();
|
|
|
+ $engine_info = eksrelay_get_engines_info( $cars, true, $car_year );
|
|
|
+
|
|
|
+ if ( ! $cars ) {
|
|
|
+ return [
|
|
|
+ 'error' => 'nie znaleziono auta, ' . get_option(
|
|
|
+ 'aiac_tool_get_car_data_no_car',
|
|
|
+ 'Orientacyjnie do 1994 roku włącznie powinien pasować gaz R12, dla aut 1995-2016 gaz R134A a dla aut od 2016 roku gaz R1234YF'
|
|
|
+ ),
|
|
|
+ 'car_brand' => $car_brand,
|
|
|
+ 'car_model' => $car_model,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $engine_names = array_column( $engine_info, 'name' );
|
|
|
+
|
|
|
+ if ( count( $engine_info ) === 1 ) {
|
|
|
+ $car_engine = $engine_info[0]['name'];
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( count( $engine_info ) > 1 && ! $car_engine ) {
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_engine', 'options' => $engine_names, 'filtered' => false ];
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach ( $engine_info as $eng ) {
|
|
|
+ if ( strtolower( trim( $eng['name'] ) ) !== strtolower( trim( $car_engine ) ) ) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $car_id = intval( $eng['id'] );
|
|
|
+ $maybe_diff = get_field( 'custom_ac', $car_id );
|
|
|
+
|
|
|
+ $gas_types = array_unique( array_filter( [
|
|
|
+ get_field( 'ac_gas_type', $car_id ),
|
|
|
+ $maybe_diff ? get_field( 'ac_gas_type_2', $car_id ) : '',
|
|
|
+ ] ) );
|
|
|
+
|
|
|
+ $year_term = get_terms( [ 'taxonomy' => 'car_production_year', 'name__like' => $car_year ] );
|
|
|
+ $brand_term = $termIds ? get_term( $termIds[0] ) : false;
|
|
|
+ $model_term = $termIds2 ? get_term( $termIds2[0] ) : false;
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ 'success' => true,
|
|
|
+ 'selected_car' => [
|
|
|
+ 'ek_ac_gas_type' => implode( ',', $gas_types ),
|
|
|
+ 'ek_brand_id' => $termIds[0] ?? '',
|
|
|
+ 'ek_brand' => ( $brand_term && ! is_wp_error( $brand_term ) ) ? $brand_term->name : $car_brand,
|
|
|
+ 'ek_car_id' => $car_id,
|
|
|
+ 'ek_engine_type' => $eng['name'],
|
|
|
+ 'ek_info' => '',
|
|
|
+ 'ek_model_id' => $termIds2[0] ?? '',
|
|
|
+ 'ek_model' => ( $model_term && ! is_wp_error( $model_term ) ) ? $model_term->name : $car_model,
|
|
|
+ 'ek_year_id' => ( ! is_wp_error( $year_term ) && $year_term ) ? $year_term[0]->term_id : '',
|
|
|
+ 'ek_year' => $car_year,
|
|
|
+ ],
|
|
|
+ 'shop_url' => $eng['url'],
|
|
|
+ 'adapters' => get_field( 'adapters', $car_id ) ?: false,
|
|
|
+ 'ac_gas_type' => get_field( 'ac_gas_type', $car_id ),
|
|
|
+ 'ac_gas_amount' => ( get_field( 'ac_gas_amount', $car_id ) ?: '-' ) . ' g',
|
|
|
+ 'ac_ports_count' => intval( get_field( 'ac_ports_count', $car_id ) ),
|
|
|
+ 'ac_oil' => get_field( 'ac_oil', $car_id ),
|
|
|
+ 'ac_oil_amount' => ( get_field( 'ac_oil_amount', $car_id ) ?: '-' ) . ' cm3',
|
|
|
+ 'ac_clutch' => get_field( 'ac_clutch', $car_id ),
|
|
|
+ 'maybe_different_layout' => $maybe_diff,
|
|
|
+ ];
|
|
|
+
|
|
|
+ if ( $maybe_diff ) {
|
|
|
+ $data['different_layout_info'] = get_field( 'custom_ac_info', $car_id ) ?: '';
|
|
|
+ $data['different_layout_adapters'] = get_field( 'adapters_2', $car_id ) ?: false;
|
|
|
+ $data['different_layout_ac_gas_type'] = get_field( 'ac_gas_type_2', $car_id );
|
|
|
+ $data['different_layout_ac_gas_amount'] = ( get_field( 'ac_gas_amount_2', $car_id ) ?: '-' ) . ' g';
|
|
|
+ $data['different_layout_ac_ports_count'] = get_field( 'ac_ports_count_2', $car_id );
|
|
|
+ $data['different_layout_ac_oil'] = get_field( 'ac_oil_2', $car_id );
|
|
|
+ $data['different_layout_ac_oil_amount'] = ( get_field( 'ac_oil_amount_2', $car_id ) ?: '-' ) . ' cm3';
|
|
|
+ $data['different_layout_ac_clutch'] = get_field( 'ac_clutch_2', $car_id );
|
|
|
+ }
|
|
|
+
|
|
|
+ return $data;
|
|
|
+ }
|
|
|
+
|
|
|
+ // podany silnik nie pasuje do żadnego na liście → pokaż opcje
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_engine', 'options' => $engine_names, 'filtered' => false ];
|
|
|
+}
|
|
|
+
|
|
|
+// ═══════════════════════════════════════════════════════════════════
|
|
|
+// Handler: POST /wp-json/eksrelay/v1/product-compatibility
|
|
|
+//
|
|
|
+// Body JSON: { car_year, car_brand?, car_model?, car_engine?, product_name? }
|
|
|
+// ═══════════════════════════════════════════════════════════════════
|
|
|
+
|
|
|
+function eksrelay_product_compatibility( WP_REST_Request $request ) {
|
|
|
+ $body = $request->get_json_params() ?: [];
|
|
|
+
|
|
|
+ if ( empty( $body['car_year'] ) ) {
|
|
|
+ return [ 'error' => 'car_year jest wymagany' ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $lang = sanitize_text_field( $body['lang'] ?? 'pl' );
|
|
|
+ $car_year = intval( sanitize_text_field( $body['car_year'] ) );
|
|
|
+ $has_brand = ! empty( $body['car_brand'] );
|
|
|
+ $has_model = ! empty( $body['car_model'] );
|
|
|
+ $car_brand = false;
|
|
|
+ $car_model = false;
|
|
|
+
|
|
|
+ // ── Tylko brand ─────────────────────────────────────────────────
|
|
|
+ if ( $has_brand && ! $has_model ) {
|
|
|
+ $car_brand = eksrelay_replace_ascii( trim( sanitize_text_field( $body['car_brand'] ) ) );
|
|
|
+ $termIds = get_terms( [ 'name__like' => $car_brand, 'parent' => 0, 'fields' => 'ids' ] );
|
|
|
+
|
|
|
+ if ( count( $termIds ) === 1 ) {
|
|
|
+ $car_models = eksrelay_models_for_brand_year( $termIds, $car_year );
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_model', 'options' => $car_models, 'filtered' => false ];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_brand', 'options' => eksrelay_all_brands(), 'filtered' => false ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // ── Tylko model ─────────────────────────────────────────────────
|
|
|
+ if ( $has_model && ! $has_brand ) {
|
|
|
+ $car_model = eksrelay_replace_ascii( trim( sanitize_text_field( $body['car_model'] ) ) );
|
|
|
+ $termIds = get_terms( [ 'name__like' => $car_model, 'fields' => 'ids' ] );
|
|
|
+
|
|
|
+ if ( count( $termIds ) === 1 ) {
|
|
|
+ $term = get_term( $termIds[0] );
|
|
|
+ if ( ! is_wp_error( $term ) && $term->parent !== 0 ) {
|
|
|
+ $parent = get_term( $term->parent );
|
|
|
+ if ( ! is_wp_error( $parent ) ) {
|
|
|
+ $car_brand = $parent->name;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return [ 'error' => 'nie znaleziono takiego modelu', 'car_model' => $car_model ];
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $models = [];
|
|
|
+ foreach ( $termIds as $tid ) {
|
|
|
+ $t = get_term_by( 'id', $tid, 'car_model' );
|
|
|
+ if ( $t ) {
|
|
|
+ $models[] = $t->name;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ( $models ) {
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_model', 'options' => $models, 'filtered' => true ];
|
|
|
+ }
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_brand', 'options' => eksrelay_all_brands(), 'filtered' => false ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ! $has_brand && ! $has_model ) {
|
|
|
+ return [ 'error' => 'car_brand lub car_model jest wymagany' ];
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ! $car_brand ) {
|
|
|
+ $car_brand = eksrelay_replace_ascii( trim( sanitize_text_field( $body['car_brand'] ) ) );
|
|
|
+ }
|
|
|
+ if ( ! $car_model ) {
|
|
|
+ $car_model = eksrelay_replace_ascii( trim( sanitize_text_field( $body['car_model'] ) ) );
|
|
|
+ }
|
|
|
+
|
|
|
+ $car_engine = eksrelay_replace_ascii( trim( sanitize_text_field( $body['car_engine'] ?? '' ) ) );
|
|
|
+ $product_name = eksrelay_replace_ascii( trim( sanitize_text_field( $body['product_name'] ?? '' ) ) );
|
|
|
+
|
|
|
+ // ── Znajdź produkt ──────────────────────────────────────────────
|
|
|
+ $product = false;
|
|
|
+
|
|
|
+ if ( $product_name ) {
|
|
|
+ $products = eksrelay_search_products_by_name( $product_name );
|
|
|
+
|
|
|
+ if ( count( $products ) > 1 ) {
|
|
|
+ // exact match → auto-wybierz
|
|
|
+ foreach ( $products as $p ) {
|
|
|
+ if ( eksrelay_replace_ascii( strtolower( trim( $p->get_title() ) ) ) === strtolower( $product_name ) ) {
|
|
|
+ $product = $p;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ( ! $product ) {
|
|
|
+ return [
|
|
|
+ 'error' => 'options',
|
|
|
+ 'field' => 'product_name',
|
|
|
+ 'options' => array_map( fn( $p ) => $p->get_title(), $products ),
|
|
|
+ 'filtered' => true,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ } elseif ( count( $products ) === 1 ) {
|
|
|
+ $product = $products[0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ── Znajdź auto ─────────────────────────────────────────────────
|
|
|
+ $termIds = get_terms( [ 'name__like' => $car_brand, 'fields' => 'ids' ] );
|
|
|
+ $termIds2 = get_terms( [ 'name__like' => $car_model, 'fields' => 'ids' ] );
|
|
|
+
|
|
|
+ // Uwaga: celowo bez filtra roku – engine_info filtruje rok wewnętrznie
|
|
|
+ $query = new WP_Query( [
|
|
|
+ 'post_type' => 'car',
|
|
|
+ 'posts_per_page' => -1,
|
|
|
+ 'tax_query' => [
|
|
|
+ 'relation' => 'AND',
|
|
|
+ [ 'taxonomy' => 'car_model', 'field' => 'id', 'terms' => $termIds ],
|
|
|
+ [ 'taxonomy' => 'car_model', 'field' => 'id', 'terms' => $termIds2 ],
|
|
|
+ ],
|
|
|
+ ] );
|
|
|
+
|
|
|
+ $cars = $query->get_posts();
|
|
|
+ $engine_info = eksrelay_get_engines_info( $cars, false, $car_year );
|
|
|
+
|
|
|
+ if ( ! $cars ) {
|
|
|
+ return [ 'error' => 'nie znaleziono takiego samochodu', 'car_brand' => $car_brand, 'car_model' => $car_model ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $engine_names = array_column( $engine_info, 'name' );
|
|
|
+
|
|
|
+ if ( count( $engine_info ) === 1 ) {
|
|
|
+ $car_engine = $engine_info[0]['name'];
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( count( $engine_info ) > 1 && ! $car_engine ) {
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_engine', 'options' => $engine_names, 'filtered' => false ];
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach ( $engine_info as $eng ) {
|
|
|
+ if ( strtolower( trim( $eng['name'] ) ) !== strtolower( trim( $car_engine ) ) ) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $engine_gas = array_values( array_filter( [ $eng['ac_gas_type'] ?? '', $eng['ac_gas_type_2'] ?? '' ] ) );
|
|
|
+ $engine_adapters = array_values( array_filter( [ $eng['adapters'] ?? '', $eng['adapters_2'] ?? '' ] ) );
|
|
|
+ if ( ! $engine_gas ) $engine_gas = [ 'no-gas' ];
|
|
|
+ if ( ! $engine_adapters ) $engine_adapters = [ 'no' ];
|
|
|
+
|
|
|
+ if ( $product ) {
|
|
|
+ // ── Sprawdzenie kompatybilności konkretnego produktu ─────────
|
|
|
+ $attributes = eksrelay_product_attributes( $product );
|
|
|
+ foreach ( $attributes as $k => $arr ) {
|
|
|
+ $attributes[ $k ] = array_map( fn( $slug ) => str_replace( "-{$lang}", '', $slug ), $arr );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ! isset( $attributes['pa_rg'] ) || empty( $attributes['pa_rg'] ) ) $attributes['pa_rg'] = [ 'no-gas' ];
|
|
|
+ if ( ! isset( $attributes['pa_ra'] ) || empty( $attributes['pa_ra'] ) ) $attributes['pa_ra'] = [ 'no' ];
|
|
|
+
|
|
|
+ $gas_fit = count( array_intersect( $engine_gas, $attributes['pa_rg'] ) ) > 0;
|
|
|
+ $adapter_fit = count( array_intersect( $engine_adapters, $attributes['pa_ra'] ) ) > 0;
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => true,
|
|
|
+ 'fit' => $gas_fit && $adapter_fit,
|
|
|
+ 'gas_fit' => $gas_fit,
|
|
|
+ 'adapter_fit' => $adapter_fit,
|
|
|
+ 'selected_engine' => $eng,
|
|
|
+ 'selected_product' => [
|
|
|
+ 'id' => $product->get_id(),
|
|
|
+ 'title' => $product->get_title(),
|
|
|
+ 'type' => $product->get_type(),
|
|
|
+ 'attributes' => $attributes,
|
|
|
+ ],
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // ── Brak konkretnego produktu – lista wszystkich kompatybilnych ─
|
|
|
+ $all_products = wc_get_products( [
|
|
|
+ 'status' => 'publish',
|
|
|
+ 'visibility' => 'visible',
|
|
|
+ 'limit' => -1,
|
|
|
+ 'orderby' => 'name',
|
|
|
+ ] );
|
|
|
+
|
|
|
+ $compatible = [];
|
|
|
+ foreach ( $all_products as $p ) {
|
|
|
+ $attrs = eksrelay_product_attributes( $p );
|
|
|
+ foreach ( $attrs as $k => $arr ) {
|
|
|
+ $attrs[ $k ] = array_map( fn( $slug ) => str_replace( "-{$lang}", '', $slug ), $arr );
|
|
|
+ }
|
|
|
+ $p_gas = ( isset( $attrs['pa_rg'] ) && ! empty( $attrs['pa_rg'] ) ) ? $attrs['pa_rg'] : [ 'no-gas' ];
|
|
|
+ $p_adapters = ( isset( $attrs['pa_ra'] ) && ! empty( $attrs['pa_ra'] ) ) ? $attrs['pa_ra'] : [ 'no' ];
|
|
|
+
|
|
|
+ if (
|
|
|
+ count( array_intersect( $engine_gas, $p_gas ) ) > 0 &&
|
|
|
+ count( array_intersect( $engine_adapters, $p_adapters ) ) > 0
|
|
|
+ ) {
|
|
|
+ $compatible[] = [
|
|
|
+ 'id' => $p->get_id(),
|
|
|
+ 'title' => $p->get_title(),
|
|
|
+ 'price' => $p->get_price(),
|
|
|
+ 'permalink' => get_permalink( $p->get_id() ),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => true,
|
|
|
+ 'compatible_products' => $compatible,
|
|
|
+ 'selected_engine' => $eng,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [ 'error' => 'options', 'field' => 'car_engine', 'options' => $engine_names, 'filtered' => false ];
|
|
|
+}
|
|
|
+
|
|
|
+// ═══════════════════════════════════════════════════════════════════
|
|
|
+// Pomocnicze funkcje wewnętrzne
|
|
|
+// ═══════════════════════════════════════════════════════════════════
|
|
|
+
|
|
|
+/**
|
|
|
+ * Zwraca listę modeli dla danej marki (termIds) i roku produkcji.
|
|
|
+ */
|
|
|
+function eksrelay_models_for_brand_year( array $termIds, int $car_year ): array {
|
|
|
+ $query = new WP_Query( [
|
|
|
+ 'post_type' => 'car',
|
|
|
+ 'posts_per_page' => -1,
|
|
|
+ 'tax_query' => [
|
|
|
+ 'relation' => 'AND',
|
|
|
+ [ 'taxonomy' => 'car_model', 'field' => 'id', 'terms' => $termIds ],
|
|
|
+ [ 'taxonomy' => 'car_production_year', 'field' => 'slug', 'terms' => [ (string) $car_year ] ],
|
|
|
+ ],
|
|
|
+ ] );
|
|
|
+
|
|
|
+ $car_models = [];
|
|
|
+ foreach ( $query->get_posts() as $car ) {
|
|
|
+ foreach ( wp_get_post_terms( $car->ID, 'car_model' ) as $term ) {
|
|
|
+ if ( ! in_array( $term->name, $car_models, true ) && $term->parent !== 0 ) {
|
|
|
+ $car_models[] = $term->name;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $car_models;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Zwraca listę wszystkich marek aut (terminy car_model z parent=0).
|
|
|
+ */
|
|
|
+function eksrelay_all_brands(): array {
|
|
|
+ return (array) get_terms( [
|
|
|
+ 'taxonomy' => 'car_model',
|
|
|
+ 'parent' => 0,
|
|
|
+ 'fields' => 'names',
|
|
|
+ 'hide_empty' => true,
|
|
|
+ ] );
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Zwraca info o silnikach dla podanych postów 'car'.
|
|
|
+ *
|
|
|
+ * Parametr $prefiltered:
|
|
|
+ * true – WP_Query już przefiltrował po roku przez taxonomy (get_car_data)
|
|
|
+ * false – rok musi być sprawdzony wewnętrznie przez pola ACF year_from / year_to (get_product_compatibility)
|
|
|
+ *
|
|
|
+ * Nazwa silnika jest budowana z pól ACF: engine_type, engine_size (ccm), engine_power_kw, engine_power_km.
|
|
|
+ * Format: "B 1.8 - 141 kW / 192 KM"
|
|
|
+ *
|
|
|
+ * Zakres roku pochodzi z pól ACF year_from / year_to (przechowywane jako term_id taksonomii car_production_year).
|
|
|
+ *
|
|
|
+ * Dodatkowe warianty silnika mogą być przechowywane w ACF repeaterze 'engines' na poście car.
|
|
|
+ */
|
|
|
+function eksrelay_get_engines_info( array $cars, bool $prefiltered, int $car_year ): array {
|
|
|
+ $engines = [];
|
|
|
+ $seen = [];
|
|
|
+
|
|
|
+ foreach ( $cars as $car ) {
|
|
|
+ $car_id = $car->ID;
|
|
|
+
|
|
|
+ // ── Filtrowanie zakresu roku przez pola ACF year_from / year_to ─
|
|
|
+ if ( $car_year ) {
|
|
|
+ $year_from_id = get_field( 'year_from', $car_id );
|
|
|
+ $year_to_id = get_field( 'year_to', $car_id );
|
|
|
+
|
|
|
+ $year_from = 0;
|
|
|
+ $year_to = 9999;
|
|
|
+
|
|
|
+ if ( $year_from_id ) {
|
|
|
+ $t = get_term( (int) $year_from_id, 'car_production_year' );
|
|
|
+ if ( $t && ! is_wp_error( $t ) ) {
|
|
|
+ $year_from = (int) $t->slug;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ( $year_to_id ) {
|
|
|
+ $t = get_term( (int) $year_to_id, 'car_production_year' );
|
|
|
+ if ( $t && ! is_wp_error( $t ) ) {
|
|
|
+ $year_to = (int) $t->slug;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( $car_year < $year_from || $car_year > $year_to ) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ── Budowanie nazwy silnika z pól ACF ────────────────────────────
|
|
|
+ $engine_type = (string) ( get_field( 'engine_type', $car_id ) ?: '' );
|
|
|
+ $engine_size_cc = (float) ( get_field( 'engine_size', $car_id ) ?: 0 );
|
|
|
+ $power_kw = (string) ( get_field( 'engine_power_kw', $car_id ) ?: '' );
|
|
|
+ $power_km = (string) ( get_field( 'engine_power_km', $car_id ) ?: '' );
|
|
|
+ $engine_size = number_format( $engine_size_cc / 1000, 1 );
|
|
|
+ $name = "{$engine_type} {$engine_size} - {$power_kw} kW / {$power_km} KM";
|
|
|
+
|
|
|
+ // ── Typ gazu i adaptery ──────────────────────────────────────────
|
|
|
+ $ac_gas_type = (string) ( get_field( 'ac_gas_type', $car_id ) ?: '' );
|
|
|
+ $ac_gas_type_2 = (string) ( get_field( 'ac_gas_type_2', $car_id ) ?: '' );
|
|
|
+ $adapters_raw = get_field( 'adapters', $car_id );
|
|
|
+ $adapters_raw2 = get_field( 'adapters_2', $car_id );
|
|
|
+ $adapters = is_array( $adapters_raw ) ? ( implode( ',', $adapters_raw ) ?: 'no' ) : (string) ( $adapters_raw ?: 'no' );
|
|
|
+ $adapters_2 = is_array( $adapters_raw2 ) ? implode( ',', $adapters_raw2 ) : (string) ( $adapters_raw2 ?: '' );
|
|
|
+
|
|
|
+ // ── Korekty gazu na podstawie roku (sanity check) ────────────────
|
|
|
+ if ( $car_year ) {
|
|
|
+ if ( $car_year <= 1994 && $ac_gas_type === '' ) {
|
|
|
+ $ac_gas_type = 'r12';
|
|
|
+ } elseif ( $car_year >= 2017 && $ac_gas_type === '' ) {
|
|
|
+ $ac_gas_type = 'r1234yf';
|
|
|
+ } elseif ( $car_year >= 1995 && $car_year <= 2016 && $ac_gas_type === '' ) {
|
|
|
+ $ac_gas_type = 'r134a';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ── Główny silnik ────────────────────────────────────────────────
|
|
|
+ $key = mb_strtolower( $name );
|
|
|
+ if ( ! isset( $seen[ $key ] ) ) {
|
|
|
+ $seen[ $key ] = true;
|
|
|
+ $engines[] = [
|
|
|
+ 'name' => $name,
|
|
|
+ 'id' => $car_id,
|
|
|
+ 'url' => get_permalink( $car_id ),
|
|
|
+ 'ac_gas_type' => $ac_gas_type,
|
|
|
+ 'ac_gas_type_2' => $ac_gas_type_2,
|
|
|
+ 'adapters' => $adapters,
|
|
|
+ 'adapters_2' => $adapters_2,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // ── ACF repeater 'engines' – dodatkowe warianty silnika ──────────
|
|
|
+ $extra_engines = get_field( 'engines', $car_id );
|
|
|
+ if ( is_array( $extra_engines ) ) {
|
|
|
+ foreach ( $extra_engines as $extra ) {
|
|
|
+ $e_type = (string) ( $extra['engine_type'] ?? '' );
|
|
|
+ $e_size_cc = (float) ( $extra['engine_size'] ?? 0 );
|
|
|
+ $e_kw = (string) ( $extra['engine_power_kw'] ?? '' );
|
|
|
+ $e_km = (string) ( $extra['engine_power_km'] ?? '' );
|
|
|
+ $e_size = number_format( $e_size_cc / 1000, 1 );
|
|
|
+ $e_name = "{$e_type} {$e_size} - {$e_kw} kW / {$e_km} KM";
|
|
|
+
|
|
|
+ $e_gas = (string) ( $extra['ac_gas_type'] ?? $ac_gas_type );
|
|
|
+ $e_gas_2 = (string) ( $extra['ac_gas_type_2'] ?? $ac_gas_type_2 );
|
|
|
+ $e_adp_r = $extra['adapters'] ?? null;
|
|
|
+ $e_adp_r2 = $extra['adapters_2'] ?? null;
|
|
|
+ $e_adp = is_array( $e_adp_r ) ? implode( ',', $e_adp_r ) : (string) ( $e_adp_r ?: $adapters );
|
|
|
+ $e_adp_2 = is_array( $e_adp_r2 ) ? implode( ',', $e_adp_r2 ) : (string) ( $e_adp_r2 ?: $adapters_2 );
|
|
|
+
|
|
|
+ $e_key = mb_strtolower( $e_name );
|
|
|
+ if ( ! isset( $seen[ $e_key ] ) ) {
|
|
|
+ $seen[ $e_key ] = true;
|
|
|
+ $engines[] = [
|
|
|
+ 'name' => $e_name,
|
|
|
+ 'id' => $car_id,
|
|
|
+ 'url' => get_permalink( $car_id ),
|
|
|
+ 'ac_gas_type' => $e_gas,
|
|
|
+ 'ac_gas_type_2' => $e_gas_2,
|
|
|
+ 'adapters' => $e_adp,
|
|
|
+ 'adapters_2' => $e_adp_2,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $engines;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Zwraca atrybuty produktu WC jako [ slug_atrybutu => [ slug_wartości, ... ] ].
|
|
|
+ * Używane do sprawdzania pa_rg (typ gazu) i pa_ra (adapter).
|
|
|
+ *
|
|
|
+ * Implementacja wzorowana na aiac_get_product_attributes_as_str_arr() z aiac_chat_api.php:
|
|
|
+ * – dla wariantów (variation): [ $attr_val ] (pojedyncza wartość ze zmiennej produktowej)
|
|
|
+ * – dla pozostałych typów: $attr_obj->get_slugs()
|
|
|
+ */
|
|
|
+function eksrelay_product_attributes( WC_Product $product ): array {
|
|
|
+ $result = [];
|
|
|
+ $attributes = $product->get_attributes();
|
|
|
+
|
|
|
+ if ( $product->is_type( 'variation' ) ) {
|
|
|
+ foreach ( $attributes as $attr_key => $attr_val ) {
|
|
|
+ $result[ $attr_key ] = [ $attr_val ];
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ foreach ( $attributes as $attr_key => $attr_obj ) {
|
|
|
+ $result[ $attr_key ] = $attr_obj->get_slugs();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $result;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Wyszukuje produkty WooCommerce po fragmencie nazwy (fulltext search).
|
|
|
+ */
|
|
|
+function eksrelay_search_products_by_name( string $product_name ): array {
|
|
|
+ add_filter( 'woocommerce_product_data_store_cpt_get_products_query', 'eksrelay_wc_query_like', 10, 2 );
|
|
|
+
|
|
|
+ $products = wc_get_products( [
|
|
|
+ 'status' => 'publish',
|
|
|
+ 'limit' => -1,
|
|
|
+ 'like' => $product_name,
|
|
|
+ ] );
|
|
|
+
|
|
|
+ remove_filter( 'woocommerce_product_data_store_cpt_get_products_query', 'eksrelay_wc_query_like', 10 );
|
|
|
+
|
|
|
+ return $products;
|
|
|
+}
|
|
|
+
|
|
|
+function eksrelay_wc_query_like( array $query, array $query_vars ): array {
|
|
|
+ if ( ! empty( $query_vars['like'] ) ) {
|
|
|
+ $query['s'] = esc_attr( $query_vars['like'] );
|
|
|
+ }
|
|
|
+ return $query;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Usuwa znaki diakrytyczne z ciągu znaków.
|
|
|
+ * Mapowanie identyczne z replace_ascii() w aiac_chat_api.php.
|
|
|
+ */
|
|
|
+function eksrelay_replace_ascii( string $string ): string {
|
|
|
+ $map = [
|
|
|
+ 'Š' => 'S', 'š' => 's', 'ë' => 'e', 'Ë' => 'E',
|
|
|
+ 'ä' => 'a', 'Ä' => 'A', 'ö' => 'o', 'Ö' => 'O',
|
|
|
+ 'ü' => 'u', 'Ü' => 'U', 'ß' => 'ss',
|
|
|
+ 'ó' => 'o', 'Ó' => 'O', 'ł' => 'l', 'Ł' => 'L',
|
|
|
+ 'ń' => 'n', 'Ń' => 'N', 'ć' => 'c', 'Ć' => 'C',
|
|
|
+ 'ę' => 'e', 'Ę' => 'E', 'ź' => 'z', 'Ź' => 'Z',
|
|
|
+ 'ż' => 'z', 'Ż' => 'Z', 'á' => 'a', 'Á' => 'A',
|
|
|
+ 'č' => 'c', 'Č' => 'C', 'ď' => 'd', 'Ď' => 'D',
|
|
|
+ 'é' => 'e', 'É' => 'E', 'ě' => 'e', 'Ě' => 'E',
|
|
|
+ 'í' => 'i', 'Í' => 'I', 'ň' => 'n', 'Ň' => 'N',
|
|
|
+ 'ř' => 'r', 'Ř' => 'R', 'ś' => 's', 'Ś' => 'S',
|
|
|
+ 'ť' => 't', 'Ť' => 'T', 'ů' => 'u', 'Ů' => 'U',
|
|
|
+ 'ý' => 'y', 'Ý' => 'Y', 'ą' => 'a', 'Ą' => 'A',
|
|
|
+ 'ș' => 's', 'Ș' => 'S', 'î' => 'i', 'Î' => 'I',
|
|
|
+ 'â' => 'a', 'Â' => 'A', 'ț' => 't', 'Ț' => 'T',
|
|
|
+ 'ğ' => 'g', 'Ğ' => 'G', 'İ' => 'I', 'ı' => 'i',
|
|
|
+ 'ç' => 'c', 'Ç' => 'C',
|
|
|
+ ];
|
|
|
+
|
|
|
+ return str_replace( array_keys( $map ), array_values( $map ), $string );
|
|
|
+}
|