Event-Editor erweitern

Editor-Template verändern

Einem Contao-Freak erzähle ich vermutlich nichts neues, aber Sie können natürlich das Editor-Template beliebig modifizieren und z.B. die einfach foreach-Schleife, die einfach alle Formularfelder hintereinander auflistet, durch etwas anderes ersetzen.

Auf einer Seite habe ich z.B. für jedes Feld eine solche Abfrage im Template

<?php if ($this->fields['endDate']): ?>
<?php $objWidget = $this->fields['endDate']; ?>				
    <tr class="<?php echo $class; ?>">
        <td class="label"><?php echo $objWidget->generateLabel(); ?></td>
        <td class="value"><?php echo $objWidget->generateWithError(); ?></td>
    </tr>			
<?php endif; ?>

Damit kann man die einzelnen Felder beliebig anordnen, und bei einigen auch Kommentare dazwischen einfügen. Die Felder heißen so, wie auch die Spalten in der Datenbank, als startDate, endDate, startTime, endTime, title, teaser, details, cssClass, published und pid. Letzteres wird nur erzeugt, wenn der User mehr als einen Kalender bearbeiten darf, ansonsten wird als PID automatisch der Kalender gewählt, für den der User die nötigen Rechte hat. Wenn ein Event gelöscht werden soll, dann wird nur das Feld captcha erzeugt.

Ein alternatives Template gibt es hier zum Download.

Felder hinzufügen/verändern

Für den Kalender gibt es z.B. die Erweiterung calender_events_plus, womit man für Events direkt einen Ort, Teilnehmer und einen Kontakt definieren kann. Wer diese Erweiterung nutzt, möchte das evtl. auch über das Frontend eingeben lassen. Dazu gibt es die Hooks buildCalendarEditForm und buildCalendarCloneForm, der vor dem Erzeugen der Formular-Widgets für den normalen Editor bzw. den Duplizieren-Editor (ab Version 3) aufgerufen wird.

Dazu muss der Hook registriert werden, z.B. in der Datei calendar_editor_plus/config/config.php

$GLOBALS['TL_HOOKS']['buildCalendarEditForm']['EditPlus'] = array('EventEditHookPlus', 'SetEditField'); 
$GLOBALS['TL_HOOKS']['buildCalendarCloneForm']['EditPlus'] = array('EventEditHookPlus', 'SetCloneField');

Dieser Hook erwartet 4 Parameter:

  • $NewEventData: Das Daten-Array mit den aktuellen Formulardaten. Diese Daten werden später in die Datenbank geschrieben 
  • $fields: Das aktuelle Formularfelder-Array. Hier wird definiert, welche Art Eingabe (text, textfield, select, ...) in dem Feld gemacht wird, welcher Wert darin steht (sollte immer der passende Wert aus $NewEventData sein), ob es ein Pflichtfeld ist, usw.
  • $currentEventObject: Das aktuell bearbeitete Event aus der Datenbank. Hier sind auch die Daten drin, die der Event-Editor noch nicht verarbeiten kann.
  • $editID: Die ID des aktuellen Events (beim Hinzufügen eines neues Events ist $editID leer, und $currentEventObject existiert nicht)

Als Rückgabe wird ein Array mit den modifizierten Eventdaten und den modifizierten Feldern erwartet.

In der Datei calendar_editor_plus/EventEditHookPlus.php implementieren wir diesen Hook

