diff --git a/admin/templates/shop-order/order-details.php b/admin/templates/shop-order/order-details.php index 2135fbd..bfe5c98 100644 --- a/admin/templates/shop-order/order-details.php +++ b/admin/templates/shop-order/order-details.php @@ -3,6 +3,7 @@ $orderId = (int)($this -> order['id'] ?? 0); ?>
Szczegóły zamówienia: order['number'] ?? ''), ENT_QUOTES, 'UTF-8');?>
+
diff --git a/admin/templates/site/main-layout.php b/admin/templates/site/main-layout.php index 17c2f5e..ae5586b 100644 --- a/admin/templates/site/main-layout.php +++ b/admin/templates/site/main-layout.php @@ -322,7 +322,7 @@ $.ajax({ url: '/admin/settings/globalSearchAjax/', - type: 'GET', + type: 'POST', dataType: 'json', data: { q: phrase }, success: function(response) { @@ -333,8 +333,12 @@ renderResults(response.items || []); }, - error: function() { - $results.html('
Błąd połączenia
').addClass('open'); + error: function(xhr) { + var msg = 'Błąd połączenia'; + if (xhr.status === 200) { + msg = 'Błąd parsowania odpowiedzi'; + } + $results.html('
' + msg + '
').addClass('open'); } }); } diff --git a/autoload/admin/Controllers/SettingsController.php b/autoload/admin/Controllers/SettingsController.php index 7d6f2fb..855ad25 100644 --- a/autoload/admin/Controllers/SettingsController.php +++ b/autoload/admin/Controllers/SettingsController.php @@ -73,26 +73,45 @@ class SettingsController */ public function globalSearchAjax(): void { - global $mdb; + header('Content-Type: application/json; charset=utf-8'); + header('Cache-Control: no-store'); - $phrase = trim((string)\Shared\Helpers\Helpers::get('q')); - if ($phrase === '' || mb_strlen($phrase) < 2) { + try { + $this->executeGlobalSearch(); + } catch (\Throwable $e) { echo json_encode([ - 'status' => 'ok', + 'status' => 'error', 'items' => [], ]); - exit; + } + exit; + } + + private function executeGlobalSearch(): void + { + global $mdb; + + $phrase = isset($_REQUEST['q']) ? trim((string)$_REQUEST['q']) : ''; + if ($phrase === '' || mb_strlen($phrase) < 2) { + echo json_encode(['status' => 'ok', 'items' => []]); + return; } $phrase = mb_substr($phrase, 0, 120); - $phraseNormalized = preg_replace('/\s+/', ' ', $phrase); - $phraseNormalized = trim((string)$phraseNormalized); + $phraseNormalized = trim((string)preg_replace('/\s+/', ' ', $phrase)); $like = '%' . $phrase . '%'; $likeNormalized = '%' . $phraseNormalized . '%'; $items = []; - $defaultLang = (string)$this->languagesRepository->defaultLanguage(); + $defaultLang = '1'; + try { + $defaultLang = (string)$this->languagesRepository->defaultLanguage(); + } catch (\Throwable $e) { + // fallback to '1' + } + + // --- Produkty --- try { $productStmt = $mdb->query( 'SELECT ' @@ -115,7 +134,10 @@ class SettingsController $productStmt = false; } - $productRows = $productStmt ? $productStmt->fetchAll() : []; + $productRows = ($productStmt && method_exists($productStmt, 'fetchAll')) + ? $productStmt->fetchAll(\PDO::FETCH_ASSOC) + : []; + if (is_array($productRows)) { foreach ($productRows as $row) { $productId = (int)($row['id'] ?? 0); @@ -147,6 +169,7 @@ class SettingsController } } + // --- Zamowienia --- try { $orderStmt = $mdb->query( 'SELECT ' @@ -178,7 +201,10 @@ class SettingsController $orderStmt = false; } - $orderRows = $orderStmt ? $orderStmt->fetchAll() : []; + $orderRows = ($orderStmt && method_exists($orderStmt, 'fetchAll')) + ? $orderStmt->fetchAll(\PDO::FETCH_ASSOC) + : []; + if (is_array($orderRows)) { foreach ($orderRows as $row) { $orderId = (int)($row['id'] ?? 0); @@ -214,11 +240,12 @@ class SettingsController } } - echo json_encode([ - 'status' => 'ok', - 'items' => array_slice($items, 0, 20), - ]); - exit; + $json = json_encode(['status' => 'ok', 'items' => array_slice($items, 0, 20)]); + if ($json === false) { + echo json_encode(['status' => 'ok', 'items' => []], JSON_UNESCAPED_UNICODE); + return; + } + echo $json; } /** diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index a20914b..354247d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,13 @@ Logi zmian z migracji na Domain-Driven Architecture. Najnowsze na gorze. --- +## ver. 0.314 (2026-02-23) - Fix wyszukiwarki admin + title zamówienia + +- **FIX**: Globalna wyszukiwarka w panelu admina przestała zwracać wyniki — dodano `Content-Type: application/json` i `Cache-Control: no-store` (zapobiega cache'owaniu przez proxy/CDN), zmiana AJAX z GET na POST, `fetchAll(PDO::FETCH_ASSOC)`, top-level try/catch z gwarantowaną odpowiedzią JSON +- **NEW**: `document.title` w widoku szczegółów zamówienia pokazuje numer zamówienia (np. "Zamówienie ZAM/123 - shopPro") + +--- + ## ver. 0.313 (2026-02-23) - Fix sync płatności Apilo + logowanie - **FIX**: `syncApiloPayment()` i `syncApiloStatus()` — `(int)` cast na `apilo_order_id` (format `"PPxxxxxx"`) dawał `0`, przez co metody pomijały sync z API Apilo. Zmiana na `empty()` diff --git a/docs/TODO.md b/docs/TODO.md index e69de29..2f9210c 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -0,0 +1 @@ +1. Może warto przepisać zadania cron, na tabelę, tak żeby zadania cron się kolejkowały i wykonywały za podstawie wpisów z bazy danych, takż żeby własnie nie było sytuacji, że zamówienie będzie próbowało zmienić status w apilo, zanim to zamówienie tam trafi. Czy wszystkie takie zadania trafiałyby do kolejki i wykonywałyby się chronologicznie. Ewentualnie jakieś inne podejście możesz zaproponować. \ No newline at end of file diff --git a/updates/versions.php b/updates/versions.php index 09cda6c..5b4df9d 100644 --- a/updates/versions.php +++ b/updates/versions.php @@ -1,5 +1,5 @@