T3BLOG Perlen: Die Vorschaufunktion gangbar machen

13.01.2012
17:45

T3BLOG Perlen: Die Vorschaufunktion gangbar machen

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 .

Einführung

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.

Zu spät

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.

Wie viele Zahlen passen in einen Wahrheitswert?

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.

Was kann man daraus lernen?

 

  • Erstens ist die Autokonvertierung von Datentypen in PHP ein Ärgernis, das möglichst vermieden werden sollte, hier zum Beispiel, indem ein expliziter cast auf integer eingefügt wird (da wäre 1 heraus gekommen, und 1 != -1) oder Vergleiche gegen vorgegebene Werte mit === (das auch den Typ vergleicht) durchführt werden.
  • Zweitens bietet die Sprache bereits einen Wert für „nicht belegt" an, den sollte man dann auch nutzen.
  • Und Drittens soll man bei Innereien von Typo3 immer nachforschen, welcher Datentyp wirklich erwartet wird, sonst wird man Überraschungen erleben. Die richtige Belegung in diesem Fall ist (integer) 1.
Die Lösung des Problems

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...

0 Kommentar(e)

Mein Kommentar zum Beitrag

Ich möchte über jeden weiteren Kommentar in diesem Post benachrichtigt werden.

Zurück zur Listenansicht

Meist gelesene Beiträge

Lightboxeffekt in Typo3 mit Perfect Lightbox
667 times viewed
19.09.2011 16:30
Mehrere Excel-Dateien in PDF "drucken" mit Hilfe eines VBA...
630 times viewed
29.08.2011 16:01
Tutorial: Web 2.0 Buttons mit Hilfe von CSS3
614 times viewed
08.08.2011 12:01
Wann ist Weblogscreening sinnvoll?
426 times viewed
11.08.2011 15:32

Letzte Kommentare

kleine Erweiterung
03.05.2012 15:48
Vielen Dank für das Skript. Es funktioniert genau wie...
24.04.2012 16:06
G+ schafft es nicht
26.03.2012 12:14
Lightbox ohne Extension
21.09.2011 13:46

Social Bookmarking

Bookmark bei: Mr. Wong Bookmark bei: Webnews Bookmark bei: Yigg Bookmark bei: StumbleUpon Bookmark bei: Google