class EventEditHookPlus extends Frontend
{
  public function SetEditField($NewEventData, $fields, $currentEventObject, $editID) {
  $result = array();
  $result['NewEventData'] = $NewEventData; 
  $result['fields']       = $fields;
  // Get Calendar_Events_Plus - Data from current event
  if ($editID) {
    $result['NewEventData']['cep_location']     = $currentEventObject->cep_location;
    $result['NewEventData']['cep_participants'] = $currentEventObject->cep_participants;
    $result['NewEventData']['cep_contact']      = $currentEventObject->cep_contact;			
  }
  // overwrite it with current POST data
  if ($this->Input->post('FORM_SUBMIT') == 'caledit_submit') {
    $result['NewEventData']['cep_location']     = $this->Input->post('cep_location');
    $result['NewEventData']['cep_participants'] = $this->Input->post('cep_participants');
    $result['NewEventData']['cep_contact']      = $this->Input->post('cep_contact');
  }
  // create new fields
  $result['fields']['cep_location'] = array(
          'name' => 'cep_location',
          'label' => $GLOBALS['TL_LANG']['MSC']['cep_location'],
          'inputType' => 'text',
          'value' => $result['NewEventData']['cep_location'],
          'eval' => array('maxlength' => 255)
  );
  $result['fields']['cep_participants'] = array(
          'name' => 'cep_participants',
          'label' => $GLOBALS['TL_LANG']['MSC']['cep_participants'],
          'inputType' => 'text',
          'value' => $result['NewEventData']['cep_participants'],
          'eval' => array('maxlength' => 255)
  );
  $result['fields']['cep_contact'] = array(
          'name' => 'cep_contact',
          'label' => $GLOBALS['TL_LANG']['MSC']['cep_contact'],
          'inputType' => 'text',
          'value' => $result['NewEventData']['cep_contact'],
          'eval' => array('maxlength' => 255)
  );				
  return $result;
  }
}

Wenn Sie die Erweiterung calendarfield installiert haben, können Sie anstelle des einfachen Textfeldes zur Eingabe des Datums auch diesen Feldtyp verwenden. Dazu einfach nur das Field-Array entsprechend abändern:

Hinweis: Damit das funktioniert, müssen in dem Seitentemplate auch MooTools geladen werden. Wenn dadurch die Auswahlfelder blöd aussehen, ggf. moo_chosen abwählen.

$result['fields']['startDate']['inputType'] = 'calendar';
$result['fields']['endDate']['inputType'] = 'calendar';

Daten vor dem Eintrag in die DB verändern

Wenn Sie die Eingaben aus dem Frontend vor dem Eintrag in die Datenbank modifizieren wollen, können Sie das über einen zweiten Hook prepareCalendarEditData tun. Als Parameter wird das aktuelle Datenarray übergeben, als Rückgabe wird ein modifiziertes Array erwartet.

$GLOBALS['TL_HOOKS']['prepareCalendarEditData']['EditPlus'] = array('EventEditHookPlus', 'prepareData');

Dieser wird unmittelbar vor der Insert/Update-SQL-Anweisung aufgerufen. Wenn Sie die Calender-Event-Plus-Daten zwar eingeben lassen wollen, aber nicht die Erweiterung calender_events_plus installiert haben, würde es bisher zu einer fetten Fehlermeldung kommen, wenn der User das Formular abschickt. Das lässt beheben, indem Sie die Zusatzdaten mit bei den Details reinschreiben, und die Spalten, die in der Datenbank nicht existieren, aus dem Datenarray löschen:

public function prepareData($eventData) {
  $result = $eventData;
  $addDet = "<p>Location: ".$eventData['cep_location']."</p>";
  $addDet.= "<p>Participiants: ".$eventData['cep_participants']."</p>";
  $addDet.= "<p>Contact: ".$eventData['cep_contact']."</p>";
  // Add location, participiants and contact to details
  $result['details'] = $addDet.$result['details'];
  // delete these fieldes from the data-array, as these columns does not exist in tl_calendar_events
  // (they actually do, if you have installed the extension calendar_events_plus)
  unset($result['cep_location']);
  unset($result['cep_participants']);
  unset($result['cep_contact']);
  return $result;
}

Das Beispiel hier zum Download. In das Contao Extension Repository möchte ich das nicht eintragen - das sollte jeder selbst so anpassen, wie er es benötigt.