Bei der Integration der Typo3-Blog-Extension T3BLOG haben wir einige Überraschungen erlebt und Erfahrungen gemacht, von denen ich in lockerer Folge in den „T3BLOG Perlen" berichte. Diesmal widme ich mich der Beitrags-Vorschau.
Dieser Beitrag bezieht sich auf Typo3 4.5.8 und T3BLOG 1.1.2 .
Der Wunsch, einen frisch geschriebenen Beitrag im Frontend Korrektur lesen zu können, bevor er veröffentlicht wird, ist nicht besonders ausgefallen, und T3BLOG sieht denn auch mit dem üblichen Lupensymbol eine Ansehen-Funktion in der Beitragsliste vor. Wer allerdings diesen Knopf schon einmal gedrückt hat, weiß dass man unveröffentlichte Beiträge auf diese Weise nicht zu Gesicht bekommt, ganz im Gegensatz zu den üblichen Gepflogenheiten von Typo3. Ist das so gedacht? Nein, es ist nur falsch implementiert. Und weil man dabei etwas über die Erweiterungsprogrammierung unter Typo3 lernen kann, möchte ich neben der Korrektur auch eine Erläuterung anbieten.
Hier ist der betreffende Originalcode von T3BLOG (pi1/widgets/blogList/class.singleFunctions.php:83 ff.), ein Ausschnitt aus der main() Funktion der Einzelansicht für Beiträge:
if ($this->uid) {
$this->riseViewNumber();
$row = $this->fetchPostDataFromDatabase();
if (is_array($row)) {
$showHiddenRecords = $GLOBALS['TSFE']->showHiddenRecords;
if ($this->isBEUserLoggedIn()) {
// Allow preview for hidden posts
$GLOBALS['TSFE']->showHiddenRecords = true;
}
$this->updatePageTitle($row['title']);
Dort wird durchaus der Versuch unternommen, dem angemeldeten Backend-Benutzer (Autor) den noch verborgenen Beitrag zugänglich zu machen. Zur Erinnerung: T3BLOG speichert die Beiträge als Elemente (records) der Seite, in die es installiert wurde. Deswegen wird, falls der Betrachter ein angemeldeter Backend-Benutzer ist, die Einstellung $GLOBALS['TSFE']->showHiddenRecords geändert, die regelt ob verborgene Elemente trotzdem aus der Datenbank gezogen werden sollen. Das ist ein richtiger Ansatz, den man sich merken kann, zumal Beschreibungen von TSFE dünn gesät sind. Allerdings treffen sich hier gleich zwei Fehler, die den Versuch vereiteln:
Wie man an den markierten Codezeilen sieht, werden die Datensätze erst aus der Datenbank gelesen, und danach wird die Einstellung geändert. Das ist dann zu spät, die „verborgenen" Bestandteile des unveröffentlichten Beitrags sind gar nicht in $row gelandet und können auch nachträglich nicht sichtbar gemacht werden. Diese Umschaltung sollte man also vorziehen. Das reicht aber noch nicht aus.
Zwei, sollte man meinen. Das ist der zweite Fehler, er ist viel subtiler und lässt daran zweifeln, dass man große Projekte wirklich in PHP implementieren will. Aber der Reihe nach: showHiddenRecords klingt nach einer binären Einstellung - verborgene Einträge anzeigen: Ja oder Nein. Typo3 erwartet hier aber einen integer, der mit 0 oder 1 belegt werden soll. Nachzulesen ist das „schon" im Kopf von t3lib_pageSelect::enableFields(), wo die Einstellung letzten Endes ausgewertet wird.
Hier ein Auszug aus enableFields() (t3lib/class.t3lib_page.php:1076 ff., Umbrüche eingefügt und Kommentare gekürzt):
...
* @param integer If $show_hidden is set (0/1), any hidden-fields in
* records are ignored. NOTICE: If you call this function, consider what to
* do with the show_hidden parameter. Maybe it should be set? See
* tslib_cObj->enableFields where it's implemented correctly.
...
function enableFields($table, $show_hidden = -1, $ignore_array = array(),
$noVersionPreview = FALSE) {
global $TYPO3_CONF_VARS;
if ($show_hidden == -1 && is_object($GLOBALS['TSFE'])) { // If show_hidden...
$show_hidden = $table == 'pages' ? $GLOBALS['TSFE']->showHiddenPage
: $GLOBALS['TSFE']->showHiddenRecords;
}
if ($show_hidden == -1) {
$show_hidden = 0;
} // If show_hidden was not changed during the previous evaluation, do it
Dort wird der Wert -1 als Standardbelegung genommen, sollte $show_hidden nicht übergeben worden sein (wurde es in unserem Fall auch nicht). Hier einen integer-Wert zu verwenden, anstatt auf null zu setzen, was PHP für unbelegte Argumente automatisch verwendet, ist sicherlich unnötiger Aufwand. Immerhin beantwortet es die Frage: In einen Wahrheitswert passen mindestens vier Zahlen, -1, 0, 1 und null.
Erst an der markierten Stelle beißt diese programmiersprachliche Besonderheit so richtig. $show_hidden ist inzwischen aus der globalen Variable, die die T3BLOG-Autoren oben umgeschaltet hatten, übernommen worden, also nun ein boolean mit Wert true. Der wird jetzt aber gegen -1 verglichen, und true == -1, ebenso wie true == 1 oder true == 93962592872986. Typo3 geht also davon aus, dass keine Anweisungen hinsichtlich der Anzeige verborgener Elemente gegeben wurden, und zeigt sie standardmäßig eben nicht an.
Hier noch einmal die doppelt korrigierte Fassung der Codestelle aus pi1/widgets/blogList/class.singleFunctions.php:83ff.:
if ($this->uid) {
$this->riseViewNumber();
$showHiddenRecords = $GLOBALS['TSFE']->showHiddenRecords;
if ($this->isBEUserLoggedIn()) {
// Allow preview for hidden posts
$GLOBALS['TSFE']->showHiddenRecords = 1;
}
$row = $this->fetchPostDataFromDatabase();
if (is_array($row)) {
$this->updatePageTitle($row['title']);
Wie man sieht, ist der Block, in dem der ursprüngliche Wert von showHiddenRecords gemerkt und die Variable umgeschaltet wird, vor die Datenbankabfrage gerutscht, und zum Einschalten der Vorschau wird 1 statt true verwendet. Eigentlich ganz einfach, kann aber einige Zeit für Recherche in Anspruch nehmen...
Mein Kommentar zum Beitrag