Initial release

This commit is contained in:
Jürgen Mummert
2026-02-17 18:53:23 +01:00
commit 63b5556b21
45 changed files with 3962 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_MODELS']['tl_organization'] = MummertMedia\EventManagerBundle\Model\OrganizationModel::class;
$GLOBALS['TL_MODELS']['tl_location'] = MummertMedia\EventManagerBundle\Model\LocationModel::class;
$GLOBALS['BE_MOD']['content']['eventmanager_organisationen'] = [
'tables' => ['tl_organization'],
];
$GLOBALS['BE_MOD']['content']['eventmanager_veranstaltungsorte'] = [
'tables' => ['tl_location'],
];
+180
View File
@@ -0,0 +1,180 @@
<?php
declare(strict_types=1);
use Contao\CoreBundle\DataContainer\PaletteManipulator;
use Contao\DataContainer;
use Contao\Database;
use Contao\StringUtil;
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', 'type', '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', 'target'], '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']['type'] = [
'label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['type'],
'exclude' => true,
'inputType' => 'select',
'options' => ['accommodation', 'shopping', 'culture'],
'reference' => &$GLOBALS['TL_LANG']['tl_calendar_events']['type_options'],
'eval' => ['multiple' => true, 'chosen' => true, 'includeBlankOption' => false, 'tl_class' => 'w50'],
'sql' => ['type' => 'blob', 'notnull' => false],
];
$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';
}
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']['eval']['mandatory'] = false;
unset($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['url']['eval']['rgxp']);
}
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
use Contao\DC_Table;
$GLOBALS['TL_DCA']['tl_calendar_events_organization'] = [
'config' => [
'dataContainer' => DC_Table::class,
'sql' => [
'keys' => [
'id' => 'primary',
'event_id' => 'index',
'organization_id' => 'index',
],
],
],
'fields' => [
'id' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'autoincrement' => true, 'notnull' => true],
],
'tstamp' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0, 'notnull' => true],
],
'event_id' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0, 'notnull' => true],
],
'organization_id' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0, 'notnull' => true],
],
],
];
+196
View File
@@ -0,0 +1,196 @@
<?php
declare(strict_types=1);
use Contao\DataContainer;
use Contao\Database;
use Contao\DC_Table;
use Contao\StringUtil;
$GLOBALS['TL_DCA']['tl_location'] = [
'config' => [
'dataContainer' => DC_Table::class,
'enableVersioning' => true,
'sql' => [
'keys' => [
'id' => 'primary',
'alias' => 'index',
'published' => 'index',
'title' => 'index',
],
],
],
'list' => [
'sorting' => [
'mode' => 1,
'fields' => ['title'],
'flag' => 1,
'panelLayout' => 'search,limit',
],
'label' => [
'fields' => ['title', 'city'],
'format' => '%s (%s)',
],
'global_operations' => [
'all' => [
'href' => 'act=select',
'class' => 'header_edit_all',
'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"',
],
],
'operations' => [
'edit' => [
'href' => 'act=edit',
'icon' => 'edit.svg',
],
'copy' => [
'href' => 'act=copy',
'icon' => 'copy.svg',
],
'delete' => [
'href' => 'act=delete',
'icon' => 'delete.svg',
'attributes' => 'onclick="if(!confirm(\'' . (string) ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? '') . '\'))return false;Backend.getScrollOffset()"',
],
'toggle' => [
'href' => 'act=toggle&amp;field=published',
'icon' => 'visible.svg',
],
'show' => [
'href' => 'act=show',
'icon' => 'show.svg',
],
],
],
'palettes' => [
'__selector__' => [],
'default' => '{title_legend},title,alias,image;{address_legend},street,street2,postal,city,state,country;{geo_legend},lat,lng;{description_legend},description;{publish_legend},published',
],
'fields' => [
'id' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'autoincrement' => true],
],
'tstamp' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
],
'dateAdded' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
],
'title' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['title'],
'exclude' => true,
'search' => true,
'sorting' => true,
'inputType' => 'text',
'eval' => ['mandatory' => true, 'maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'alias' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['alias'],
'exclude' => true,
'search' => true,
'inputType' => 'text',
'eval' => ['rgxp' => 'alias', 'unique' => true, 'maxlength' => 128, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 128, 'default' => ''],
],
'description' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['description'],
'exclude' => true,
'inputType' => 'textarea',
'eval' => ['rte' => 'tinyMCE', 'tl_class' => 'clr'],
'sql' => ['type' => 'text', 'notnull' => false],
],
'street' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['street'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'street2' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['street2'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'postal' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['postal'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'city' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['city'],
'exclude' => true,
'search' => true,
'sorting' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'state' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['state'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'country' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['country'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 2, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 2, 'default' => 'de'],
],
'lat' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['lat'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 10, 'tl_class' => 'w50'],
'sql' => ['type' => 'decimal', 'precision' => 10, 'scale' => 8, 'default' => '0.00000000'],
],
'lng' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['lng'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 11, 'tl_class' => 'w50'],
'sql' => ['type' => 'decimal', 'precision' => 11, 'scale' => 8, 'default' => '0.00000000'],
],
'image' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['image'],
'exclude' => true,
'inputType' => 'fileTree',
'eval' => ['filesOnly' => true, 'fieldType' => 'radio', 'tl_class' => 'clr'],
'sql' => ['type' => 'binary', 'length' => 16, 'notnull' => false],
],
'published' => [
'label' => &$GLOBALS['TL_LANG']['tl_location']['published'],
'exclude' => true,
'filter' => true,
'toggle' => true,
'inputType' => 'checkbox',
'eval' => ['doNotCopy' => true],
'sql' => ['type' => 'string', 'length' => 1, 'fixed' => true, 'default' => ''],
],
],
];
$GLOBALS['TL_DCA']['tl_location']['fields']['alias']['save_callback'][] = static function (string $value, DataContainer $dc): string {
if ($value !== '') {
return $value;
}
$value = StringUtil::generateAlias($dc->activeRecord?->title ?? '');
$exists = Database::getInstance()
->prepare('SELECT id FROM tl_location WHERE alias=? AND id!=?')
->execute($value, (int) ($dc->id ?? 0));
if ($exists->numRows > 0) {
throw new \RuntimeException(sprintf((string) ($GLOBALS['TL_LANG']['tl_location']['aliasExists'] ?? '%s'), $value));
}
return $value;
};
+102
View File
@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
use Contao\CoreBundle\DataContainer\PaletteManipulator;
use Contao\DataContainer;
use Contao\Database;
use Contao\Input;
use Contao\StringUtil;
if (isset($GLOBALS['TL_DCA']['tl_member']['palettes']) && is_array($GLOBALS['TL_DCA']['tl_member']['palettes'])) {
foreach (array_keys($GLOBALS['TL_DCA']['tl_member']['palettes']) as $paletteName) {
if ($paletteName === '__selector__') {
continue;
}
PaletteManipulator::create()
->addLegend('organization_legend', 'contact_legend', PaletteManipulator::POSITION_AFTER)
->addField('organizations', 'organization_legend', PaletteManipulator::POSITION_APPEND)
->applyToPalette((string) $paletteName, 'tl_member');
}
}
$GLOBALS['TL_DCA']['tl_member']['config']['onbeforesubmit_callback'][] = static function (array $values): array {
unset($values['organizations']);
return $values;
};
$GLOBALS['TL_DCA']['tl_member']['config']['onsubmit_callback'][] = static function (DataContainer $dc): void {
if (!$dc->id) {
return;
}
$postedValues = Input::post('organizations');
if (null === $postedValues) {
return;
}
$organizationIds = array_values(array_unique(array_map('intval', is_array($postedValues) ? $postedValues : [$postedValues])));
$memberId = (int) $dc->id;
$db = Database::getInstance();
$time = time();
$db->prepare('DELETE FROM tl_member_organization WHERE member_id=?')
->execute($memberId);
foreach ($organizationIds as $organizationId) {
$db->prepare('INSERT INTO tl_member_organization (tstamp, member_id, organization_id) VALUES (?, ?, ?)')
->execute($time, $memberId, $organizationId);
}
};
$GLOBALS['TL_DCA']['tl_member']['fields']['organizations'] = [
'label' => &$GLOBALS['TL_LANG']['tl_member']['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_member_organization WHERE member_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 [];
}
$memberId = (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_member_organization WHERE member_id=?')
->execute($memberId);
foreach ($organizationIds as $organizationId) {
$db->prepare('INSERT INTO tl_member_organization (tstamp, member_id, organization_id) VALUES (?, ?, ?)')
->execute($time, $memberId, $organizationId);
}
return $organizationIds;
},
],
];
+32
View File
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
use Contao\DC_Table;
$GLOBALS['TL_DCA']['tl_member_organization'] = [
'config' => [
'dataContainer' => DC_Table::class,
'sql' => [
'keys' => [
'id' => 'primary',
'member_id' => 'index',
'organization_id' => 'index',
],
],
],
'fields' => [
'id' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'autoincrement' => true, 'notnull' => true],
],
'tstamp' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0, 'notnull' => true],
],
'member_id' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0, 'notnull' => true],
],
'organization_id' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0, 'notnull' => true],
],
],
];
+64
View File
@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_DCA']['tl_module']['palettes']['member_organizations'] = '{title_legend},name,headline,type;{eventmanager_legend},editPage;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
$GLOBALS['TL_DCA']['tl_module']['palettes']['member_events'] = '{title_legend},name,headline,type;{eventmanager_legend},editPage;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
$GLOBALS['TL_DCA']['tl_module']['palettes']['organization_edit'] = '{title_legend},name,headline,type;{eventmanager_legend},listPage,logoFolder;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
$GLOBALS['TL_DCA']['tl_module']['palettes']['event_edit'] = '{title_legend},name,headline,type;{eventmanager_legend},listPage,eventFolder,termsPage,frontendAuthorId,frontendArchiveId;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
$GLOBALS['TL_DCA']['tl_module']['fields']['editPage'] = [
'label' => &$GLOBALS['TL_LANG']['tl_module']['editPage'],
'exclude' => true,
'inputType' => 'pageTree',
'eval' => ['fieldType' => 'radio', 'mandatory' => true, 'tl_class' => 'w50'],
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
];
$GLOBALS['TL_DCA']['tl_module']['fields']['listPage'] = [
'label' => &$GLOBALS['TL_LANG']['tl_module']['listPage'],
'exclude' => true,
'inputType' => 'pageTree',
'eval' => ['fieldType' => 'radio', 'mandatory' => true, 'tl_class' => 'w50'],
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
];
$GLOBALS['TL_DCA']['tl_module']['fields']['logoFolder'] = [
'label' => &$GLOBALS['TL_LANG']['tl_module']['logoFolder'],
'exclude' => true,
'inputType' => 'fileTree',
'eval' => ['fieldType' => 'radio', 'files' => false, 'mandatory' => true, 'tl_class' => 'w50'],
'sql' => ['type' => 'binary', 'length' => 16, 'notnull' => false],
];
$GLOBALS['TL_DCA']['tl_module']['fields']['eventFolder'] = [
'label' => &$GLOBALS['TL_LANG']['tl_module']['eventFolder'],
'exclude' => true,
'inputType' => 'fileTree',
'eval' => ['fieldType' => 'radio', 'files' => false, 'mandatory' => true, 'tl_class' => 'w50'],
'sql' => ['type' => 'binary', 'length' => 16, 'notnull' => false],
];
$GLOBALS['TL_DCA']['tl_module']['fields']['termsPage'] = [
'label' => &$GLOBALS['TL_LANG']['tl_module']['termsPage'],
'exclude' => true,
'inputType' => 'pageTree',
'eval' => ['fieldType' => 'radio', 'mandatory' => false, 'tl_class' => 'w50'],
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
];
$GLOBALS['TL_DCA']['tl_module']['fields']['frontendAuthorId'] = [
'label' => &$GLOBALS['TL_LANG']['tl_module']['frontendAuthorId'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['mandatory' => true, 'rgxp' => 'digit', 'maxlength' => 10, 'tl_class' => 'w50'],
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
];
$GLOBALS['TL_DCA']['tl_module']['fields']['frontendArchiveId'] = [
'label' => &$GLOBALS['TL_LANG']['tl_module']['frontendArchiveId'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['mandatory' => true, 'rgxp' => 'digit', 'maxlength' => 10, 'tl_class' => 'w50'],
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
];
+304
View File
@@ -0,0 +1,304 @@
<?php
declare(strict_types=1);
use Contao\DataContainer;
use Contao\Database;
use Contao\DC_Table;
use Contao\StringUtil;
$GLOBALS['TL_DCA']['tl_organization'] = [
'config' => [
'dataContainer' => DC_Table::class,
'enableVersioning' => true,
'onbeforesubmit_callback' => [
static function (array $values): array {
unset($values['members']);
return $values;
},
],
'sql' => [
'keys' => [
'id' => 'primary',
'alias' => 'index',
'published' => 'index',
],
],
],
'list' => [
'sorting' => [
'mode' => 1,
'fields' => ['title'],
'flag' => 1,
'panelLayout' => 'search,limit',
],
'label' => [
'fields' => ['title', 'city'],
'format' => '%s (%s)',
],
'global_operations' => [
'all' => [
'href' => 'act=select',
'class' => 'header_edit_all',
'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"',
],
],
'operations' => [
'edit' => [
'href' => 'act=edit',
'icon' => 'edit.svg',
],
'copy' => [
'href' => 'act=copy',
'icon' => 'copy.svg',
],
'delete' => [
'href' => 'act=delete',
'icon' => 'delete.svg',
'attributes' => 'onclick="if(!confirm(\'' . (string) ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? '') . '\'))return false;Backend.getScrollOffset()"',
],
'toggle' => [
'href' => 'act=toggle&amp;field=published',
'icon' => 'visible.svg',
],
'show' => [
'href' => 'act=show',
'icon' => 'show.svg',
],
],
],
'palettes' => [
'__selector__' => [],
'default' => '{title_legend},title,alias,type,isExternal,logo;{address_legend},street,street2,postal,city,state,country;{contact_legend},phone,email,website;{geo_legend},lat,lng;{description_legend},description;{relation_legend},members;{publish_legend},published',
],
'fields' => [
'id' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'autoincrement' => true],
],
'pid' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
],
'tstamp' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
],
'dateAdded' => [
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
],
'title' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['title'],
'exclude' => true,
'search' => true,
'sorting' => true,
'inputType' => 'text',
'eval' => ['mandatory' => true, 'maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'alias' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['alias'],
'exclude' => true,
'search' => true,
'inputType' => 'text',
'eval' => ['rgxp' => 'alias', 'unique' => true, 'maxlength' => 128, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 128, 'default' => ''],
],
'logo' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['logo'],
'exclude' => true,
'inputType' => 'fileTree',
'eval' => ['filesOnly' => true, 'fieldType' => 'radio', 'tl_class' => 'clr'],
'sql' => ['type' => 'binary', 'length' => 16, 'notnull' => false],
],
'street' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['street'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'street2' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['street2'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'postal' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['postal'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'city' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['city'],
'exclude' => true,
'search' => true,
'sorting' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'state' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['state'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'country' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['country'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 2, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 2, 'default' => ''],
],
'phone' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['phone'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 64, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 64, 'default' => ''],
],
'email' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['email'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['rgxp' => 'email', 'maxlength' => 255, 'tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'website' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['website'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['rgxp' => 'url', 'maxlength' => 255, 'tl_class' => 'clr'],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
'lat' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['lat'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 10, 'tl_class' => 'w50'],
'sql' => ['type' => 'decimal', 'precision' => 10, 'scale' => 8, 'default' => '0.00000000'],
],
'lng' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['lng'],
'exclude' => true,
'inputType' => 'text',
'eval' => ['maxlength' => 11, 'tl_class' => 'w50'],
'sql' => ['type' => 'decimal', 'precision' => 11, 'scale' => 8, 'default' => '0.00000000'],
],
'description' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['description'],
'exclude' => true,
'inputType' => 'textarea',
'eval' => ['rte' => 'tinyMCE', 'tl_class' => 'clr'],
'sql' => ['type' => 'text', 'notnull' => false],
],
'published' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['published'],
'exclude' => true,
'filter' => true,
'toggle' => true,
'inputType' => 'checkbox',
'eval' => ['doNotCopy' => true],
'sql' => ['type' => 'string', 'length' => 1, 'fixed' => true, 'default' => ''],
],
'isExternal' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['isExternal'],
'exclude' => true,
'inputType' => 'checkbox',
'eval' => ['tl_class' => 'w50'],
'sql' => ['type' => 'string', 'length' => 1, 'fixed' => true, 'default' => ''],
],
'type' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['type'],
'exclude' => true,
'inputType' => 'select',
'options' => ['accommodation', 'shopping', 'culture'],
'reference' => &$GLOBALS['TL_LANG']['tl_organization']['type_options'],
'eval' => ['multiple' => true, 'chosen' => true, 'includeBlankOption' => false, 'tl_class' => 'w50'],
'sql' => ['type' => 'blob', 'notnull' => false],
],
'members' => [
'label' => &$GLOBALS['TL_LANG']['tl_organization']['members'],
'exclude' => true,
'inputType' => 'select',
'options_callback' => static function (): array {
$result = Database::getInstance()
->query('SELECT id, firstname, lastname FROM tl_member ORDER BY lastname ASC, firstname ASC');
$options = [];
foreach ($result->fetchAllAssoc() as $row) {
$name = trim(($row['firstname'] ?? '') . ' ' . ($row['lastname'] ?? ''));
$options[(int) $row['id']] = $name !== ''
? $name
: sprintf((string) ($GLOBALS['TL_LANG']['tl_organization']['memberFallback'] ?? '%s'), $row['id']);
}
return $options;
},
'eval' => ['multiple' => true, 'chosen' => true, 'tl_class' => 'clr'],
'relation' => [
'type' => 'hasMany',
'load' => 'lazy',
'table' => 'tl_member',
'field' => 'id',
],
'load_callback' => [
static function ($value, DataContainer $dc): array {
if (!$dc->id) {
return [];
}
$result = Database::getInstance()
->prepare('SELECT member_id FROM tl_member_organization WHERE organization_id=? ORDER BY member_id')
->execute($dc->id);
return array_map(static fn (array $row): int => (int) $row['member_id'], $result->fetchAllAssoc());
},
],
'save_callback' => [
static function ($value, DataContainer $dc): array {
if (!$dc->id) {
return [];
}
$organizationId = (int) $dc->id;
$memberIds = array_values(array_unique(array_map('intval', StringUtil::deserialize($value, true))));
$db = Database::getInstance();
$time = time();
$db->prepare('DELETE FROM tl_member_organization WHERE organization_id=?')
->execute($organizationId);
foreach ($memberIds as $memberId) {
$db->prepare('INSERT INTO tl_member_organization (tstamp, member_id, organization_id) VALUES (?, ?, ?)')
->execute($time, $memberId, $organizationId);
}
return $memberIds;
},
],
],
],
];
$GLOBALS['TL_DCA']['tl_organization']['fields']['alias']['save_callback'][] = static function (string $value, DataContainer $dc): string {
if ($value !== '') {
return $value;
}
$value = StringUtil::generateAlias($dc->activeRecord?->title ?? '');
$exists = Database::getInstance()
->prepare('SELECT id FROM tl_organization WHERE alias=? AND id!=?')
->execute($value, (int) ($dc->id ?? 0));
if ($exists->numRows > 0) {
throw new \RuntimeException(sprintf((string) ($GLOBALS['TL_LANG']['tl_organization']['aliasExists'] ?? '%s'), $value));
}
return $value;
};
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['MOD']['eventmanager_organisationen'] = ['Organisationen', 'Organisationen verwalten'];
$GLOBALS['TL_LANG']['MOD']['eventmanager_veranstaltungsorte'] = ['Veranstaltungsorte', 'Veranstaltungsorte verwalten'];
$GLOBALS['TL_LANG']['FMD']['eventmanager'] = 'Event-Manager';
$GLOBALS['TL_LANG']['FMD']['member_organizations'] = ['Meine Organisationen', 'Listet Organisationen des eingeloggten Mitglieds auf.'];
$GLOBALS['TL_LANG']['FMD']['organization_edit'] = ['Organisation bearbeiten', 'Bearbeitungsformular für eine Organisation.'];
$GLOBALS['TL_LANG']['FMD']['member_events'] = ['Meine Veranstaltungen', 'Listet Veranstaltungen der zugeordneten Organisationen auf.'];
$GLOBALS['TL_LANG']['FMD']['event_edit'] = ['Veranstaltung bearbeiten', 'Bearbeitungsformular für eine Veranstaltung.'];
@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['tl_calendar_events']['organization_legend'] = 'Organisationen und Ort';
$GLOBALS['TL_LANG']['tl_calendar_events']['location_id'] = ['Veranstaltungsort', 'Zugeordneter Veranstaltungsort'];
$GLOBALS['TL_LANG']['tl_calendar_events']['type'] = ['Typ', 'Mehrere Typen auswählbar.'];
$GLOBALS['TL_LANG']['tl_calendar_events']['organizations'] = ['Organisationen', 'Zugeordnete Organisationen'];
$GLOBALS['TL_LANG']['tl_calendar_events']['photographer'] = ['Urheber/Fotograf', 'Die Angabe des Urhebers ist notwendig. Ihnen muss eine Genehmigung zur Verwendung des Bildes vorliegen.'];
$GLOBALS['TL_LANG']['tl_calendar_events']['isSoldOut'] = ['Ausverkauft', 'Diese Veranstaltung ist ausverkauft.'];
$GLOBALS['TL_LANG']['tl_calendar_events']['isCanceled'] = ['Abgesagt', 'Diese Veranstaltung wurde abgesagt.'];
$GLOBALS['TL_LANG']['tl_calendar_events']['termsAccepted'] = ['Nutzungsbedingungen akzeptiert', 'Die Nutzungsbedingungen wurden akzeptiert.'];
$GLOBALS['TL_LANG']['tl_calendar_events']['type_options']['accommodation'] = 'Unterkunft';
$GLOBALS['TL_LANG']['tl_calendar_events']['type_options']['shopping'] = 'Shopping';
$GLOBALS['TL_LANG']['tl_calendar_events']['type_options']['culture'] = 'Kultur';
+25
View File
@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['tl_location']['title'] = ['Titel', 'Name des Veranstaltungsortes'];
$GLOBALS['TL_LANG']['tl_location']['alias'] = ['Alias', 'Eindeutiger Alias des Veranstaltungsortes'];
$GLOBALS['TL_LANG']['tl_location']['description'] = ['Beschreibung', 'Beschreibung'];
$GLOBALS['TL_LANG']['tl_location']['street'] = ['Straße', 'Straße'];
$GLOBALS['TL_LANG']['tl_location']['street2'] = ['Adresszusatz', 'Adresszusatz'];
$GLOBALS['TL_LANG']['tl_location']['postal'] = ['PLZ', 'Postleitzahl'];
$GLOBALS['TL_LANG']['tl_location']['city'] = ['Ort', 'Ort'];
$GLOBALS['TL_LANG']['tl_location']['state'] = ['Bundesland', 'Bundesland'];
$GLOBALS['TL_LANG']['tl_location']['country'] = ['Land', 'Land'];
$GLOBALS['TL_LANG']['tl_location']['lat'] = ['Breitengrad', 'Breitengrad'];
$GLOBALS['TL_LANG']['tl_location']['lng'] = ['Längengrad', 'Längengrad'];
$GLOBALS['TL_LANG']['tl_location']['image'] = ['Bild', 'Bild-Datei'];
$GLOBALS['TL_LANG']['tl_location']['published'] = ['Veröffentlicht', 'Veranstaltungsort veröffentlichen'];
$GLOBALS['TL_LANG']['tl_location']['title_legend'] = 'Titel';
$GLOBALS['TL_LANG']['tl_location']['address_legend'] = 'Adresse';
$GLOBALS['TL_LANG']['tl_location']['geo_legend'] = 'Geodaten';
$GLOBALS['TL_LANG']['tl_location']['description_legend'] = 'Beschreibung';
$GLOBALS['TL_LANG']['tl_location']['publish_legend'] = 'Veröffentlichung';
$GLOBALS['TL_LANG']['tl_location']['aliasExists'] = 'Alias "%s" ist bereits vergeben.';
+6
View File
@@ -0,0 +1,6 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['tl_member']['organization_legend'] = 'Organisationen';
$GLOBALS['TL_LANG']['tl_member']['organizations'] = ['Organisationen', 'Zugeordnete Organisationen'];
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['tl_module']['eventmanager_legend'] = 'Event-Manager';
$GLOBALS['TL_LANG']['tl_module']['editPage'] = ['Bearbeitungsseite', 'Bitte wählen Sie die Seite mit dem Bearbeitungsmodul aus.'];
$GLOBALS['TL_LANG']['tl_module']['listPage'] = ['Listenansicht-Seite', 'Bitte wählen Sie die Seite mit dem Listenmodul aus.'];
$GLOBALS['TL_LANG']['tl_module']['logoFolder'] = ['Logo-Ordner', 'Bitte wählen Sie den Ordner aus, in dem hochgeladene Organisationslogos gespeichert werden sollen.'];
$GLOBALS['TL_LANG']['tl_module']['eventFolder'] = ['Event-Ordner', 'Bitte wählen Sie den Ordner aus, in dem eventbezogene Uploads gespeichert werden sollen.'];
$GLOBALS['TL_LANG']['tl_module']['termsPage'] = ['Seite mit Nutzungsbedingungen', 'Optional: Seite mit den Nutzungsbedingungen, die im Frontend beim Zustimmungs-Label verlinkt wird.'];
$GLOBALS['TL_LANG']['tl_module']['frontendAuthorId'] = ['Backend Benutzer ID', 'ID des Backend-Benutzers, der als Autor für frontendseitig angelegte Events gesetzt wird.'];
$GLOBALS['TL_LANG']['tl_module']['frontendArchiveId'] = ['ID des Newsarchivs', 'Archiv-ID (pid), in das frontendseitig angelegte Events gespeichert werden.'];
+38
View File
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['tl_organization']['title'] = ['Titel', 'Name der Organisation'];
$GLOBALS['TL_LANG']['tl_organization']['alias'] = ['Alias', 'Eindeutiger Alias der Organisation'];
$GLOBALS['TL_LANG']['tl_organization']['logo'] = ['Logo', 'Logo-Datei'];
$GLOBALS['TL_LANG']['tl_organization']['street'] = ['Straße', 'Straße'];
$GLOBALS['TL_LANG']['tl_organization']['street2'] = ['Adresszusatz', 'Adresszusatz'];
$GLOBALS['TL_LANG']['tl_organization']['postal'] = ['PLZ', 'Postleitzahl'];
$GLOBALS['TL_LANG']['tl_organization']['city'] = ['Ort', 'Ort'];
$GLOBALS['TL_LANG']['tl_organization']['state'] = ['Bundesland', 'Bundesland'];
$GLOBALS['TL_LANG']['tl_organization']['country'] = ['Land', 'Land'];
$GLOBALS['TL_LANG']['tl_organization']['phone'] = ['Telefon', 'Telefonnummer'];
$GLOBALS['TL_LANG']['tl_organization']['email'] = ['E-Mail', 'E-Mail-Adresse'];
$GLOBALS['TL_LANG']['tl_organization']['website'] = ['Webseite', 'Webseite'];
$GLOBALS['TL_LANG']['tl_organization']['lat'] = ['Breitengrad', 'Breitengrad'];
$GLOBALS['TL_LANG']['tl_organization']['lng'] = ['Längengrad', 'Längengrad'];
$GLOBALS['TL_LANG']['tl_organization']['description'] = ['Beschreibung', 'Beschreibung'];
$GLOBALS['TL_LANG']['tl_organization']['published'] = ['Veröffentlicht', 'Organisation veröffentlichen'];
$GLOBALS['TL_LANG']['tl_organization']['isExternal'] = ['Extern', 'Externe Organisation'];
$GLOBALS['TL_LANG']['tl_organization']['type'] = ['Typ', 'Mehrere Typen auswählbar.'];
$GLOBALS['TL_LANG']['tl_organization']['members'] = ['Mitglieder', 'Zugeordnete Mitglieder'];
$GLOBALS['TL_LANG']['tl_organization']['type_options']['accommodation'] = 'Unterkunft';
$GLOBALS['TL_LANG']['tl_organization']['type_options']['shopping'] = 'Shopping';
$GLOBALS['TL_LANG']['tl_organization']['type_options']['culture'] = 'Kultur';
$GLOBALS['TL_LANG']['tl_organization']['title_legend'] = 'Titel';
$GLOBALS['TL_LANG']['tl_organization']['address_legend'] = 'Adresse';
$GLOBALS['TL_LANG']['tl_organization']['contact_legend'] = 'Kontakt';
$GLOBALS['TL_LANG']['tl_organization']['geo_legend'] = 'Geodaten';
$GLOBALS['TL_LANG']['tl_organization']['description_legend'] = 'Beschreibung';
$GLOBALS['TL_LANG']['tl_organization']['relation_legend'] = 'Beziehungen';
$GLOBALS['TL_LANG']['tl_organization']['publish_legend'] = 'Veröffentlichung';
$GLOBALS['TL_LANG']['tl_organization']['memberFallback'] = 'Mitglied #%s';
$GLOBALS['TL_LANG']['tl_organization']['aliasExists'] = 'Alias "%s" ist bereits vergeben.';
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['MOD']['eventmanager_organisationen'] = ['Organizations', 'Manage organizations'];
$GLOBALS['TL_LANG']['MOD']['eventmanager_veranstaltungsorte'] = ['Locations', 'Manage locations'];
$GLOBALS['TL_LANG']['FMD']['eventmanager'] = 'Event manager';
$GLOBALS['TL_LANG']['FMD']['member_organizations'] = ['My organizations', 'Lists organizations of the logged-in member.'];
$GLOBALS['TL_LANG']['FMD']['organization_edit'] = ['Edit organization', 'Edit form for one organization.'];
$GLOBALS['TL_LANG']['FMD']['member_events'] = ['My events', 'Lists events of the member organizations.'];
$GLOBALS['TL_LANG']['FMD']['event_edit'] = ['Edit event', 'Edit form for one event.'];
@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['tl_calendar_events']['organization_legend'] = 'Organizations and location';
$GLOBALS['TL_LANG']['tl_calendar_events']['location_id'] = ['Location', 'Assigned location'];
$GLOBALS['TL_LANG']['tl_calendar_events']['type'] = ['Type', 'Multiple types can be selected.'];
$GLOBALS['TL_LANG']['tl_calendar_events']['organizations'] = ['Organizations', 'Assigned organizations'];
$GLOBALS['TL_LANG']['tl_calendar_events']['photographer'] = ['Author/Photographer', 'Please provide the image author/photographer and make sure you have permission to use the image.'];
$GLOBALS['TL_LANG']['tl_calendar_events']['isSoldOut'] = ['Sold out', 'This event is sold out.'];
$GLOBALS['TL_LANG']['tl_calendar_events']['isCanceled'] = ['Canceled', 'This event has been canceled.'];
$GLOBALS['TL_LANG']['tl_calendar_events']['termsAccepted'] = ['Terms accepted', 'The terms of use have been accepted.'];
$GLOBALS['TL_LANG']['tl_calendar_events']['type_options']['accommodation'] = 'Accommodation';
$GLOBALS['TL_LANG']['tl_calendar_events']['type_options']['shopping'] = 'Shopping';
$GLOBALS['TL_LANG']['tl_calendar_events']['type_options']['culture'] = 'Culture';
+25
View File
@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['tl_location']['title'] = ['Title', 'Location name'];
$GLOBALS['TL_LANG']['tl_location']['alias'] = ['Alias', 'Unique location alias'];
$GLOBALS['TL_LANG']['tl_location']['description'] = ['Description', 'Description'];
$GLOBALS['TL_LANG']['tl_location']['street'] = ['Street', 'Street'];
$GLOBALS['TL_LANG']['tl_location']['street2'] = ['Address line 2', 'Address line 2'];
$GLOBALS['TL_LANG']['tl_location']['postal'] = ['Postal code', 'Postal code'];
$GLOBALS['TL_LANG']['tl_location']['city'] = ['City', 'City'];
$GLOBALS['TL_LANG']['tl_location']['state'] = ['State', 'State'];
$GLOBALS['TL_LANG']['tl_location']['country'] = ['Country', 'Country'];
$GLOBALS['TL_LANG']['tl_location']['lat'] = ['Latitude', 'Latitude'];
$GLOBALS['TL_LANG']['tl_location']['lng'] = ['Longitude', 'Longitude'];
$GLOBALS['TL_LANG']['tl_location']['image'] = ['Image', 'Image file'];
$GLOBALS['TL_LANG']['tl_location']['published'] = ['Published', 'Publish location'];
$GLOBALS['TL_LANG']['tl_location']['title_legend'] = 'Title';
$GLOBALS['TL_LANG']['tl_location']['address_legend'] = 'Address';
$GLOBALS['TL_LANG']['tl_location']['geo_legend'] = 'Geo data';
$GLOBALS['TL_LANG']['tl_location']['description_legend'] = 'Description';
$GLOBALS['TL_LANG']['tl_location']['publish_legend'] = 'Publication';
$GLOBALS['TL_LANG']['tl_location']['aliasExists'] = 'Alias "%s" already exists.';
+6
View File
@@ -0,0 +1,6 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['tl_member']['organization_legend'] = 'Organizations';
$GLOBALS['TL_LANG']['tl_member']['organizations'] = ['Organizations', 'Assigned organizations'];
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['tl_module']['eventmanager_legend'] = 'Event manager';
$GLOBALS['TL_LANG']['tl_module']['editPage'] = ['Edit page', 'Please select the page containing the edit module.'];
$GLOBALS['TL_LANG']['tl_module']['listPage'] = ['List page', 'Please select the page containing the list module.'];
$GLOBALS['TL_LANG']['tl_module']['logoFolder'] = ['Logo folder', 'Please select the folder where uploaded organization logos should be stored.'];
$GLOBALS['TL_LANG']['tl_module']['eventFolder'] = ['Event folder', 'Please select the folder where event-related uploads should be stored.'];
$GLOBALS['TL_LANG']['tl_module']['termsPage'] = ['Terms page', 'Optional: page containing the terms of use linked from the frontend consent label.'];
$GLOBALS['TL_LANG']['tl_module']['frontendAuthorId'] = ['Backend user ID', 'Backend user ID that should be set as author for events created from the frontend.'];
$GLOBALS['TL_LANG']['tl_module']['frontendArchiveId'] = ['News archive ID', 'Archive ID (pid) where events created from the frontend should be stored.'];
+38
View File
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
$GLOBALS['TL_LANG']['tl_organization']['title'] = ['Title', 'Organization name'];
$GLOBALS['TL_LANG']['tl_organization']['alias'] = ['Alias', 'Unique organization alias'];
$GLOBALS['TL_LANG']['tl_organization']['logo'] = ['Logo', 'Logo file'];
$GLOBALS['TL_LANG']['tl_organization']['street'] = ['Street', 'Street'];
$GLOBALS['TL_LANG']['tl_organization']['street2'] = ['Address line 2', 'Address line 2'];
$GLOBALS['TL_LANG']['tl_organization']['postal'] = ['Postal code', 'Postal code'];
$GLOBALS['TL_LANG']['tl_organization']['city'] = ['City', 'City'];
$GLOBALS['TL_LANG']['tl_organization']['state'] = ['State', 'State'];
$GLOBALS['TL_LANG']['tl_organization']['country'] = ['Country', 'Country'];
$GLOBALS['TL_LANG']['tl_organization']['phone'] = ['Phone', 'Phone number'];
$GLOBALS['TL_LANG']['tl_organization']['email'] = ['Email', 'Email address'];
$GLOBALS['TL_LANG']['tl_organization']['website'] = ['Website', 'Website'];
$GLOBALS['TL_LANG']['tl_organization']['lat'] = ['Latitude', 'Latitude'];
$GLOBALS['TL_LANG']['tl_organization']['lng'] = ['Longitude', 'Longitude'];
$GLOBALS['TL_LANG']['tl_organization']['description'] = ['Description', 'Description'];
$GLOBALS['TL_LANG']['tl_organization']['published'] = ['Published', 'Publish organization'];
$GLOBALS['TL_LANG']['tl_organization']['isExternal'] = ['External', 'External organization'];
$GLOBALS['TL_LANG']['tl_organization']['type'] = ['Type', 'Multiple types can be selected.'];
$GLOBALS['TL_LANG']['tl_organization']['members'] = ['Members', 'Assigned members'];
$GLOBALS['TL_LANG']['tl_organization']['type_options']['accommodation'] = 'Accommodation';
$GLOBALS['TL_LANG']['tl_organization']['type_options']['shopping'] = 'Shopping';
$GLOBALS['TL_LANG']['tl_organization']['type_options']['culture'] = 'Culture';
$GLOBALS['TL_LANG']['tl_organization']['title_legend'] = 'Title';
$GLOBALS['TL_LANG']['tl_organization']['address_legend'] = 'Address';
$GLOBALS['TL_LANG']['tl_organization']['contact_legend'] = 'Contact';
$GLOBALS['TL_LANG']['tl_organization']['geo_legend'] = 'Geo data';
$GLOBALS['TL_LANG']['tl_organization']['description_legend'] = 'Description';
$GLOBALS['TL_LANG']['tl_organization']['relation_legend'] = 'Relations';
$GLOBALS['TL_LANG']['tl_organization']['publish_legend'] = 'Publication';
$GLOBALS['TL_LANG']['tl_organization']['memberFallback'] = 'Member #%s';
$GLOBALS['TL_LANG']['tl_organization']['aliasExists'] = 'Alias "%s" already exists.';
View File
@@ -0,0 +1,310 @@
{% extends "@Contao/frontend_module/_base.html.twig" %}
{% block content %}
{% if error is defined and error %}
<p role="alert">{{ error }}</p>
<p><a href="{{ backUrl }}">Zurück</a></p>
{% elseif form is defined and form %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/themes/airbnb.css">
<link rel="stylesheet" href="https://unpkg.com/filepond/dist/filepond.min.css">
<link rel="stylesheet" href="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css">
<script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/de.js"></script>
<script src="https://unpkg.com/filepond/dist/filepond.min.js"></script>
<script src="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.js"></script>
{{ form_start(form, { action: app.request.uri, attr: { 'aria-live': 'polite' } }) }}
<input type="hidden" name="REQUEST_TOKEN" value="{{ requestToken }}">
<input type="hidden" id="remove_image" name="remove_image" value="0">
{{ form_row(form.title) }}
{{ form_row(form.startDate) }}
{{ form_row(form.endDate) }}
{{ form_row(form.addTime) }}
<div id="event-time-wrap" style="display:none;" hidden aria-hidden="true">
{{ form_row(form.startTime) }}
{{ form_row(form.endTime) }}
</div>
{% if form.organization_ids is defined %}
{{ form_row(form.organization_ids) }}
{% endif %}
{{ form_row(form.location_id) }}
{{ form_row(form.type) }}
{{ form_row(form.teaser) }}
{{ form_row(form.description) }}
{{ form_row(form.url) }}
{{ form_row(form.addImage) }}
<div id="event-image-upload-wrap" style="display:none;" hidden aria-hidden="true">
{{ form_row(form.eventUpload) }}
{{ form_row(form.photographer) }}
<p class="help-text">Die Angabe des Urhebers ist notwendig. Ihnen muss eine Genehmigung zur Verwendung des Bildes vorliegen.</p>
</div>
{{ form_row(form.termsAccepted) }}
{{ form_row(form.isSoldOut) }}
{{ form_row(form.isCanceled) }}
{{ form_row(form.published) }}
<div class="actions" aria-label="Formularaktionen">
<button type="submit" id="save-btn" disabled>Speichern</button>
<button type="submit" id="save-back-btn" name="save_back" value="1" disabled>Speichern und Zurück</button>
<a href="{{ backUrl }}" aria-label="Zurück zur vorherigen Seite">Zurück</a>
</div>
{{ form_end(form) }}
<script>
(function () {
const locationSelect = document.querySelector('select.js-location-choice');
const organizationSelect = document.querySelector('select.js-organization-choice');
const typeSelect = document.querySelector('select.js-event-type-choice');
if (organizationSelect && typeof window.Choices === 'function') {
new window.Choices(organizationSelect, {
searchEnabled: true,
shouldSort: false,
removeItemButton: true,
itemSelectText: '',
placeholder: true,
placeholderValue: organizationSelect.dataset.placeholder || 'Veranstalter suchen …',
noResultsText: 'Keine Treffer',
noChoicesText: 'Keine Optionen verfügbar'
});
}
if (locationSelect && typeof window.Choices === 'function') {
new window.Choices(locationSelect, {
searchEnabled: true,
shouldSort: false,
itemSelectText: '',
placeholder: true,
placeholderValue: locationSelect.dataset.placeholder || 'Suchen …',
noResultsText: 'Keine Treffer',
noChoicesText: 'Keine Optionen verfügbar'
});
}
if (typeSelect && typeof window.Choices === 'function') {
new window.Choices(typeSelect, {
searchEnabled: false,
shouldSort: false,
removeItemButton: true,
itemSelectText: '',
placeholder: true,
placeholderValue: typeSelect.dataset.placeholder || 'Typen suchen …',
noResultsText: 'Keine Treffer',
noChoicesText: 'Keine Optionen verfügbar'
});
}
if (typeof window.flatpickr === 'function') {
const dateInputs = document.querySelectorAll('input.js-flatpickr-date');
dateInputs.forEach(function (input) {
window.flatpickr(input, {
locale: 'de',
dateFormat: 'Y-m-d',
allowInput: true
});
});
const timeInputs = document.querySelectorAll('input.js-flatpickr-time');
timeInputs.forEach(function (input) {
window.flatpickr(input, {
locale: 'de',
enableTime: true,
noCalendar: true,
dateFormat: 'H:i',
time_24hr: true,
allowInput: true
});
});
}
const addImageToggle = document.querySelector('input.js-add-image-toggle');
const addTimeToggle = document.querySelector('input.js-add-time-toggle');
const timeWrap = document.getElementById('event-time-wrap');
const startTimeInput = document.getElementById('{{ form.startTime.vars.id }}');
const imageWrap = document.getElementById('event-image-upload-wrap');
const imageInput = document.querySelector('input.js-event-image-upload');
const photographerInput = document.querySelector('input.js-photographer');
const removeImageInput = document.getElementById('remove_image');
const currentImagePath = {{ (currentImagePath is defined and currentImagePath) ? ('/' ~ currentImagePath)|json_encode|raw : 'null' }};
const hadInitialImage = !!currentImagePath;
let pondDirty = false;
const form = document.querySelector('form');
const saveButton = document.getElementById('save-btn');
const saveBackButton = document.getElementById('save-back-btn');
if (!form || !saveButton || !saveBackButton) {
return;
}
const initial = new FormData(form);
const hasChanges = () => {
const current = new FormData(form);
for (const [key, value] of current.entries()) {
if (initial.getAll(key).join(',') !== current.getAll(key).join(',')) {
return true;
}
}
return false;
};
const updateButtons = () => {
const changed = hasChanges() || pondDirty;
saveButton.disabled = !changed;
saveBackButton.disabled = !changed;
};
const setImageVisibility = () => {
if (!addImageToggle || !imageWrap) {
return;
}
addImageToggle.setAttribute('aria-controls', 'event-image-upload-wrap');
addImageToggle.setAttribute('aria-expanded', addImageToggle.checked ? 'true' : 'false');
imageWrap.style.display = addImageToggle.checked ? '' : 'none';
imageWrap.hidden = !addImageToggle.checked;
imageWrap.setAttribute('aria-hidden', addImageToggle.checked ? 'false' : 'true');
if (photographerInput) {
photographerInput.required = !!addImageToggle.checked;
}
if (!addImageToggle.checked && removeImageInput) {
removeImageInput.value = hadInitialImage ? '1' : '0';
}
updateButtons();
};
const setTimeVisibility = () => {
if (!addTimeToggle || !timeWrap) {
return;
}
addTimeToggle.setAttribute('aria-controls', 'event-time-wrap');
addTimeToggle.setAttribute('aria-expanded', addTimeToggle.checked ? 'true' : 'false');
timeWrap.style.display = addTimeToggle.checked ? '' : 'none';
timeWrap.hidden = !addTimeToggle.checked;
timeWrap.setAttribute('aria-hidden', addTimeToggle.checked ? 'false' : 'true');
if (startTimeInput) {
startTimeInput.required = !!addTimeToggle.checked;
}
updateButtons();
};
if (addTimeToggle) {
addTimeToggle.addEventListener('change', setTimeVisibility);
setTimeVisibility();
}
if (addImageToggle) {
addImageToggle.addEventListener('change', setImageVisibility);
setImageVisibility();
}
if (imageInput && typeof window.FilePond !== 'undefined') {
if (typeof window.FilePondPluginImagePreview !== 'undefined') {
window.FilePond.registerPlugin(window.FilePondPluginImagePreview);
}
const filePondOptions = {
instantUpload: false,
storeAsFile: true,
allowMultiple: false,
allowReplace: true,
credits: false,
acceptedFileTypes: ['image/*'],
labelIdle: 'Bild hierher ziehen oder <span class="filepond--label-action">durchsuchen</span>'
};
if (currentImagePath) {
filePondOptions.files = [
{
source: currentImagePath,
options: {
type: 'local'
}
}
];
filePondOptions.server = {
load: (source, load, error, progress, abort) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', source);
xhr.responseType = 'blob';
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
load(xhr.response);
} else {
error('Laden fehlgeschlagen');
}
};
xhr.onerror = function () {
error('Laden fehlgeschlagen');
};
xhr.send();
return {
abort: () => {
xhr.abort();
abort();
}
};
}
};
}
const pond = window.FilePond.create(imageInput, filePondOptions);
const syncPondState = () => {
const files = pond.getFiles();
const hasLocalFile = files.some((file) => window.FilePond.FileOrigin && file.origin === window.FilePond.FileOrigin.LOCAL);
const hasNewFile = files.some((file) => window.FilePond.FileOrigin && file.origin !== window.FilePond.FileOrigin.LOCAL);
const imageEnabled = addImageToggle ? addImageToggle.checked : true;
pondDirty = imageEnabled && (hasNewFile || (hadInitialImage && !hasLocalFile));
if (removeImageInput) {
if (!imageEnabled) {
removeImageInput.value = hadInitialImage ? '1' : '0';
} else {
removeImageInput.value = hadInitialImage && !hasLocalFile && !hasNewFile ? '1' : '0';
}
}
updateButtons();
};
syncPondState();
pond.on('removefile', function () {
syncPondState();
});
pond.on('addfile', function () {
syncPondState();
});
pond.on('updatefiles', function () {
syncPondState();
});
}
form.addEventListener('input', function () {
updateButtons();
});
form.addEventListener('change', function () {
updateButtons();
});
})();
</script>
{% else %}
<p>Kein Formular verfügbar.</p>
{% endif %}
{% endblock %}
@@ -0,0 +1,101 @@
{% extends "@Contao/frontend_module/_base.html.twig" %}
{% block content %}
<h2>Kommende Veranstaltungen</h2>
{% if upcomingEvents is empty %}
<p>Keine kommenden Veranstaltungen gefunden.</p>
{% else %}
<ul class="member-events member-events-upcoming" aria-label="Liste kommender Veranstaltungen">
{% for item in upcomingEvents %}
<li>
<span>{{ item.title }}</span>
<span>
{% if item.startDate %}
<time datetime="{{ item.startDate|date('Y-m-d') }}">{{ item.startDate|date('d.m.Y') }}</time>
{% endif %}
</span>
{% if isEditor %}
<form method="post" style="display:inline;" aria-label="Sichtbarkeit für {{ item.title }} ändern">
<input type="hidden" name="REQUEST_TOKEN" value="{{ requestToken }}">
<input type="hidden" name="action" value="toggle_published">
<input type="hidden" name="event_id" value="{{ item.id }}">
<button type="submit" aria-label="{{ item.published ? 'Auf inaktiv setzen' : 'Auf aktiv setzen' }} für {{ item.title }}">{{ item.published ? 'aktiv' : 'inaktiv' }}</button>
</form>
{% if item.editUrl %}
<a href="{{ item.editUrl }}" aria-label="{{ item.title }} bearbeiten">Bearbeiten</a>
{% endif %}
<form method="post" style="display:inline;" aria-label="{{ item.title }} duplizieren">
<input type="hidden" name="REQUEST_TOKEN" value="{{ requestToken }}">
<input type="hidden" name="action" value="duplicate">
<input type="hidden" name="event_id" value="{{ item.id }}">
<button type="submit" aria-label="{{ item.title }} duplizieren">Duplizieren</button>
</form>
<form method="post" style="display:inline;" onsubmit="return confirm('wirklich löschen?');" aria-label="{{ item.title }} löschen">
<input type="hidden" name="REQUEST_TOKEN" value="{{ requestToken }}">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="event_id" value="{{ item.id }}">
<button type="submit" aria-label="{{ item.title }} löschen">Löschen</button>
</form>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% if canCreateEvent is defined and canCreateEvent %}
<form method="post" aria-label="Neue Veranstaltung erstellen">
<input type="hidden" name="REQUEST_TOKEN" value="{{ requestToken }}">
<input type="hidden" name="action" value="create">
<button type="submit" aria-label="Neue Veranstaltung erstellen">Neue Veranstaltung erstellen</button>
</form>
{% endif %}
<h2>Vergangene Veranstaltungen</h2>
{% if pastEvents is empty %}
<p>Keine vergangenen Veranstaltungen gefunden.</p>
{% else %}
<ul class="member-events member-events-past" aria-label="Liste vergangener Veranstaltungen">
{% for item in pastEvents %}
<li>
<span>{{ item.title }}</span>
<span>
{% if item.startDate %}
<time datetime="{{ item.startDate|date('Y-m-d') }}">{{ item.startDate|date('d.m.Y') }}</time>
{% endif %}
</span>
{% if isEditor %}
<form method="post" style="display:inline;" aria-label="Sichtbarkeit für {{ item.title }} ändern">
<input type="hidden" name="REQUEST_TOKEN" value="{{ requestToken }}">
<input type="hidden" name="action" value="toggle_published">
<input type="hidden" name="event_id" value="{{ item.id }}">
<button type="submit" aria-label="{{ item.published ? 'Auf inaktiv setzen' : 'Auf aktiv setzen' }} für {{ item.title }}">{{ item.published ? 'aktiv' : 'inaktiv' }}</button>
</form>
{% if item.editUrl %}
<a href="{{ item.editUrl }}" aria-label="{{ item.title }} bearbeiten">Bearbeiten</a>
{% endif %}
<form method="post" style="display:inline;" aria-label="{{ item.title }} duplizieren">
<input type="hidden" name="REQUEST_TOKEN" value="{{ requestToken }}">
<input type="hidden" name="action" value="duplicate">
<input type="hidden" name="event_id" value="{{ item.id }}">
<button type="submit" aria-label="{{ item.title }} duplizieren">Duplizieren</button>
</form>
<form method="post" style="display:inline;" onsubmit="return confirm('wirklich löschen?');" aria-label="{{ item.title }} löschen">
<input type="hidden" name="REQUEST_TOKEN" value="{{ requestToken }}">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="event_id" value="{{ item.id }}">
<button type="submit" aria-label="{{ item.title }} löschen">Löschen</button>
</form>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
@@ -0,0 +1,19 @@
{% extends "@Contao/frontend_module/_base.html.twig" %}
{% block content %}
<h2>Organisationen</h2>
{% if organizations is empty %}
<p>Keine Organisationen gefunden.</p>
{% else %}
<ul class="member-organizations" aria-label="Liste der Organisationen">
{% for item in organizations %}
<li>
<span>{{ item.title }}</span>
{% if item.editUrl %}
<a href="{{ item.editUrl }}" aria-label="{{ item.title }} bearbeiten">Bearbeiten</a>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
@@ -0,0 +1,169 @@
{% extends "@Contao/frontend_module/_base.html.twig" %}
{% block content %}
{% if error is defined and error %}
<p role="alert">{{ error }}</p>
<p><a href="{{ backUrl }}">Zurück</a></p>
{% elseif form is defined and form %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css">
<link rel="stylesheet" href="https://unpkg.com/filepond/dist/filepond.min.css">
<link rel="stylesheet" href="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css">
<script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
<script src="https://unpkg.com/filepond/dist/filepond.min.js"></script>
<script src="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.js"></script>
{{ form_start(form, { attr: { 'aria-live': 'polite' } }) }}
<input type="hidden" name="REQUEST_TOKEN" value="{{ requestToken }}">
<input type="hidden" id="remove_logo" name="remove_logo" value="0">
{{ form_widget(form) }}
<div class="actions" aria-label="Formularaktionen">
<button type="submit" id="save-btn" disabled>Speichern</button>
<button type="submit" id="save-back-btn" name="save_back" value="1" disabled>Speichern und Zurück</button>
<a href="{{ backUrl }}" aria-label="Zurück zur vorherigen Seite">Zurück</a>
</div>
{{ form_end(form) }}
<script>
(function () {
const typeSelect = document.querySelector('select.js-organization-type-choice');
if (typeSelect && typeof window.Choices === 'function') {
new window.Choices(typeSelect, {
searchEnabled: false,
shouldSort: false,
removeItemButton: true,
itemSelectText: '',
placeholder: true,
placeholderValue: typeSelect.dataset.placeholder || 'Typ auswählen …',
noResultsText: 'Keine Treffer',
noChoicesText: 'Keine Optionen verfügbar'
});
}
const currentLogoPath = {{ (currentLogoPath is defined and currentLogoPath) ? ('/' ~ currentLogoPath)|json_encode|raw : 'null' }};
const logoInput = document.querySelector('input.js-logo-upload');
const removeLogoInput = document.getElementById('remove_logo');
const hadInitialLogo = !!currentLogoPath;
let pondDirty = false;
const form = document.querySelector('form');
const saveButton = document.getElementById('save-btn');
const saveBackButton = document.getElementById('save-back-btn');
if (!form || !saveButton || !saveBackButton) {
return;
}
const initial = new FormData(form);
const hasChanges = () => {
const current = new FormData(form);
for (const [key, value] of current.entries()) {
if (initial.getAll(key).join(',') !== current.getAll(key).join(',')) {
return true;
}
}
return false;
};
const updateButtons = () => {
const changed = hasChanges() || pondDirty;
saveButton.disabled = !changed;
saveBackButton.disabled = !changed;
};
if (logoInput && typeof window.FilePond !== 'undefined') {
if (typeof window.FilePondPluginImagePreview !== 'undefined') {
window.FilePond.registerPlugin(window.FilePondPluginImagePreview);
}
const filePondOptions = {
instantUpload: false,
storeAsFile: true,
allowMultiple: false,
allowReplace: true,
credits: false,
acceptedFileTypes: ['image/*'],
labelIdle: 'Logo hierher ziehen oder <span class="filepond--label-action">durchsuchen</span>'
};
if (currentLogoPath) {
filePondOptions.files = [
{
source: currentLogoPath,
options: {
type: 'local'
}
}
];
filePondOptions.server = {
load: (source, load, error, progress, abort) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', source);
xhr.responseType = 'blob';
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
load(xhr.response);
} else {
error('Laden fehlgeschlagen');
}
};
xhr.onerror = function () {
error('Laden fehlgeschlagen');
};
xhr.send();
return {
abort: () => {
xhr.abort();
abort();
}
};
}
};
}
const pond = window.FilePond.create(logoInput, filePondOptions);
const syncPondState = () => {
const files = pond.getFiles();
const hasLocalFile = files.some((file) => window.FilePond.FileOrigin && file.origin === window.FilePond.FileOrigin.LOCAL);
const hasNewFile = files.some((file) => window.FilePond.FileOrigin && file.origin !== window.FilePond.FileOrigin.LOCAL);
pondDirty = hasNewFile || (hadInitialLogo && !hasLocalFile);
if (removeLogoInput) {
removeLogoInput.value = hadInitialLogo && !hasLocalFile && !hasNewFile ? '1' : '0';
}
updateButtons();
};
syncPondState();
pond.on('removefile', function (error, file) {
if (error) {
return;
}
syncPondState();
});
pond.on('addfile', function () {
syncPondState();
});
pond.on('updatefiles', function () {
syncPondState();
});
}
form.addEventListener('input', function () {
updateButtons();
});
form.addEventListener('change', function () {
updateButtons();
});
})();
</script>
{% else %}
<p>Kein Formular verfügbar.</p>
{% endif %}
{% endblock %}