Request parameters could not be validated (&cHash empty)

Heute wurde ich drauf aufmerksam gemacht, dass bei einer kleinen Galerie das Weiterblättern nicht mehr funktionieren würde. Ein Blick bestätigte den Fehler:

Request parameters could not be validated

Betroffen war ein TYPO3 CMS (Version 6.1.7) mit EXT:chgallery (Version 2.5.2).

Was aber verursacht den Fehler? Und warum hatte das lange Zeit fehlerfrei funktioniert???

Analyse

Auslöser der Fehlermeldung ist eine Abfrage im Konstruktor des Plugins (bzw. \TYPO3\CMS\Frontend\Plugin\AbstractPlugin):

// cHash mode check
// IMPORTANT FOR CACHED PLUGINS (USER cObject): As soon as you generate cached plugin output which depends on parameters (eg. seeing the details of a news item) you MUST check if a cHash value is set.
// Background: The function call will check if a cHash parameter was sent with the URL because only if it was the page may be cached. If no cHash was found the function will simply disable caching to avoid unpredictable caching behaviour. In any case your plugin can generate the expected output and the only risk is that the content may not be cached. A missing cHash value is considered a mistake in the URL resulting from either URL manipulation, "realurl" "grayzones" etc. The problem is rare (more frequent with "realurl") but when it occurs it is very puzzling!
if ($this->pi_checkCHash && count($this->piVars)) {
    $GLOBALS['TSFE']->reqCHash();
}

Die aufgerufene Methode reqCHash() stellt fest, dass kein cHash gesetzt ist, und löst (in Kombination mit der Einstellung pageNotFoundOnCHashError) die Fehlermeldung aus.

Ok, und warum ist kein cHash gesetzt?

Beim Durchklicken fällt auf, dass im Pagebrowser der no_cache-Parameter enthalten ist. Das würde einen cHash überflüssig machen, weshalb er insolchen Links fehlt.
Die Seite selbst soll jedoch gecacht werden, und die Extension ist eigentlich ein USER-Objekt, d.h. auch cachbar. Ein Blick in den Extension-Code bestätigt, dass die Galerie eigentlich für Caching ausgelegt ist und der cHash geprüft werden soll ($pi_checkCHash = true). Das wiederum würden begründen, weshalb ein Fehler wegen fehlendem cHash ausgelöst wird.

Woher, also, kommt der unerwünschte no_cache-Parameter in den Links?

Drehen wir eine Runde durch die AbstractPlugin-Klasse :-)
Der Pagebrowser der Galerie wird über pi_list_browseresults() erzeugt. Die Methode selbst erhält keinen Parameter übergeben, der direkt Einfluss auf das Caching bzw. den no_cache-Parameter hat. Die Methode greift zur Linkerzeugung aber auf pi_linkTP_keepPIvars() zu, welche als dritten Parameter $cache übergeben bekommt:

* @param boolean $cache If $cache is set, the page is asked to be cached by a &cHash value (unless the current plugin using this class is a USER_INT). Otherwise the no_cache-parameter will be a part of the link.

Da kommen wir der Sache doch vielleicht schon näher. Eine schnelle Debugausgabe bestätigt: ja, der Parameter ist weder TRUE noch 1, d.h. hier werden Links für ungecachte Aufrufe angefordert.

Woher kommt der Wert, der hier als $cache-Parameter an die Methode übergeben wird?

Übergeben wird die Variable $pi_isOnlyFields, welche innerhalb der Methode pi_list_browseresults() gefüllt wird:

$pi_isOnlyFields = $this->pi_isOnlyFields($this->pi_isOnlyFields);

Springen wir also weiter zu dieser Methode:

/**
 * Returns TRUE if the piVars array has ONLY those fields entered that is set in the $fList (commalist) AND if none of those fields value is greater than $lowerThan field if they are integers.
 * Notice that this function will only work as long as values are integers.
 *
 * @param string $fList List of fields (keys from piVars) to evaluate on
 * @param integer $lowerThan Limit for the values.
 * @return boolean Returns TRUE (1) if conditions are met.
 * @todo Define visibility
 */
public function pi_isOnlyFields($fList, $lowerThan = -1) {
    $lowerThan = $lowerThan == -1 ? $this->pi_lowerThan : $lowerThan;
    $fList = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $fList, 1);
    $tempPiVars = $this->piVars;
    foreach ($fList as $k) {
        if (!\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($tempPiVars[$k]) || $tempPiVars[$k] < $lowerThan) {
            unset($tempPiVars[$k]);
        }
    }
    if (!count($tempPiVars)) {
        return 1;
    }
}

In Worten: Falls in den piVars nur Parameter vorkommen, die in der übergebenen Fieldlist ($fList) vorkommen, gibt eine 1 zurück.
Nachdem wir für gecachte Links einen Rückgabewert 1 erwarten und benötigen würden, liegt nahe, dass hier wohl keine 1 zurückkommt. Werfen wir also ein Auge auf die Feldliste:

Übergeben wird hier $this->pi_isOnlyFields. Die Klassenvariable ist defaultmäßig auf ‚mode,pointer‘ gesetzt. Es ist also logisch, dass pi_isOnlyFields() am Ende noch Werte in dem piVars-Array hat, nachdem chgallery als piVar-Keys single, dir und pointer hat. Und folglich kommt hier keine 1 zurück.

Lösung

Ein einfaches Anapssen des pi_isOnlyFields-Werte passend zur Extension löst das Problem:

     var $pi_isOnlyFields = 'pointer,single,dir';

Aber warum ist das (jetzt) so? Bzw. was hat sich hier wann geändert, dass die chgallery nicht mehr läuft???

Hinterlasse einen Kommentar.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.