[ '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&field=published', 'icon' => 'visible.svg', ], 'show' => [ 'href' => 'act=show', 'icon' => 'show.svg', ], ], ], 'palettes' => [ '__selector__' => [], 'default' => '{title_legend},title,alias,tags,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' => 11, 'tl_class' => 'w50'], 'sql' => ['type' => 'decimal', 'precision' => 11, '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' => ''], ], 'tags' => [ 'label' => &$GLOBALS['TL_LANG']['tl_organization']['tags'], 'exclude' => 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' => 'organization_type'], 'sql' => ['type' => 'blob', 'notnull' => false], 'relation' => ['type' => 'hasMany', 'load' => 'eager'], ], '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; };