Folgende Schritte sind notwendig, um eine eigene Extension Workspace-tauglich zu machen:
- t3ver_* Datenbankeinträge anlegen
- ext_tables.php ergänzen
- tca.php ergänzen
- Frontend-Ausgabe anpassen
Wenn man den Kickstarter benutzt, kann man sich Schritt 1 und 3 abnehmen lassen: Unter „New Database Tables“ bei jeder Tabelle „Enable versioning“ aktivieren.
1. t3ver_* Datenbankeinträge anlegen
In der Datei ext_tables.sql alle Tabellen die versioniert werden sollen um folgende Einträge ergänzen:
t3ver_oid int(11) DEFAULT '0' NOT NULL, t3ver_id int(11) DEFAULT '0' NOT NULL, t3ver_wsid int(11) DEFAULT '0' NOT NULL, t3ver_label varchar(30) DEFAULT '' NOT NULL, t3ver_state tinyint(4) DEFAULT '0' NOT NULL, t3ver_stage tinyint(4) DEFAULT '0' NOT NULL, t3ver_count int(11) DEFAULT '0' NOT NULL, t3ver_tstamp int(11) DEFAULT '0' NOT NULL, t3_origuid int(11) DEFAULT '0' NOT NULL,
Und am Ende nach KEY parent (pid):
KEY parent (pid), KEY t3ver_oid (t3ver_oid,t3ver_wsid)
Das gilt für alle Datenbank-Tabellen die man anlegt. Tabellen die ergänzt werden sind üblicherweise pages oder tt_content, die haben bereits die Versionierungsfelder, da muss man nichts machen.
2. ext_tables.php ergänzen
In der Datei „ext_tables.php“ gibt es einen $TCA Array, dort den „ctrl“ Bereich um die roten Einträge erweitern.
$TCA['user_veranstaltungen_event'] = array (
'ctrl' => array (
'title' => 'LLL:EXT:user_veranstaltungen/locallang_db.xml:user_veranstaltungen_event',
'label' => 'title',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
'default_sortby' => 'ORDER BY crdate',
'versioningWS' => TRUE,
'versioning_followPages' => TRUE,
'origUid' => 't3_origuid',
(...)
),
);
3. tca.php ergänzen
In der tca.php den Eintrag „t3ver_label“ in allen Tabellen hinzufügen:
$TCA['user_veranstaltungen_event'] = array (
'ctrl' => $TCA['user_veranstaltungen_event']['ctrl'],
'interface' => array (
'showRecordFieldList' => 'hidden,starttime,endtime,eventdate,title,description,location,images,images_description'
),
'feInterface' => $TCA['user_veranstaltungen_event']['feInterface'],
'columns' => array (
't3ver_label' => array (
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.versionLabel',
'config' => array (
'type' => 'input',
'size' => '30',
'max' => '30',
)
),
'hidden' => array (
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
'config' => array (
'type' => 'check',
'default' => '0'
)
),
(...)
4. Frontend-Ausgabe anpassen
Alle Ausgaben der Extension müssen jetzt an die Versionierung angepasst werden. Dafür gibt es einige Typo3-Hilfsfunktionen.
Die wichtigste Funktion für die Frontend-Ausgabe ist $GLOBALS['TSFE']->sys_page->versionOL($table,$row);
Die wird einfach nach der Datenbank-Abfrage aufgerufen, und ersetzt mit automatisch die $row durch die gerade gewünschte Version (Live, Draft, Workspace).
Ohne Versionierung:
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*',$table,'uid='.$eventid.' and hidden=0 and deleted=0'); if($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { (...do something with $row...) }
Mit Versionierung:
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*',$table,'uid='.$eventid.' and hidden=0 and deleted=0'); if($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { $GLOBALS['TSFE']->sys_page->versionOL($table,$row); if (is_array($row)) { (...do something with $row...) } }
Wer eine einfache Extension mit nur einer Tabelle und einer Frontendausgabe hat sollte hiermit schon klarkommen. Evtl. muss man mit der SQL-Abfrage ein bißchen rumspielen:
- hidden=0 rausnehmen, das wird dann von versionOL überprüft
- zusätzlich where pid > 0
- SQL Abfrage anpassen je nachdem ob mit Live oder Preview:
if ($GLOBALS['TSFE']->sys_page->versioningPreview == TRUE){...}
Datenbank Einträge
Mit ein bißchen rumprobieren konnte ich in der Datenbank die meisten Felder nachvollziehen:
t3ver_state:
- -1: offline
- 0: live
- >0 entweder die Workspaceid oder die Bearbeitungsstati haben Zahlen zugeordnet, da bin ich noch nicht sicher
t3ver_id: Versionsnummer die mit jeder Version hochgezählt wird
t3ver_oid: Foreign Key auf den Live Datensatz, 0 wenn Live
t3ver_label: Name des Workspaces, INITIAL PLACEHOLDER wenn noch kein Live existiert
Ablauf der Änderungen in der Datenbank
Ein Datensatz wird immer als Duplikat zur Liveversion angelegt und mit t3ver_oid auf die uid vom Original-Datensatz verlinkt. Das heißt im Bearbeitungs-Modus gibt es 2 Datensätze: den LIVE und den Entwurf.
Wenn der Datensatz im Entwurf neu angelegt wurde, wird im Live ein Dummy-Datensatz angelegt. Er hat t3ver_label=INITIAL PLACEHOLDER.
Wird die Änderung veröffentlich, werden alle Änderungen in den Live-Datensatz übernommen und der zweite Datensatz gelöscht. t3ver_id wird dabei um 1 incrementiert.
Beispiel Ablauf:
1. Element neu angelegt
Placeholder: - uid=49 - t3ver_state=1 (workspaceid) - t3ver_label=INITIAL PLACEHOLDER - t3ver_id=0 (versionsnummer) Entwurf: - uid=50 - PID=-1 - t3ver_state=-1 (offline) - t3ver_label=First draft version - t3ver_oid = 49 (placeholder uid) - t3ver_id=1 (versionsnummer)
2. Veröffentlicht
Entwurf (uid=50) gelöscht, Placeholder (uid=49) mit Entwurfsdaten ersetzt - t3ver_state=0 (live) - t3ver_id=1
3. Datensatz wird wieder bearbeitet
Live: - uid=49 Rest unverändert Entwurf: - uid=51 - PID=-1 - t3ver_state=-1 (offline) - t3ver_label=Auto-created for WS #1 - t3ver_oid = 49 (placeholder uid) - t3ver_id=2
Links und weiterführende Infos
Weitere Versionierungsfunktionen (z.B. für Backend-Module) findet in der Typo3 Extension API Dokumentation. Auch ein paar grundlegende Probleme wie z.B. Abfragen mit mehreren Tabellen sind da gut erklärt:
Was auch hilft ist bereits versionierbare Extensions wie tt_news (evtl. auch calendar) anzusehen. Einfach nach „t3ver“ suchen, dann findet man den Code der für Versionierung zuständig ist.
Code der Funktion versionOL: https://typo3.org/api/typo3cms/_template_service_8php_source.html
Dokumentation über Workspaces allgemein: https://docs.typo3.org/typo3cms/CoreApiReference/latest/ApiOverview/Workspaces/
Pingback: Links der Woche… - TYPO3 Blogger | TYPO3 Blogger