TYPO3-Update LTS 9 + 10 + 11

Verschiedene Stolpersteine und Fehlermeldungen

  • Fluid-Fehler: Fluid parse error in template XY. Error: Required argument "value" was not supplied. (error code 1237823699). Template source chunk: <f:case default="TRUE">
    Lösung: Die Standardoption wird nun mit <f:defaultCase> </f:defaultCase> eingerahmt
  • ext:gridelements: Zuordnungen von Elementen in ihre Container sind zerschossen
    Lösung: Muss man auch erstmal drauf kommen: Beim Update der DB-Struktur gehen die Zuordnungen verloren weil die Werte negativ sind. Danke an blue, der eine schicke SQL-Query dafür parat hat, die auf der alten Datenbank (also von der bisherigen TYPO3-Version) abgeschickt werden muss und die Update-Queries für die neue DB zusammenbaut:
    SELECT CONCAT('UPDATE tt_content set colPos=',colPos,' where uid=',uid,' limit 1;')
    FROM tt_content
    ORDER BY uid;
  • Install-Tool in TYPO3 10 wird nich mehr gefunden
    Anders als in allen bisherigen Versionen ruft man dieses nicht mehr mittels /typo3/install/ auf, sondern es befindet sich unter /typo3/install.php
    Diese Änderung ohne wenigstens entsprechende Weiterleitung von der bewährten und erwarteten Variante ist aus meiner Sicht unnötig schikanös und frustrierend
  • Typoscript-Conditions nun im Symfony-Style
    Wer in seinem TS-Code Fallunterscheidungen eingebaut hat, muss diese ab TYPO3 10 komplett überarbeiten damit diese weiterhin laufen.
    Hier ein paar Beispiele:
    Alt: [globalString = ENV:HTTP_HOST = maischner.de]
    Neu: [request.getNormalizedParams().getHttpHost() == 'maischner.de']

    Alt: [PIDinRootline = 17, 24]

    alt: [PIDinRootline = x,y]
    neu: [x in tree.rootLineIds || y in tree.rootLineIds]

    alt: [globalVar = GP:tx_foo_bar|foobar > 0]
    neu: [request.getQueryParams()['tx_foo_bar']['foobar'] > 0] # für GET
    neu: [request.getParsedBody()['tx_foo_bar']['foobar'] > 0] # für POST
     
  • Call to a member function sql_query() on null / Call to undefined method TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::enableFields()
    Auch wenn es offenbar verpöhnt ist, als Entwickler noch eigene SQL-Queries zu schreiben, lasse ich mir das für schnellere oder auch kompliziertere Sachen nicht nehmen. Sei es, weil Doctrine DBAL mitunter einfach an seine Grenzen stößt oder zu schwerfällig ist.
    Die alte Funktion enableFields() im cObj gibt es zwar nicht mehr, dafür kommt man nun dank der Extension typo3db_legacy folgendermaßen dran: $GLOBALS['TSFE']->sys_page->enableFields( TABLE ) - also z.B. $GLOBALS['TSFE']->sys_page->enableFields( 'pages' )
  • Page Not Found -The page did not exist or was inaccessible. Reason: The requested page does not exist
    Hier kann die Zuordnung von URL zu einer Seite nicht ermittelt werden.
    Mögliche Lösung: Das URL-Segment der beabsichtigten Seite prüfen und ggf. anpassen und einen Redirect bauen

  • TS-Conditions greifen nicht mehr
    Grund: Die bislang bewährte Syntax wurde ab TYPO3 9.4 komplett beerdigt und gegen die Symfony Expression Language getauscht. Es wird also nicht langweilig.

    ALT: [globalString = IENV:HTTP_HOST = typo3.org]
    NEU: [like(request.getNormalizedParams().getHttpHost(), 'typo3.org')]

    ALT: [globalString = IENV:TYPO3_SSL=1]
    NEU: [request.getNormalizedParams().isHttps() == 1]

    ALT: [globalVar = GP:tx_news_pi1|news > 0]
    NEU: [request.getQueryParams()['tx_news_pi1']['news'] > 0]

    # befindet sich die ID in der Rootline (z.B. für die Ansprache aller Unterseiten)
    Alt: [PIDinRootline = 3,4]
    Neu: [3 in tree.rootLineIds || 4 in tree.rootLineIds]
     
  • Cache für Admins deaktivieren funktioniert nicht mehr
    Eine beliebte Standard-Einstellung ist das Deaktivieren des Caches für Admins (gerade in der Entwicklung).
    Dafür hat bislang folgende Zeile im User-TS genügt.
    override.tsdebug.forceTemplateParsing = 1
    Da das Admin-Panel aber nun als eigene Systemextension ausgelagert wurde, muss diese ggf. noch aktiviert werden, damit das wieder funktioniert.
  • The package "xyz" depends on "lang" which is not present in the system.
    Wenn ein Extension-Fehler dafür sorgt, dass man nicht einmal ins Install-Tool durchgelassen wird (wo man renitente Extensions eigentlich deaktivieren lassen kann), muss man wohl in der typo3conf/PackageStates.php den betreffenden Eintrag per Hand entfernen.
  • Class 'TYPO3\CMS\Core\Information\Typo3Version' not found
  • TYPO3Fluid\Fluid\Core\Parser\Exception
    Template source chunk: <f:case default="true">
  • Checking session and executing silent configuration update
  • 1239891990 InvalidArgumentException
    "The extension name must not be empty."

    Lösung: Hier handelt es sich um einen aus meiner Sicht überflüssig abgeschnittenen Zopf. Die Variable $_EXTKEY wird nicht mehr mit dem aktuellen Extensionnamen befüllt, sondern muss an allen Stellen hart kodiert werden. Ein Traum für jeden richtigen Programmierer.
  • [Semantical Error] The annotation "@lazy" in property XY was never imported. Did you maybe forget to add a "use" statement for this annotation?
    Lösung: Das @lazy einfach durch die neue Doctrine-Formulierung @TYPO3\CMS\Extbase\Annotation\ORM\Lazy ersetzen
    Analoges gilt für "The annotation "@inject"": Dies bitte durch @TYPO3\CMS\Extbase\Annotation\Inject ersetzen
  • 1579965021 TYPO3\CMS\Extbase\Persistence\Generic\Mapper\Exception\UnknownPropertyTypeException
    The type of property XY could not be identified, therefore the desired value (NULL) cannot be mapped onto it. The type of a class property is usually defined via php doc blocks. Make sure the property has a valid @var tag set which defines the type.
    Lösung: Auch schön! Man muss neuerdings peinlich darauf achten, im PHP-Doc-Block (also dort, wo man die Variable genauer definiert, hier: im Model) keinen Schnickschnack (z.B. Kommentare) stehen zu haben.

