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-admin.php
<?php
if (!defined('ABSPATH')) exit;

class ABFinder_Admin {

	private $repo;

	public function __construct(ABFinder_Repository $repo) {
		$this->repo = $repo;

		add_action('admin_menu', [$this, 'menu']);
		add_action('admin_enqueue_scripts', [$this, 'enqueue']);

		// AJAX: Woo product kereső
		add_action('wp_ajax_abfinder_product_search', [$this, 'ajax_product_search']);

		// AJAX: mapping mentés
		add_action('wp_ajax_abfinder_save_mapping', [$this, 'ajax_save_mapping']);
		add_action('wp_ajax_abfinder_remove_mapping', [$this, 'ajax_remove_mapping']);
		add_action('wp_ajax_abfinder_create_adaption', [$this, 'ajax_create_adaption']);
	}

	public function menu() {
		add_menu_page(
			'Izzó párosítás',
			'Izzó párosítás',
			'manage_options',
			'abfinder-mapping',
			[$this, 'page'],
			'dashicons-admin-generic',
			56
		);
	}

	public function enqueue($hook) {
		if ($hook !== 'toplevel_page_abfinder-mapping') return;

		// Select2 a kényelmes keresőhöz (WP core-ban sokszor van, de biztosra megyünk)
		wp_enqueue_style('select2');
		wp_enqueue_script('select2');

		wp_enqueue_style('abfinder-admin', ABFINDER_URL . 'assets/admin.css', [], @filemtime(ABFINDER_PATH.'assets/admin.css') ?: '1.0.0');
		wp_enqueue_script('abfinder-admin', ABFINDER_URL . 'assets/admin.js', ['jquery', 'select2'], @filemtime(ABFINDER_PATH.'assets/admin.js') ?: '1.0.0', true);

		wp_localize_script('abfinder-admin', 'ABF_ADMIN', [
			'ajaxUrl' => admin_url('admin-ajax.php'),
			'nonce'   => wp_create_nonce('abfinder_admin'),
		]);
	}

	public function page() {
		if (!current_user_can('manage_options')) return;

		// Query
		$q = isset($_GET['s']) ? sanitize_text_field($_GET['s']) : '';

		// Adaptions list
		$rows = $this->repo->admin_get_adaptions($q, 200);

		?>
		<div class="wrap abf-admin">
			<h1>Izzó típus → Termék párosítás</h1>
			<div class="abf-create">
				<input type="text" id="abf-new-fits" placeholder="Új izzótípus (pl. H7 vagy H8,H9,H11)" />
				<button class="button button-primary" id="abf-create-btn">Hozzáadás</button>
				<span class="abf-create-msg" id="abf-create-msg"></span>
			</div>

			<form method="get" class="abf-admin-search">
				<input type="hidden" name="page" value="abfinder-mapping" />
				<input type="text" name="s" value="<?php echo esc_attr($q); ?>" placeholder="Izzó típus keresése (pl. H7, H11, D1S…)" />
				<button class="button">Keresés</button>
			</form>

			<p class="description">Tipp: terméknév alapján keress, majd “Hozzáadás”. Több termék is társítható 1 izzó típushoz.</p>

			<table class="widefat striped abf-admin-table">
				<thead>
				<tr>
					<th style="width:180px;">Izzó típus</th>
					<th>Jelenlegi termékek</th>
					<th style="width:360px;">Hozzáadás</th>
				</tr>
				</thead>
				<tbody>
				<?php if (!$rows): ?>
					<tr><td colspan="3">Nincs találat.</td></tr>
				<?php else: foreach ($rows as $r):
					$id = intval($r['id']);
					$fits_on = (string)$r['fits_on']; // pl: H8,H9,H11
					$products = $this->repo->admin_get_products_for_adaption_row($r);
					?>
					<tr data-row-id="<?php echo esc_attr($id); ?>">
						<td>
							<div class="abf-bulb">
								<strong><?php echo esc_html($fits_on); ?></strong>
							</div>
						</td>
						<td>
							<div class="abf-prod-list">
								<?php if (!$products): ?>
									<em>—</em>
								<?php else: foreach ($products as $p): ?>
									<div class="abf-prod-pill" data-product-id="<?php echo esc_attr($p['id']); ?>">
										<a href="<?php echo esc_url($p['edit_url']); ?>" target="_blank"><?php echo esc_html($p['name']); ?></a>
										<button class="button-link abf-remove" title="Eltávolítás">×</button>
									</div>
								<?php endforeach; endif; ?>
							</div>
						</td>
						<td>
							<select class="abf-product-select" style="width: 260px;"></select>
							<button class="button button-primary abf-add">Hozzáadás</button>
							<div class="abf-msg"></div>
						</td>
					</tr>
				<?php endforeach; endif; ?>
				</tbody>
			</table>
		</div>
		<?php
	}

