<?php
namespace App\Controller\Content;
use App\Controller\BaseController;
use App\Helpers\Mysql\MysqlEntitySearch;
use App\Helpers\Odbc\OdbcProdukte;
use App\Service\SessionService;
use App\Service\IceCatService;
use App\Service\SearchResultsFormatter;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
class DownloadController extends BaseController
{
/**
* @Route("/download", name="download")
*/
public function download(): Response
{
return $this->baseRender('content/downloads.html.twig');
}
/**
* @Route("/entity-search", name="entity_search")
*/
public function entitySearch(): Response
{
return $this->baseRender('content/entity_search.html.twig');
}
/**
* @Route("/search-entity-fast", name="search_entity_fast")
* v3.0.0 - Now returns formatted HTML from backend
*/
public function searchEntityFast(
Request $request,
MysqlEntitySearch $entitySearch,
SearchResultsFormatter $formatter
): JsonResponse
{
$search = $request->query->get('search', '');
$category = $request->query->get('category', null);
$manufacturer = $request->query->get('manufacturer', null);
// Execute search with filters (validation is handled by MysqlEntitySearch)
$searchResults = $entitySearch->search($search, $category, $manufacturer);
// Format results into HTML using service (proper MVC separation)
// Optional: Set checkIceCat=true to actually call IceCat API (WARNING: Slow!)
$checkIceCat = $request->query->get('check_icecat', 'false') === 'true';
$formattedResults = $formatter->formatSearchResults($searchResults, $checkIceCat);
// Return both formatted HTML and raw data for backward compatibility
$response = [
'html' => $formattedResults['html'],
'count' => $formattedResults['count'],
'scenario' => $formattedResults['scenario'],
'metadata' => $searchResults['metadata'] ?? [],
'icecat_status' => $formattedResults['icecat_status'] ?? [],
// Keep raw data for any custom frontend processing if needed
'results' => $searchResults['results'] ?? [],
'alternatives' => $searchResults['alternatives'] ?? [],
];
return new JsonResponse($response);
}
/**
* @Route("/entity-search/categories", name="entity_search_categories")
*/
public function getCategories(MysqlEntitySearch $entitySearch): JsonResponse
{
$categories = $entitySearch->getCategories();
return new JsonResponse($categories);
}
/**
* @Route("/entity-search/manufacturers", name="entity_search_manufacturers")
*/
public function getManufacturers(MysqlEntitySearch $entitySearch): JsonResponse
{
$manufacturers = $entitySearch->getManufacturers();
return new JsonResponse($manufacturers);
}
/**
* @Route("/opcache-reset-temp", name="opcache_reset_temp")
* TEMPORARY: Reset PHP opcache - DELETE THIS ROUTE AFTER USE
*/
public function opcacheReset(): JsonResponse
{
if (function_exists('opcache_reset')) {
opcache_reset();
return new JsonResponse(['status' => 'OPcache reset successfully']);
}
return new JsonResponse(['status' => 'OPcache not available'], 500);
}
/**
* @Route("/product-details", name="product_details")
* Get detailed product information for modal display (includes IceCat data)
*/
public function getProductDetails(Request $request, ManagerRegistry $doctrine, IceCatService $iceCatService): JsonResponse
{
$articleNr = $request->query->get('article_nr', '');
$manufacturer = $request->query->get('manufacturer', '');
if (empty($articleNr)) {
return new JsonResponse(['error' => 'Article number is required'], 400);
}
try {
// First try to get from ODBC (produkte table)
$productData = null;
$source = 'mysql';
try {
$odbc = new OdbcProdukte();
$products = $odbc->searchByArtnr($articleNr, 1);
if (!empty($products)) {
$product = $products[0];
$productData = [
'article_nr' => $product->getArtnr(),
'manufacturer' => $product->getHersteller(),
'description' => $product->getDescription(),
'ean' => $product->getEan(),
'category' => $product->getArtGr(),
'image_file' => $product->getBildDatei(),
'price' => $product->getVk(),
'availability' => $product->getAvailability(),
'delivery' => $product->getDeliveryTime(),
'color' => '',
'pages' => '',
'compatible_with' => '',
];
$source = 'odbc';
}
} catch (\Exception $e) {
error_log('ODBC not available for product details: ' . $e->getMessage());
}
// Fallback to MySQL entity table if ODBC not available
if (!$productData) {
$connection = $doctrine->getConnection();
$sql = "
SELECT
entity_id,
name1 as article_nr,
hersteller as manufacturer,
name2 as description,
ean,
artgr as category,
picfile as image_file,
keywords,
description as long_description,
color,
size
FROM entity
WHERE name1 = :article_nr
";
if ($manufacturer) {
$sql .= " AND hersteller = :manufacturer";
}
$sql .= " LIMIT 1";
$params = ['article_nr' => $articleNr];
if ($manufacturer) {
$params['manufacturer'] = $manufacturer;
}
$stmt = $connection->prepare($sql);
$result = $stmt->executeQuery($params);
$productData = $result->fetchAssociative();
if ($productData) {
// Add empty fields that might not exist in entity table
$productData['price'] = null;
$productData['availability'] = null;
$productData['delivery'] = null;
$productData['pages'] = '';
$productData['compatible_with'] = '';
$productData['long_description'] = $productData['long_description'] ?? '';
}
}
if (!$productData) {
return new JsonResponse(['error' => 'Product not found'], 404);
}
// Add source information
$productData['source'] = $source;
// Build image URL
if (!empty($productData['image_file']) && $productData['image_file'] !== 'nopic.gif') {
$manufacturerLower = strtolower($productData['manufacturer'] ?? $manufacturer);
$productData['image_url'] = '/image/' . $manufacturerLower . '/' . $productData['image_file'];
} else {
$productData['image_url'] = '/img/nopic.gif';
}
// Fetch IceCat product specifications with detailed response information
$iceCatSpecs = null;
try {
$ean = $productData['ean'] ?? '';
$productManufacturer = $productData['manufacturer'] ?? $manufacturer;
// Handle special HP manufacturer case (from old code)
if (substr($productManufacturer, 0, 2) === 'HP') {
$productManufacturer = 'HP';
}
// Request detailed response including HTTP status, raw response, etc.
$iceCatDetailedResponse = $iceCatService->getProductSpecs($ean, $articleNr, $productManufacturer, true);
if ($iceCatDetailedResponse && $iceCatDetailedResponse['success']) {
$productData['icecat_available'] = true;
$productData['icecat_specs'] = $iceCatDetailedResponse['specs'];
// Include detailed API response information
$productData['icecat_details'] = [
'http_status_code' => $iceCatDetailedResponse['http_status'],
'request_url' => $iceCatDetailedResponse['request_url'],
'response_time_ms' => $iceCatDetailedResponse['response_time_ms'],
'raw_response' => $iceCatDetailedResponse['raw_response'],
'error' => $iceCatDetailedResponse['error']
];
} else {
$productData['icecat_available'] = false;
// Include details about why IceCat failed
$productData['icecat_details'] = [
'http_status_code' => $iceCatDetailedResponse['http_status'] ?? null,
'request_url' => $iceCatDetailedResponse['request_url'] ?? null,
'response_time_ms' => $iceCatDetailedResponse['response_time_ms'] ?? null,
'raw_response' => $iceCatDetailedResponse['raw_response'] ?? null,
'error' => $iceCatDetailedResponse['error'] ?? 'Product not found in IceCat database'
];
}
} catch (\Exception $e) {
error_log('IceCat fetch failed for ' . $articleNr . ': ' . $e->getMessage());
$productData['icecat_available'] = false;
$productData['icecat_details'] = [
'http_status_code' => null,
'request_url' => null,
'response_time_ms' => null,
'raw_response' => null,
'error' => $e->getMessage()
];
}
return new JsonResponse($productData);
} catch (\Exception $e) {
error_log('Error fetching product details: ' . $e->getMessage());
return new JsonResponse(['error' => 'Failed to load product details: ' . $e->getMessage()], 500);
}
}
}