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: = htmlspecialchars((string)($this -> 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 @@
-$current_ver = 313;
+$current_ver = 314;
for ($i = 1; $i <= $current_ver; $i++)
{