Mein Bild-Optimierer-Plugin meckert unter Joomla 4 plötzlich rum, dass Einleitungsbild (image_intro) und so genanntes "Komplettes Beitragsbild" (image_fulltext) nicht existieren, wenn ich sie mit dem neuen Joomla-Medienmanager in einem Beitrag auswähle. Schuld sind "komische" Anhängsel an die Bildpfade, die Joomla jetzt automatisch mitspeichert und die in meinem Fall störend sind. Wie man sie los wird?

Joomla 3 versus Joomla 4

In beiden Szenarien lege ich einen neuen Beitrag an und wähle im Tabulator "Bilder und Links" ein "Einleitungsbild" und ein Bild im Feld mit dem blöden Namen "Komplettes Beitragsbild". Wichtig ist, dass ich nicht den JCE-Editor verwende, sondern den Joomla-Standard, der wiederum den joomlaeigenen Medienmanager für die Bild-Auswahl anbietet.

Mein eingesetztes Besipielbild ist images/headers/maple.jpg.

Nach dem Speichern des Beitrags kann ich entweder in der Datenbank in der Tabelle #__content den Beitrag suchen und mir das Datenbank-Feld images anschauen oder ich verwende zum Debuggen folgenden, altbekannten Code in einer Beitragsansicht im Frontend:

defined('_JEXEC') or die;

$images = json_decode($this->item->images);
echo ' DEBUG $images: <pre>' . print_r($images, true) . '</pre>';exit;

Ergebnis in Joomla 3

Meinen Debug-Code habe ich an den Anfang der Datei components\com_content\views\article\tmpl\default.php eingebaut und rufe dann meinen neuen Beitrag im Frontend auf.

Der Ausgabe-Code sieht (gekürzt) so aus:

stdClass Object
(
    [image_intro] => images/headers/maple.jpg
...
    [image_fulltext] => images/headers/maple.jpg
...
)

Ergebnis in Joomla 4

Meinen Debug-Code habe ich an den Anfang der Datei components\com_content\tmpl\article\default.php eingebaut und rufe dann meinen neuen Beitrag im Frontend auf.

Der Ausgabe-Code sieht (gekürzt) so aus:

stdClass Object
(
    [image_intro] => images/headers/maple.jpg#joomlaImage://local-images/headers/maple.jpg?width=700&height=180
...
    [image_fulltext] => images/headers/maple.jpg#joomlaImage://local-images/headers/maple.jpg?width=700&height=180
...
)

Man beachte die "komischen" Würmer #joomlaImage://local-images/... nach den normalen Pfaden images/headers/maple.jpg im Unterschied zur Joomla-3-Ausgabe.

Wann stört das nicht?

Wenn ich die Pfade so wie sie sind in einen <img>-Tag einbaue. Die Bilder werden trotzdem angezeigt.

<img src=<?php echo $images->image_intro; ?> alt="">

=> ERGIBT:

<img src=images/headers/maple.jpg#joomlaImage://local-images/headers/maple.jpg?width=700&height=180 alt="">

Wann stört das?

Wenn ich prüfen will, ob das Bild unter dem Pfad existiert, was mein Bild-Optimierer-Plugin beispielsweise macht.

if (is_file(JPATH_SITE . '/' . $images->image_intro))
{
 ---TU WAS---
}

Joomla 3 wird was tun, Joomla 4 aber nicht.

Lösung? Die Peter-Henderson-&-Co-Methode

Neben Joomla-Methoden, z.B. aus der JUri-Klasse, kann man auch puritisches PHP verwenden, um den Wurm loszuwerden:

$images->intro_image = explode('#', $images->image_intro)[0];

if (is_file(JPATH_SITE . '/' . $images->image_intro))
{
 ---TU WAS---
}

oder etwas ausführlicher in einer eigenen Methode/Funktion (für Joomla 3 und 4), wenn man's öfter mal braucht:

/** Since Joomla 4 new stupid path format like
* images/blue.jpg#joomlaImage://local-images/blue.jpg?width=80&height=80
*/
public static function extractImagePath($image)
{
	if (empty($image) || version_compare(JVERSION, '4', 'lt')
		|| strpos($image, '#') === false)
	{
		return $image;
	}

	return explode('#', $image)[0];
}

Anderes Szenario unter Joomla 4 - Den "Wurm" entschlüsseln

Oben geht es ja darum, dass ich den Pfad so haben möchte, dass eine Prüfung durchgeführt werden kann, ob die Bilddatei existiert und das sowohl kompatibel mit Joomla 3 als auch Joomla 4.

Bembelimen aus dem Joomla-Forum hat uns darauf hingewiesen, dass es in Joomla 4 auch eine HTMLHelper/JHtml-Methode gibt (cleanImageURL()), mit der man den Pfad ermitteln kann. Die dient dem Zweck, den "Wurm" in seine Bestandteile zu zerlegen und die darin enthaltenen Informationen (z.B. width und height) in einem PHP-Object zurückzugeben, wenn man sie weiter nutzen möchte und zusätzlich den gesäuberten Pfad haben möchte. Die Verwendung kann dann so aussehen:

// z.B. das zurückerhaltene image_intro mit dem "Wurm" hinten dran:
$meinBild = 'images/headers/maple.jpg#joomlaImage://local-images/headers/maple.jpg?width=700&height=180';

// Zerlegen:
$wurmInfos = HTMLHelper::_('cleanImageURL', $meinBild);

// $wurmInfos debuggen:
echo ' DEBUG $wurmInfos : <pre>' . print_r($wurmInfos , true) . '</pre>';exit;

Die Debug-Ausgabe sieht dann so aus:

stdClass Object
(
    [attributes] => Array
        (
            [width] => 700
            [height] => 180
        )

    [url] => images/headers/maple.jpg
)

Um den gesäuberten Pfad auszugeben, greife ich auf die Objekteigenschaft url zurück:

echo $wurmInfos->url;

Nach ein paar Tests und Spielereien: Die Methode dient ausschließlich dieser spezifischen Entschlüsselung! Sie ist anderweitig nicht sonderlich intelligent und spuckt auch Unsinn aus, wenn der "Wurm" nicht exakt so angehängt und aufgebaut ist, wie ihn der Medienmanager abspeichert.