	public function ajax_product_search() {
		check_ajax_referer('abfinder_admin', 'nonce');
		if (!current_user_can('manage_options')) wp_send_json_error(['message' => 'No permission'], 403);

		$term = isset($_GET['term']) ? sanitize_text_field($_GET['term']) : '';
		$items = $this->repo->admin_search_products($term, 20);

		// Select2 expects {id,text}
		$out = array_map(fn($p) => ['id' => $p['id'], 'text' => $p['name']], $items);
		wp_send_json($out);
	}

	public function ajax_save_mapping() {
		check_ajax_referer('abfinder_admin', 'nonce');
		if (!current_user_can('manage_options')) wp_send_json_error(['message' => 'Nincs jogosultság.'], 403);

		$row_id = intval($_POST['row_id'] ?? 0);
		$product_ids = $_POST['product_ids'] ?? [];

		if ($row_id <= 0) {
			wp_send_json_error(['message' => 'Hiányzó sor azonosító.'], 400);
		}

		if (!is_array($product_ids)) {
			// fallback ha 1 db jön
			$product_ids = [$product_ids];
		}

		$product_ids = array_values(array_filter(array_map('intval', $product_ids)));

		if (!$product_ids) {
			wp_send_json_error(['message' => 'Válassz ki legalább egy terméket!'], 400);
		}

		$added = [];
		foreach ($product_ids as $pid) {
			$ok = $this->repo->admin_add_product_to_adaption($row_id, $pid);
			if ($ok) {
				$added[] = $this->repo->admin_get_product_basic($pid);
			}
		}

		if (!$added) {
			wp_send_json_error(['message' => 'Nem sikerült menteni.'], 500);
		}

		wp_send_json_success(['products' => $added]);
	}

	public function ajax_remove_mapping() {
		check_ajax_referer('abfinder_admin', 'nonce');
		if (!current_user_can('manage_options')) wp_send_json_error(['message' => 'No permission'], 403);

		$row_id = intval($_POST['row_id'] ?? 0);
		$product_id = intval($_POST['product_id'] ?? 0);

		if ($row_id <= 0 || $product_id <= 0) {
			wp_send_json_error(['message' => 'Hiányzó adatok.'], 400);
		}

		$ok = $this->repo->admin_remove_product_from_adaption($row_id, $product_id);
		if (!$ok) wp_send_json_error(['message' => 'Nem sikerült eltávolítani.'], 500);

		wp_send_json_success();
	}

	public function ajax_create_adaption() {
		check_ajax_referer('abfinder_admin', 'nonce');
		if (!current_user_can('manage_options')) wp_send_json_error(['message' => 'Nincs jogosultság.'], 403);

		$fits_on = sanitize_text_field($_POST['fits_on'] ?? '');
		$fits_on = trim($fits_on);

		if ($fits_on === '') {
			wp_send_json_error(['message' => 'Add meg az izzótípust (fits_on)!'], 400);
		}

		$row = $this->repo->admin_create_adaption($fits_on);
		if (!$row) {
			wp_send_json_error(['message' => 'Nem sikerült létrehozni (lehet, hogy már létezik).'], 400);
		}

		wp_send_json_success(['row' => $row]);
	}

}