Events with a URL were saved with source "external", so Contao linked lists straight to the external site and redirected the detail page. The URL is now kept in the url field and only shown as a button on the detail page. - frontend form saves source "default" for every event - backend: source option "external" removed, url field relabelled "Externer Link", obsolete target field dropped from the palette - migration switches existing source="external" events to "default" Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
201 lines
8.6 KiB
PHP
201 lines
8.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use Contao\CoreBundle\DataContainer\PaletteManipulator;
|
|
use Contao\DataContainer;
|
|
use Contao\Database;
|
|
use Contao\StringUtil;
|
|
use Contao\System;
|
|
|
|
unset($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['location']);
|
|
unset($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['address']);
|
|
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['config']['onload_callback'][] = static function (): void {
|
|
if (!isset($GLOBALS['TL_DCA']['tl_calendar_events']['palettes']) || !is_array($GLOBALS['TL_DCA']['tl_calendar_events']['palettes'])) {
|
|
return;
|
|
}
|
|
|
|
foreach (array_keys($GLOBALS['TL_DCA']['tl_calendar_events']['palettes']) as $paletteName) {
|
|
if ($paletteName === '__selector__') {
|
|
continue;
|
|
}
|
|
|
|
PaletteManipulator::create()
|
|
->addLegend('organization_legend', 'details_legend', PaletteManipulator::POSITION_AFTER)
|
|
->addField(['location_id', 'tags', 'organizations'], 'organization_legend', PaletteManipulator::POSITION_APPEND)
|
|
->applyToPalette((string) $paletteName, 'tl_calendar_events');
|
|
|
|
PaletteManipulator::create()
|
|
->addField('photographer', 'image_legend', PaletteManipulator::POSITION_APPEND)
|
|
->applyToPalette((string) $paletteName, 'tl_calendar_events');
|
|
|
|
PaletteManipulator::create()
|
|
->addField(['source', 'url'], 'details_legend', PaletteManipulator::POSITION_APPEND)
|
|
->addField(['termsAccepted', 'isSoldOut', 'isCanceled'], 'publish_legend', PaletteManipulator::POSITION_APPEND)
|
|
->applyToPalette((string) $paletteName, 'tl_calendar_events');
|
|
}
|
|
};
|
|
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['config']['onbeforesubmit_callback'][] = static function (array $values): array {
|
|
unset($values['organizations']);
|
|
|
|
return $values;
|
|
};
|
|
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['location_id'] = [
|
|
'label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['location_id'],
|
|
'exclude' => true,
|
|
'filter' => true,
|
|
'sorting' => true,
|
|
'inputType' => 'select',
|
|
'foreignKey' => 'tl_location.title',
|
|
'options_callback' => static function (): array {
|
|
$result = Database::getInstance()
|
|
->query('SELECT id, title FROM tl_location ORDER BY title ASC');
|
|
|
|
$options = [];
|
|
|
|
foreach ($result->fetchAllAssoc() as $row) {
|
|
$options[(int) $row['id']] = (string) $row['title'];
|
|
}
|
|
|
|
return $options;
|
|
},
|
|
'eval' => ['mandatory' => true, 'includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50'],
|
|
'relation' => [
|
|
'type' => 'hasOne',
|
|
'load' => 'eager',
|
|
'table' => 'tl_location',
|
|
'field' => 'id',
|
|
],
|
|
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
|
];
|
|
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['tags'] = [
|
|
'label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['tags'],
|
|
'exclude' => true,
|
|
'filter' => true,
|
|
'inputType' => 'select',
|
|
'foreignKey' => 'tl_tags.tag',
|
|
'options_callback' => ['numero2_tags.listener.data_container.tags', 'getTagOptions'],
|
|
'load_callback' => [['numero2_tags.listener.data_container.tags', 'loadTags']],
|
|
'save_callback' => [['numero2_tags.listener.data_container.tags', 'saveTags']],
|
|
'eval' => ['multiple' => true, 'size' => 8, 'tl_class' => 'w50 tags', 'chosen' => true, 'groupTagsByField' => true, 'tagGroup' => 'event_type'],
|
|
'sql' => ['type' => 'blob', 'notnull' => false],
|
|
'relation' => ['type' => 'hasMany', 'load' => 'eager'],
|
|
];
|
|
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['organizations'] = [
|
|
'label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['organizations'],
|
|
'exclude' => true,
|
|
'inputType' => 'select',
|
|
'foreignKey' => 'tl_organization.title',
|
|
'eval' => ['multiple' => true, 'chosen' => true, 'tl_class' => 'clr'],
|
|
'relation' => [
|
|
'type' => 'hasMany',
|
|
'load' => 'lazy',
|
|
'table' => 'tl_organization',
|
|
'field' => 'id',
|
|
],
|
|
'load_callback' => [
|
|
static function ($value, DataContainer $dc): array {
|
|
if (!$dc->id) {
|
|
return [];
|
|
}
|
|
|
|
$result = Database::getInstance()
|
|
->prepare('SELECT organization_id FROM tl_calendar_events_organization WHERE event_id=? ORDER BY organization_id')
|
|
->execute($dc->id);
|
|
|
|
return array_map(static fn (array $row): int => (int) $row['organization_id'], $result->fetchAllAssoc());
|
|
},
|
|
],
|
|
'save_callback' => [
|
|
static function ($value, DataContainer $dc): array {
|
|
if (!$dc->id) {
|
|
return [];
|
|
}
|
|
|
|
$eventId = (int) $dc->id;
|
|
$organizationIds = array_values(array_unique(array_map('intval', StringUtil::deserialize($value, true))));
|
|
$db = Database::getInstance();
|
|
$time = time();
|
|
|
|
$db->prepare('DELETE FROM tl_calendar_events_organization WHERE event_id=?')
|
|
->execute($eventId);
|
|
|
|
foreach ($organizationIds as $organizationId) {
|
|
$db->prepare('INSERT INTO tl_calendar_events_organization (tstamp, event_id, organization_id) VALUES (?, ?, ?)')
|
|
->execute($time, $eventId, $organizationId);
|
|
}
|
|
|
|
return $organizationIds;
|
|
},
|
|
],
|
|
];
|
|
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['photographer'] = [
|
|
'label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['photographer'],
|
|
'exclude' => true,
|
|
'inputType' => 'text',
|
|
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
|
|
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
|
|
];
|
|
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['isSoldOut'] = [
|
|
'label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['isSoldOut'],
|
|
'exclude' => true,
|
|
'inputType' => 'checkbox',
|
|
'eval' => ['tl_class' => 'w50'],
|
|
'sql' => ['type' => 'string', 'length' => 1, 'fixed' => true, 'default' => ''],
|
|
];
|
|
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['isCanceled'] = [
|
|
'label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['isCanceled'],
|
|
'exclude' => true,
|
|
'inputType' => 'checkbox',
|
|
'eval' => ['tl_class' => 'w50'],
|
|
'sql' => ['type' => 'string', 'length' => 1, 'fixed' => true, 'default' => ''],
|
|
];
|
|
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['termsAccepted'] = [
|
|
'label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['termsAccepted'],
|
|
'exclude' => true,
|
|
'inputType' => 'checkbox',
|
|
'eval' => ['tl_class' => 'clr'],
|
|
'sql' => ['type' => 'string', 'length' => 1, 'fixed' => true, 'default' => ''],
|
|
];
|
|
|
|
if (isset($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['source']) && is_array($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['source'])) {
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['source']['eval'] ??= [];
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['source']['eval']['tl_class'] = 'w50';
|
|
|
|
// Keine Weiterleitung auf externe Seiten: Events öffnen immer die Detailseite,
|
|
// die externe URL (Feld "url") wird dort als Button ausgegeben.
|
|
$originalSourceOptionsCallback = $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['source']['options_callback'] ?? null;
|
|
|
|
if (null !== $originalSourceOptionsCallback) {
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['source']['options_callback'] = static function (DataContainer $dc) use ($originalSourceOptionsCallback): array {
|
|
$options = \is_array($originalSourceOptionsCallback)
|
|
? System::importStatic($originalSourceOptionsCallback[0])->{$originalSourceOptionsCallback[1]}($dc)
|
|
: $originalSourceOptionsCallback($dc);
|
|
|
|
return array_values(array_diff((array) $options, ['external']));
|
|
};
|
|
}
|
|
}
|
|
|
|
if (isset($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['target']) && is_array($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['target'])) {
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['target']['eval'] ??= [];
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['target']['eval']['tl_class'] = 'w50';
|
|
}
|
|
|
|
if (isset($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['url']) && is_array($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['url'])) {
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['url']['eval'] ??= [];
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['url']['eval']['tl_class'] = 'clr';
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['url']['label'] = &$GLOBALS['TL_LANG']['tl_calendar_events']['url'];
|
|
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['url']['eval']['mandatory'] = false;
|
|
unset($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['url']['eval']['rgxp']);
|
|
}
|