|
|
|
|
@@ -61,14 +61,20 @@ foreach (($listingCategories ?? []) as $categoryRow) {
|
|
|
|
|
$categoryInputValue = $categoryTitleMap[$categorySlugValue] ?? $categorySlugValue;
|
|
|
|
|
$eventLocationModeValue = $editingEvent ? (string)($editEvent['location_source_type'] ?? 'custom') : 'custom';
|
|
|
|
|
$eventLocationSourceIdValue = $editingEvent && !empty($editEvent['location_source_listing_id']) ? (int)$editEvent['location_source_listing_id'] : 0;
|
|
|
|
|
$eventLocationSourceInputValue = '';
|
|
|
|
|
$usesDatabaseEventLocation = $currentEntryKind === 'event' && $eventLocationModeValue !== 'custom';
|
|
|
|
|
$eventAddressInfoValue = trim(implode(', ', array_filter([
|
|
|
|
|
$streetValue,
|
|
|
|
|
trim($zipValue . ' ' . $cityValue),
|
|
|
|
|
$regionValue,
|
|
|
|
|
])));
|
|
|
|
|
$eventLocationPlaceOptions = [];
|
|
|
|
|
$eventLocationEditorialOptions = [];
|
|
|
|
|
foreach (($eventLocationOptions ?? []) as $locationOption) {
|
|
|
|
|
if ((string)($locationOption['listing_type'] ?? '') === 'place') {
|
|
|
|
|
$eventLocationPlaceOptions[] = $locationOption;
|
|
|
|
|
} elseif ((string)($locationOption['listing_type'] ?? '') === 'editorial_event') {
|
|
|
|
|
$eventLocationEditorialOptions[] = $locationOption;
|
|
|
|
|
}
|
|
|
|
|
if ((int)($locationOption['id'] ?? 0) !== $eventLocationSourceIdValue) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
@@ -78,12 +84,6 @@ foreach (($eventLocationOptions ?? []) as $locationOption) {
|
|
|
|
|
trim((string)($locationOption['zip'] ?? '') . ' ' . (string)($locationOption['city'] ?? '')),
|
|
|
|
|
])));
|
|
|
|
|
$optionDateLabel = !empty($locationOption['starts_at']) ? date('d.m.Y', strtotime((string)$locationOption['starts_at'])) : '';
|
|
|
|
|
$eventLocationSourceInputValue = trim(implode(' · ', array_filter([
|
|
|
|
|
$optionTypeLabel,
|
|
|
|
|
(string)($locationOption['title'] ?? ''),
|
|
|
|
|
$optionDateLabel,
|
|
|
|
|
$optionAddressLabel,
|
|
|
|
|
])));
|
|
|
|
|
if ($eventLocationModeValue !== 'custom' && !empty($locationOption['category_title'])) {
|
|
|
|
|
$categoryInputValue = (string)$locationOption['category_title'];
|
|
|
|
|
$categorySlugValue = (string)($locationOption['category_slug'] ?? $categorySlugValue);
|
|
|
|
|
@@ -1144,25 +1144,6 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
</option>
|
|
|
|
|
<?php endforeach; ?>
|
|
|
|
|
</datalist>
|
|
|
|
|
<datalist id="eventLocationOptionList">
|
|
|
|
|
<?php foreach (($eventLocationOptions ?? []) as $locationOption): ?>
|
|
|
|
|
<?php
|
|
|
|
|
$optionTypeLabel = (string)($locationOption['listing_type'] ?? '') === 'place' ? 'Ort' : 'Veranstaltung';
|
|
|
|
|
$optionAddressLabel = trim(implode(', ', array_filter([
|
|
|
|
|
(string)($locationOption['street'] ?? ''),
|
|
|
|
|
trim((string)($locationOption['zip'] ?? '') . ' ' . (string)($locationOption['city'] ?? '')),
|
|
|
|
|
])));
|
|
|
|
|
$optionDateLabel = !empty($locationOption['starts_at']) ? date('d.m.Y', strtotime((string)$locationOption['starts_at'])) : '';
|
|
|
|
|
$optionLabel = trim(implode(' · ', array_filter([
|
|
|
|
|
$optionTypeLabel,
|
|
|
|
|
(string)($locationOption['title'] ?? ''),
|
|
|
|
|
$optionDateLabel,
|
|
|
|
|
$optionAddressLabel,
|
|
|
|
|
])));
|
|
|
|
|
?>
|
|
|
|
|
<option value="<?= htmlspecialchars($optionLabel, ENT_QUOTES) ?>" data-location='<?= htmlspecialchars(json_encode($locationOption, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), ENT_QUOTES) ?>'></option>
|
|
|
|
|
<?php endforeach; ?>
|
|
|
|
|
</datalist>
|
|
|
|
|
<?php if (!$editing && $showEventTypeChoice): ?>
|
|
|
|
|
<div class="stack gap-8">
|
|
|
|
|
<label class="label">Was möchtest du anlegen?</label>
|
|
|
|
|
@@ -1197,8 +1178,29 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stack gap-6" id="eventLocationSourceWrap">
|
|
|
|
|
<label class="label" for="eventLocationSourceInput" id="eventLocationSourceLabel">Ort aus Datenbank</label>
|
|
|
|
|
<input id="eventLocationSourceInput" class="input" list="eventLocationOptionList" placeholder="Eintrag aus der Datenbank auswählen" value="<?= htmlspecialchars($eventLocationSourceInputValue, ENT_QUOTES) ?>">
|
|
|
|
|
<label class="label" for="eventLocationSourceSelect" id="eventLocationSourceLabel">Ort aus Datenbank</label>
|
|
|
|
|
<select id="eventLocationSourceSelect" class="select">
|
|
|
|
|
<option value=""><?= $eventLocationModeValue === 'editorial_event' ? 'Keine aktuell verfügbaren Veranstaltungen' : 'Ort aus der Datenbank auswählen' ?></option>
|
|
|
|
|
<?php foreach (($eventLocationModeValue === 'editorial_event' ? $eventLocationEditorialOptions : $eventLocationPlaceOptions) as $locationOption): ?>
|
|
|
|
|
<?php
|
|
|
|
|
$optionAddressLabel = trim(implode(', ', array_filter([
|
|
|
|
|
(string)($locationOption['street'] ?? ''),
|
|
|
|
|
trim((string)($locationOption['zip'] ?? '') . ' ' . (string)($locationOption['city'] ?? '')),
|
|
|
|
|
])));
|
|
|
|
|
$optionDateLabel = !empty($locationOption['starts_at']) ? date('d.m.Y', strtotime((string)$locationOption['starts_at'])) : '';
|
|
|
|
|
$optionLabel = trim(implode(' · ', array_filter([
|
|
|
|
|
(string)($locationOption['title'] ?? ''),
|
|
|
|
|
$optionDateLabel,
|
|
|
|
|
$optionAddressLabel,
|
|
|
|
|
])));
|
|
|
|
|
?>
|
|
|
|
|
<option
|
|
|
|
|
value="<?= (int)($locationOption['id'] ?? 0) ?>"
|
|
|
|
|
data-location='<?= htmlspecialchars(json_encode($locationOption, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), ENT_QUOTES) ?>'
|
|
|
|
|
<?= (int)($locationOption['id'] ?? 0) === $eventLocationSourceIdValue ? 'selected' : '' ?>
|
|
|
|
|
><?= htmlspecialchars($optionLabel, ENT_QUOTES) ?></option>
|
|
|
|
|
<?php endforeach; ?>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<?php if (($section ?? 'events') === 'events' && !$editingListing): ?>
|
|
|
|
|
<div class="flex gap-8" style="flex-wrap:wrap;" id="eventCreateListingActionsWrap">
|
|
|
|
|
@@ -1450,7 +1452,7 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
const eventLocationModeWrap = document.getElementById('eventLocationModeWrap');
|
|
|
|
|
const eventLocationModeSelect = document.getElementById('eventLocationMode');
|
|
|
|
|
const eventLocationSourceWrap = document.getElementById('eventLocationSourceWrap');
|
|
|
|
|
const eventLocationSourceInput = document.getElementById('eventLocationSourceInput');
|
|
|
|
|
const eventLocationSourceSelect = document.getElementById('eventLocationSourceSelect');
|
|
|
|
|
const eventLocationSourceIdInput = document.getElementById('eventLocationSourceId');
|
|
|
|
|
const eventLocationSourceLabel = document.getElementById('eventLocationSourceLabel');
|
|
|
|
|
const categoryInputWrap = document.getElementById('categoryInputWrap');
|
|
|
|
|
@@ -1532,16 +1534,50 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function findEventLocationOptionByLabel(label) {
|
|
|
|
|
const normalized = (label || '').trim();
|
|
|
|
|
if (!normalized) return null;
|
|
|
|
|
const option = document.querySelector(`#eventLocationOptionList option[value="${CSS.escape(normalized)}"]`);
|
|
|
|
|
const allEventLocationOptions = <?= json_encode($eventLocationOptions ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
|
|
|
|
|
|
|
|
function buildEventLocationLabel(option) {
|
|
|
|
|
if (!option) return '';
|
|
|
|
|
const addressLabel = [String(option.street || ''), `${String(option.zip || '')} ${String(option.city || '')}`.trim()]
|
|
|
|
|
.filter(Boolean)
|
|
|
|
|
.join(', ');
|
|
|
|
|
const dateLabel = option.starts_at ? new Date(String(option.starts_at)).toLocaleDateString('de-DE') : '';
|
|
|
|
|
return [String(option.title || ''), dateLabel, addressLabel].filter(Boolean).join(' · ');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function findEventLocationOptionById(id) {
|
|
|
|
|
const normalizedId = Number(id || 0);
|
|
|
|
|
if (!normalizedId) return null;
|
|
|
|
|
const option = allEventLocationOptions.find((entry) => Number(entry.id || 0) === normalizedId);
|
|
|
|
|
if (!option) return null;
|
|
|
|
|
try {
|
|
|
|
|
return JSON.parse(option.getAttribute('data-location') || 'null');
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
return option;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function rebuildEventLocationOptions() {
|
|
|
|
|
if (!eventLocationSourceSelect) return;
|
|
|
|
|
const mode = eventLocationModeSelect?.value || 'custom';
|
|
|
|
|
const selectedId = Number(eventLocationSourceIdInput?.value || eventLocationSourceSelect.value || 0);
|
|
|
|
|
const filteredOptions = allEventLocationOptions.filter((option) => String(option.listing_type || '') === mode);
|
|
|
|
|
const emptyLabel = mode === 'editorial_event'
|
|
|
|
|
? 'Keine aktuell verfügbaren Veranstaltungen'
|
|
|
|
|
: 'Ort aus der Datenbank auswählen';
|
|
|
|
|
|
|
|
|
|
eventLocationSourceSelect.innerHTML = '';
|
|
|
|
|
const placeholderOption = document.createElement('option');
|
|
|
|
|
placeholderOption.value = '';
|
|
|
|
|
placeholderOption.textContent = filteredOptions.length === 0 ? emptyLabel : (mode === 'editorial_event' ? 'Veranstaltung aus der Datenbank auswählen' : 'Ort aus der Datenbank auswählen');
|
|
|
|
|
eventLocationSourceSelect.appendChild(placeholderOption);
|
|
|
|
|
eventLocationSourceSelect.disabled = filteredOptions.length === 0;
|
|
|
|
|
|
|
|
|
|
filteredOptions.forEach((option) => {
|
|
|
|
|
const element = document.createElement('option');
|
|
|
|
|
element.value = String(option.id || '');
|
|
|
|
|
element.textContent = buildEventLocationLabel(option);
|
|
|
|
|
if (Number(option.id || 0) === selectedId) {
|
|
|
|
|
element.selected = true;
|
|
|
|
|
}
|
|
|
|
|
eventLocationSourceSelect.appendChild(element);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function applyEventLocationOption(option) {
|
|
|
|
|
@@ -1585,7 +1621,7 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
|
|
|
|
|
function clearEventLocationSelection() {
|
|
|
|
|
if (eventLocationSourceIdInput) eventLocationSourceIdInput.value = '';
|
|
|
|
|
if (eventLocationSourceInput) eventLocationSourceInput.value = '';
|
|
|
|
|
if (eventLocationSourceSelect) eventLocationSourceSelect.value = '';
|
|
|
|
|
if (streetInput) streetInput.value = '';
|
|
|
|
|
if (zipInput) zipInput.value = '';
|
|
|
|
|
if (cityInput) cityInput.value = '';
|
|
|
|
|
@@ -1614,6 +1650,7 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
if (eventLocationSourceLabel) {
|
|
|
|
|
eventLocationSourceLabel.textContent = mode === 'editorial_event' ? 'Veranstaltung aus Datenbank' : 'Ort aus Datenbank';
|
|
|
|
|
}
|
|
|
|
|
rebuildEventLocationOptions();
|
|
|
|
|
|
|
|
|
|
if (categoryInput) {
|
|
|
|
|
if (usesDatabaseLocation) {
|
|
|
|
|
@@ -1624,7 +1661,7 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (usesDatabaseLocation) {
|
|
|
|
|
const option = findEventLocationOptionByLabel(eventLocationSourceInput?.value || '');
|
|
|
|
|
const option = findEventLocationOptionById(eventLocationSourceSelect?.value || eventLocationSourceIdInput?.value || '');
|
|
|
|
|
if (option && String(option.listing_type || '') === mode) {
|
|
|
|
|
applyEventLocationOption(option);
|
|
|
|
|
} else {
|
|
|
|
|
@@ -1683,9 +1720,9 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
clearEventLocationSelection();
|
|
|
|
|
syncEventLocationMode();
|
|
|
|
|
});
|
|
|
|
|
eventLocationSourceInput?.addEventListener('change', () => {
|
|
|
|
|
eventLocationSourceSelect?.addEventListener('change', () => {
|
|
|
|
|
const mode = eventLocationModeSelect?.value || 'custom';
|
|
|
|
|
const option = findEventLocationOptionByLabel(eventLocationSourceInput.value || '');
|
|
|
|
|
const option = findEventLocationOptionById(eventLocationSourceSelect.value || '');
|
|
|
|
|
if (!option || String(option.listing_type || '') !== mode) {
|
|
|
|
|
clearEventLocationSelection();
|
|
|
|
|
return;
|
|
|
|
|
|