Bugfix
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
Meilisearch Frontend Search
|
Meilisearch Frontend Search
|
||||||
Contao 5 – Frontend Module Template
|
Contao 5 – Frontend Module Template
|
||||||
#}
|
#}
|
||||||
|
<!-- indexer::stop -->
|
||||||
<div
|
<div
|
||||||
class="meilisearch-search"
|
class="meilisearch-search"
|
||||||
data-limit="{{ meiliLimit }}"
|
data-limit="{{ meiliLimit }}"
|
||||||
@@ -27,7 +27,7 @@ Contao 5 – Frontend Module Template
|
|||||||
|
|
||||||
<div id="meilisearch-results" class="meilisearch-results"></div>
|
<div id="meilisearch-results" class="meilisearch-results"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- indexer::continue -->
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import MeiliSearch from 'https://cdn.jsdelivr.net/npm/meilisearch@latest/dist/bundles/meilisearch.esm.js';
|
import MeiliSearch from 'https://cdn.jsdelivr.net/npm/meilisearch@latest/dist/bundles/meilisearch.esm.js';
|
||||||
|
|
||||||
|
|||||||
@@ -34,11 +34,10 @@ class MeilisearchIndexService
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
// Contao vollständig initialisieren (CLI & Cron!)
|
|
||||||
$this->framework->initialize();
|
$this->framework->initialize();
|
||||||
|
|
||||||
$host = (string) Config::get('meilisearch_host');
|
$host = (string) Config::get('meilisearch_host');
|
||||||
$apiKey = (string) Config::get('meilisearch_api_write');
|
$apiKey = (string) Config::get('meilisearch_api_write');
|
||||||
$this->indexName = (string) Config::get('meilisearch_index');
|
$this->indexName = (string) Config::get('meilisearch_index');
|
||||||
|
|
||||||
if ($host === '' || $this->indexName === '') {
|
if ($host === '' || $this->indexName === '') {
|
||||||
@@ -48,44 +47,44 @@ class MeilisearchIndexService
|
|||||||
$this->client = new Client($host, $apiKey);
|
$this->client = new Client($host, $apiKey);
|
||||||
$index = $this->client->index($this->indexName);
|
$index = $this->client->index($this->indexName);
|
||||||
|
|
||||||
// 🔑 PRIMARY KEY EINMALIG FESTLEGEN
|
|
||||||
try {
|
try {
|
||||||
$index->updateSettings([
|
$index->updateSettings(['primaryKey' => 'id']);
|
||||||
'primaryKey' => 'id',
|
} catch (\Throwable) {}
|
||||||
]);
|
|
||||||
} catch (\Throwable) {
|
|
||||||
// bewusst ignorieren
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ Index-Settings sicherstellen
|
|
||||||
$this->ensureIndexSettings($index);
|
$this->ensureIndexSettings($index);
|
||||||
|
|
||||||
// 🔄 Index leeren (Settings bleiben erhalten)
|
|
||||||
$index->deleteAllDocuments();
|
$index->deleteAllDocuments();
|
||||||
|
|
||||||
// 📄 Inhalte indexieren
|
|
||||||
$this->indexTlSearch($index);
|
$this->indexTlSearch($index);
|
||||||
$this->indexTlSearchPdf($index);
|
$this->indexTlSearchPdf($index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Relevanz- & Sortierlogik für Meilisearch
|
|
||||||
*/
|
|
||||||
private function ensureIndexSettings(Indexes $index): void
|
private function ensureIndexSettings(Indexes $index): void
|
||||||
{
|
{
|
||||||
$index->updateSettings([
|
$index->updateSettings([
|
||||||
'searchableAttributes' => [
|
'searchableAttributes' => ['title', 'keywords', 'text'],
|
||||||
'title',
|
'sortableAttributes' => ['priority', 'startDate'],
|
||||||
'keywords',
|
|
||||||
'text',
|
|
||||||
],
|
|
||||||
'sortableAttributes' => [
|
|
||||||
'priority',
|
|
||||||
'startDate',
|
|
||||||
],
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ⛔ MEILISEARCH_META aus Text entfernen
|
||||||
|
*/
|
||||||
|
private function stripMeilisearchMeta(string $text): string
|
||||||
|
{
|
||||||
|
$text = preg_replace(
|
||||||
|
'/⟦MEILISEARCH_META⟧.*?⟦\/MEILISEARCH_META⟧/su',
|
||||||
|
'',
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
|
||||||
|
// Text normalisieren
|
||||||
|
$text = preg_replace('/\s{2,}/u', ' ', $text);
|
||||||
|
$text = preg_replace('/\n{2,}/u', "\n", $text);
|
||||||
|
|
||||||
|
return trim($text);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* startDate aus schema.org Event extrahieren
|
* startDate aus schema.org Event extrahieren
|
||||||
*/
|
*/
|
||||||
@@ -105,16 +104,12 @@ class MeilisearchIndexService
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Contao-JSON-LD (vollqualifiziert)
|
|
||||||
if (!empty($entry['https://schema.org/startDate'])) {
|
if (!empty($entry['https://schema.org/startDate'])) {
|
||||||
$ts = strtotime($entry['https://schema.org/startDate']);
|
return strtotime($entry['https://schema.org/startDate']) ?: null;
|
||||||
return $ts ?: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🛟 Fallback (falls Contao das irgendwann ändert)
|
|
||||||
if (!empty($entry['startDate'])) {
|
if (!empty($entry['startDate'])) {
|
||||||
$ts = strtotime($entry['startDate']);
|
return strtotime($entry['startDate']) ?: null;
|
||||||
return $ts ?: null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,22 +134,21 @@ class MeilisearchIndexService
|
|||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$type = $this->detectTypeFromMeta($row['meta'] ?? null);
|
$type = $this->detectTypeFromMeta($row['meta'] ?? null);
|
||||||
|
|
||||||
// 📅 Event-Startdatum einmal ermitteln
|
|
||||||
$eventStart = null;
|
$eventStart = null;
|
||||||
if ($type === 'event') {
|
if ($type === 'event') {
|
||||||
$eventStart = $this->extractEventStartDate($row['meta'] ?? null);
|
$eventStart = $this->extractEventStartDate($row['meta'] ?? null);
|
||||||
|
|
||||||
// ⛔ Vergangene Events überspringen (wenn nicht erlaubt)
|
|
||||||
if (!$indexPastEvents && $eventStart !== null && $eventStart < $today) {
|
if (!$indexPastEvents && $eventStart !== null && $eventStart < $today) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cleanText = $this->stripMeilisearchMeta((string) $row['text']);
|
||||||
|
|
||||||
$doc = [
|
$doc = [
|
||||||
'id' => $type . '_' . $row['id'],
|
'id' => $type . '_' . $row['id'],
|
||||||
'type' => $type,
|
'type' => $type,
|
||||||
'title' => $row['title'],
|
'title' => $row['title'],
|
||||||
'text' => $row['text'],
|
'text' => $cleanText,
|
||||||
'url' => $row['url'],
|
'url' => $row['url'],
|
||||||
'protected' => (bool) $row['protected'],
|
'protected' => (bool) $row['protected'],
|
||||||
'checksum' => $row['checksum'],
|
'checksum' => $row['checksum'],
|
||||||
@@ -162,12 +156,10 @@ class MeilisearchIndexService
|
|||||||
'priority' => (int) ($row['priority'] ?? 0),
|
'priority' => (int) ($row['priority'] ?? 0),
|
||||||
];
|
];
|
||||||
|
|
||||||
// 📅 startDate nur für Events setzen
|
|
||||||
if ($eventStart !== null) {
|
if ($eventStart !== null) {
|
||||||
$doc['startDate'] = $eventStart;
|
$doc['startDate'] = $eventStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🖼️ Bild aus UUID erzeugen
|
|
||||||
if (!empty($row['imagepath'])) {
|
if (!empty($row['imagepath'])) {
|
||||||
$imagePath = $this->imageHelper->resolveImagePath($row['imagepath']);
|
$imagePath = $this->imageHelper->resolveImagePath($row['imagepath']);
|
||||||
if ($imagePath !== null) {
|
if ($imagePath !== null) {
|
||||||
@@ -204,7 +196,7 @@ class MeilisearchIndexService
|
|||||||
'id' => $fileType . '_' . $row['id'],
|
'id' => $fileType . '_' . $row['id'],
|
||||||
'type' => $fileType,
|
'type' => $fileType,
|
||||||
'title' => $row['title'],
|
'title' => $row['title'],
|
||||||
'text' => $row['text'],
|
'text' => $this->stripMeilisearchMeta((string) $row['text']),
|
||||||
'url' => $row['url'],
|
'url' => $row['url'],
|
||||||
'checksum' => $row['checksum'],
|
'checksum' => $row['checksum'],
|
||||||
'poster' => self::FILETYPE_ICON_MAP[$fileType]
|
'poster' => self::FILETYPE_ICON_MAP[$fileType]
|
||||||
@@ -215,9 +207,6 @@ class MeilisearchIndexService
|
|||||||
$index->addDocuments($documents);
|
$index->addDocuments($documents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Typ (page | event | news) aus meta erkennen
|
|
||||||
*/
|
|
||||||
private function detectTypeFromMeta(?string $meta): string
|
private function detectTypeFromMeta(?string $meta): string
|
||||||
{
|
{
|
||||||
if (!$meta) {
|
if (!$meta) {
|
||||||
@@ -233,7 +222,6 @@ class MeilisearchIndexService
|
|||||||
if (($entry['@type'] ?? null) === 'https://schema.org/Event') {
|
if (($entry['@type'] ?? null) === 'https://schema.org/Event') {
|
||||||
return 'event';
|
return 'event';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($entry['@type'] ?? null) === 'https://schema.org/NewsArticle') {
|
if (($entry['@type'] ?? null) === 'https://schema.org/NewsArticle') {
|
||||||
return 'news';
|
return 'news';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user