MOON
Server: Apache
System: Linux server.royaltuning.hu 4.18.0-425.13.1.el8_7.x86_64 #1 SMP Tue Feb 21 04:20:52 EST 2023 x86_64
User: royaltuning (1001)
PHP: 8.2.30
Disabled: exec,passthru,shell_exec,system
Upload Files
File: /home/royaltuning/www/public/wp-content/plugins/izzo-kereso/includes/class-abfinder-rest.php
<?php
if (!defined('ABSPATH')) exit;

class ABFinder_REST {
	private $repo;
	private $parser;

	public function __construct(ABFinder_Repository $repo, ABFinder_Parser $parser) {
		$this->repo = $repo;
		$this->parser = $parser;
	}

	public function register() {
		add_action('rest_api_init', function () {
			register_rest_route('abfinder/v1', '/makes', [
				'methods' => 'GET',
				'permission_callback' => '__return_true',
				'callback' => [$this, 'makes'],
			]);

			register_rest_route('abfinder/v1', '/models', [
				'methods' => 'GET',
				'permission_callback' => '__return_true',
				'callback' => [$this, 'models'],
			]);

			register_rest_route('abfinder/v1', '/years', [
				'methods' => 'GET',
				'permission_callback' => '__return_true',
				'callback' => [$this, 'years'],
			]);

			register_rest_route('abfinder/v1', '/variants', [
				'methods' => 'GET',
				'permission_callback' => '__return_true',
				'callback' => [$this, 'variants'],
			]);

			register_rest_route('abfinder/v1', '/result', [
				'methods' => 'GET',
				'permission_callback' => '__return_true',
				'callback' => [$this, 'result'],
			]);
		});
	}

	public function makes(WP_REST_Request $req) {
		$q = (string)$req->get_param('search');
		$limit = intval($req->get_param('limit')) ?: 300;
		return rest_ensure_response([
			'items' => $this->repo->search_makes($q, $limit),
		]);
	}

	public function models(WP_REST_Request $req) {
		$make = (string)$req->get_param('make');
		$q = (string)$req->get_param('search');
		$limit = intval($req->get_param('limit')) ?: 300;
		return rest_ensure_response([
			'items' => $this->repo->search_models($make, $q, $limit),
		]);
	}

	public function years(WP_REST_Request $req) {
		$make = (string)$req->get_param('make');
		$model = (string)$req->get_param('model');
		return rest_ensure_response([
			'items' => $this->repo->get_years($make, $model),
		]);
	}

	public function variants(WP_REST_Request $req) {
		$make = (string)$req->get_param('make');
		$model = (string)$req->get_param('model');
		$year = intval($req->get_param('year'));

		$rows = $this->repo->get_variants($make, $model, $year);

		$items = array_map(function($r) {
			$sub = trim((string)($r['submodel'] ?? ''));
			$qual = trim((string)($r['qualifier'] ?? ''));
			$body = trim((string)($r['bodytype'] ?? ''));

			$labelParts = array_filter([$sub, $qual, $body]);
			$label = $labelParts ? implode(' / ', $labelParts) : 'Default';

			$key = ($sub ?? '') . '|||' . ($qual ?? '');
			return [
				'id' => intval($r['id']),
				'key' => $key,
				'label' => $label,
				'submodel' => $sub,
				'qualifier' => $qual,
				'bodytype' => $body,
			];
		}, $rows);

		// dedupe by key
		$dedup = [];
		foreach ($items as $it) {
			$dedup[$it['key']] = $it;
		}

		return rest_ensure_response([
			'items' => array_values($dedup),
		]);
	}

	public function result(WP_REST_Request $req) {
		$vehicle_id = intval($req->get_param('vehicle_id'));

		$make = (string)$req->get_param('make');
		$model = (string)$req->get_param('model');
		$year = intval($req->get_param('year'));
		$variantKey = (string)$req->get_param('variant_key');

		$vehicle = null;
		if ($vehicle_id > 0) {
			$vehicle = $this->repo->get_vehicle_by_id($vehicle_id);
		} else {
			$vehicle = $this->repo->get_vehicle_by_fields($make, $model, $year, $variantKey);
		}

		if (!$vehicle) {
			return new WP_REST_Response(['error' => 'Vehicle not found'], 404);
		}

		$bulbs = $this->parser->parse_bulb_size($vehicle['bulb_size'] ?? '');

		// enrich with products
		foreach ($bulbs as &$b) {
			$b['products'] = $this->get_products_for_base($b['base']);
		}

		// log query (optional)
		$this->repo->log_query(intval($vehicle['id']), [
			'make' => $vehicle['make'] ?? '',
			'model' => $vehicle['model'] ?? '',
			'year' => $vehicle['year'] ?? '',
		]);

		return rest_ensure_response([
			'vehicle' => [
				'id' => intval($vehicle['id']),
				'vid' => intval($vehicle['vid'] ?? 0),
				'year' => intval($vehicle['year']),
				'make' => (string)$vehicle['make'],
				'model' => (string)$vehicle['model'],
				'submodel' => (string)($vehicle['submodel'] ?? ''),
				'qualifier' => (string)($vehicle['qualifier'] ?? ''),
				'bodytype' => (string)($vehicle['bodytype'] ?? ''),
			],
			'bulbs' => $bulbs,
		]);
	}

	private function get_products_for_base(string $base): array {
		$base = strtoupper(trim($base));
		if ($base === '') return [];

		// cache by base
		$cacheKey = 'abfinder_products_' . md5($base);
		//$cached = get_transient($cacheKey);
		//if (is_array($cached)) return $cached;

		$adaptions = $this->repo->find_adaptions_for_bulb_base($base);

		$product_ids = [];
		foreach ($adaptions as $a) {
			$p = (string)($a['products'] ?? '');
			if ($p === '') continue;
			foreach (explode(',', $p) as $id) {
				$id = intval(trim($id));
				if ($id > 0) $product_ids[] = $id;
			}
		}
		$product_ids = array_values(array_unique($product_ids));

		$products = [];
		foreach ($product_ids as $pid) {
			// WooCommerce optional
			if (function_exists('wc_get_product')) {
				$prod = wc_get_product($pid);
				if ($prod) {
					$products[] = [
						'id' => $pid,
						'name' => $prod->get_name(),
						'url' => get_permalink($pid),
						'price_html' => $prod->get_price_html(),
						'image' => wp_get_attachment_image_url($prod->get_image_id(), 'medium') ?: '',
					];
					continue;
				}
			}

			// fallback (if Woo not active)
			$products[] = [
				'id' => $pid,
				'name' => get_the_title($pid),
				'url' => get_permalink($pid),
				'price_html' => '',
				'image' => '',
			];
		}

		set_transient($cacheKey, $products, 6 * HOUR_IN_SECONDS);
		return $products;
	}
}