Hier möchte ich meinen Update-Weg von TYPO3 8 auf die nächsthöheren Versionen 9, 10, 11 usw. festhalten.
Die LTS 8 war eine solide Version und hat sich im Tagesgeschäft sehr gut bewährt. Aber um den Anschluss nicht zu verlieren, wird es nun Zeit sich den Herausforderungen zu stellen, die ein Update mit seinen breaking changes zwangsläufig mit sich bringt.

Aufgrund der grundlegenden Änderung bei der URL-Generierung (nun im Core) und der zwischenzeitlich aus meiner Sicht nicht zufriedenstellenden Onboard-Lösung habe ich die Updates bei den von mir betreuten Instanzen lange hinauszögern müssen (mal abgesehen vom reichhaltigen Tagesgeschäft). Die gewachsenen und ausgetüftelten CoolURI- bzw. RealURL-Konfigurationen konnten aus meiner Sicht einfach nicht vernünftig abgebildet werden. Aus SEO-Sicht möchte ich gern über die URLs bestimmen und nicht durch das CMS eingeschränkt werden.

URL-Handling

Das besprochene Generierung der sprechenden URLs aus den Parameter-URLs wird seit TYPO3 9 grob folgendermaßen gelöst:

  • es gibt keinen Index mehr, der die sprechenden URLs in der Datenbank vorhält
  • diese werden anhand der Konfiguration ermittelt

Herausforderungen:

  • Segmente vom Pfad ausschließen (z.B. für unwichtige Pfade)
    Das funktioniert aktuell nach meinem Verständnis nur, wenn die gewünschte Seite des Segments as grauer Ordner angelegt wird.
    Es funktioniert also nicht (mehr unmittelbar aus dem Backend), dass man folgendes Schema erzielt:
    domain.tld/news/ und domain.tld/news/beitrag-xyz-343/
    Wenn man die News-Seite als Ordner definiert, kann man natürlich die News-Übersicht nicht aufrufen.
    Obgleich kann man das nun natürlich in der Site-Konfiguration regeln kann (sh. unten), ist also
     
  • Änderung von Pfaden und Weiterleitung von der bisherigen Variante
    Möchte ich einen Pfad ändern (z.B. weil sich der Name der Unterseite geändert hat), so muss das manuell erfolgen. Eine automatische Änderung anhand der Kriterien findet nicht statt. Der Vorteil ist dabei nur, dass man immer die Hohheit über den Pfad einer Seite hat.
    Nächster Punkt ist die Weiterleitung der alten Variante auf die aktuelle. Dafür gibt
  • abschließender Slash (trailing slash)