#webdev

Heute gab es auf einer von mir betreuten Website mit MODX ein merkwürdiges Problem: Die Startseite sowie alle weiteren Unterseiten waren plötzlich weiß und zeigten keine Inhalte mehr an – der Zugang zum Backend lief aber zum Glück noch.

Auf der Suche nach der Ursache wollte ich zunächst ins Fehlerprotokoll gucken, aber die Seite im Backend lud sich endlos selbst neu, da das Error-Log zu groß war: 1,1 GB!

Per FTP auf dem Server angemeldet, das Fehlerprotokoll, /core/cache/logs/error.log, heruntergeladen und auf dem Server gelöscht.
Die Startseite und alle Unterseiten waren daraufhin wieder erreichbar – Symptom behoben, aber die Ursache noch nicht.

Beim Surfen durch die Seite füllte sich das Fehlerprotokoll innerhalb weniger Minuten wieder, je nach Unterseite mit vielen Bildern sogar um einige MB pro Seitenaufruf, sodass das Log schon nach kurzer Zeit wieder bei 10, 30 und 80 MB war.

Die Ursache für das große Error-Log war das Modul phpThumb(), das reihenweise Fehlermeldungen wie folgende generierte:

[2018-03-15 13:20:18] (ERROR @ /mnt/web###/##/##/########/htdocs/project/website/core/components/phpthumbof/model/phpthumbof.class.php : 156) [pThumb] Resource: 1 || Image: /home/strato/http/premium/rid/##/##/########/htdocs/project/website/assets/gallery/12/126.jpg  
Could not generate thumbnail
phpThumb debug output:
	[0] => phpThumb() v1.7.14-201608101311 in file "phpthumb.class.php" on line 229
	[1] => setSourceFilename(/home/strato/http/premium/rid/##/##/########/htdocs/project/website/assets/gallery/12/126.jpg) set $this->sourceFilename to "/home/strato/http/premium/rid/##/##/########/htdocs/project/website/assets/gallery/12/126.jpg" in file "phpthumb.class.php" on line 294
	[2] => $AvailableImageOutputFormats = array(text;ico;bmp;wbmp;gif;png;jpeg) in file "phpthumb.class.php" on line 969
	[3] => $this->thumbnailFormat set to $this->config_output_format "jpeg" in file "phpthumb.class.php" on line 980
	[4] => $this->thumbnailFormat set to $this->f "jpeg" in file "phpthumb.class.php" on line 987
	[5] => $this->thumbnailQuality set to "75" in file "phpthumb.class.php" on line 997
	[6] => resolvePath: /home/strato/http/premium/rid/##/##/########/htdocs/project/website/assets/gallery/12/126.jpg (allowed_dirs: Array
(
)
) in file "phpthumb.class.php" on line 1140
	[7] => resolvePath: iteration, path=/home/strato/http/premium/rid/##/##/########/htdocs/project/website/assets/gallery/12/126.jpg, base path = /mnt/web###/##/##/########/htdocs/project/website in file "phpthumb.class.php" on line 1159
	[8] => resolvePath: stop at component 4 in file "phpthumb.class.php" on line 1175
	[9] => resolvePath: stop at path=/home/strato/http/premium in file "phpthumb.class.php" on line 1178
	[10] => resolvePath: no match, returning null in file "phpthumb.class.php" on line 1180
	[11] => !$this->config_allow_src_above_docroot therefore setting "" (outside "/mnt/web###/##/##/########/htdocs/project/website") to null in file "phpthumb.class.php" on line 1344
	[12] => $this->sourceFilename set to "" in file "phpthumb.class.php" on line 894
	[13] => phpThumb() v1.7.14-201608101311
http://phpthumb.sourceforge.net

Error messages disabled.

edit phpThumb.config.php and (temporarily) set
$PHPTHUMB_CONFIG['disable_debug'] = false;
to view the details of this error in file "phpthumb.class.php" on line 4126
	[14] => resolvePath: /home/strato/http/premium/rid/##/##/########/htdocs/project/website/assets/gallery/12/126.jpg (allowed_dirs: Array
(
)
) in file "phpthumb.class.php" on line 1140
	[15] => resolvePath: iteration, path=/home/strato/http/premium/rid/##/##/########/htdocs/project/website/assets/gallery/12/126.jpg, base path = /mnt/web###/##/##/########/htdocs/project/website in file "phpthumb.class.php" on line 1159
	[16] => resolvePath: stop at component 4 in file "phpthumb.class.php" on line 1175
	[17] => resolvePath: stop at path=/home/strato/http/premium in file "phpthumb.class.php" on line 1178
	[18] => resolvePath: no match, returning null in file "phpthumb.class.php" on line 1180
	[19] => !$this->config_allow_src_above_docroot therefore setting "" (outside "/mnt/web###/##/##/########/htdocs/project/website") to null in file "phpthumb.class.php" on line 1344
	[20] => SetCacheFilename() _src set from md5($this->sourceFilename) "" = "d41d8cd98f00b204e9800998ecf8427e" in file "phpthumb.class.php" on line 3520
	[21] => SetCacheFilename() _par set from md5(_farC_w970_dpi150_q75) in file "phpthumb.class.php" on line 3553
	[22] => starting ExtractEXIFgetImageSize() in file "phpthumb.class.php" on line 3314
	[23] => skipping getimagesize() because $this->sourceFilename is empty in file "phpthumb.class.php" on line 3326
	[24] => getimagesize("") failed in file "phpthumb.class.php" on line 3357
	[25] => $this->useRawIMoutput=true after checking $UnAllowedParameters in file "phpthumb.class.php" on line 1595
	[26] => ImageMagickThumbnailToGD() aborting because $this->sourceFilename is empty in file "phpthumb.class.php" on line 1640
	[27] => ImageMagickThumbnailToGD() failed in file "phpthumb.class.php" on line 3364
	[28] => SetOrientationDependantWidthHeight() starting with ""x"" in file "phpthumb.class.php" on line 3293
	[29] => SetOrientationDependantWidthHeight() setting w="970", h="0" in file "phpthumb.class.php" on line 3309
	[30] => EXIF thumbnail extraction: (size=0; type=""; 0x0) in file "phpthumb.class.php" on line 3421
	[31] => starting SourceImageToGD() in file "phpthumb.class.php" on line 3679
	[32] => Not using EXIF thumbnail data because $this->exif_thumbnail_data is empty in file "phpthumb.class.php" on line 3751
	[33] => $this->gdimg_source is still empty in file "phpthumb.class.php" on line 3803
	[34] => ImageMagickThumbnailToGD() failed in file "phpthumb.class.php" on line 3805
	[35] => phpThumb() v1.7.14-201608101311
http://phpthumb.sourceforge.net

Error messages disabled.

edit phpThumb.config.php and (temporarily) set
$PHPTHUMB_CONFIG['disable_debug'] = false;
to view the details of this error in file "phpthumb.class.php" on line 4126
	[36] => SourceImageToGD() failed in file "phpthumb.class.php" on line 374
----------------------

»Could not generate thumbnail« war zunächst das Offensichtlichste und Verständlichste an der Fehlermeldung. Eine Google-Suche danach brachte nur ein Ergebnis, dass leider keine Lösung aber einen wichtigen Hinweis lieferte: Irgendetwas stimmt mit den Pfaden zu den Bild-Dateien nicht.

In der Haupt-Konfigurationsdatei /core/config/config.inc.php fiel mir bereits auf, dass es zwei absolute Pfade gibt (Zahlen/IDs durch »#« ersetzt):

  1. /home/strato/http/premium/rid/##/##/########/htdocs/project/website/
  2. /mnt/web###/##/##/########/htdocs/project/website/

Diese waren verschiedenen Einstellungen zugeordnet; jedoch ohne erkennbaren Grund, warum die erste Variante bei der einen Einstellung und die zweite Variante bei einer anderen. Bei anderen MODX-Websites bei anderen Hostern, wie All-Inkl.com oder Uberspace, sind die Pfade bei allen Einstellungen identisch.

Strato nutzt zwei absolute Pfade für Websites. Einmal den, ich nenne es mal, »offiziellen« /home/strato/http/premium/rid/##/##/########/htdocs/; und den »inoffiziellen« (wahrscheinlich physischen) Pfad /mnt/web###/##/##/########/htdocs/.
Ein Blick in die PHP-Konfiguration zeigt auch: der erste Pfad steht auch in den üblichen Server-Variablen wie _SERVER["DOCUMENT_ROOT"]; der zweite Pfad tauch in – für mich bisher ungewöhnlichen – Server-Variablen wie _SERVER["RZ_path"] auf.

Nach einigen Versuchen und wiederholtem Lesen jeder Zeile der Fehlermeldung, war schließlich klar was genau die Ursache für die Fehler-Tirade ist: phpThumb arbeitet mit dem zweiten, »inoffiziellen« Pfad, bekommt aber von MODX die Pfade zu den Bild-Dateien in der ersten, »offiziellen« Variante. Und dann, beim »auflösen« der Pfade passiert das, was in den Zeilen 7–11 bzw. 15–19 der Fehlermeldung steht: phpThumb verlässt den Bereich, den es lesen darf (docroot also Document Root) und findet die Bild-Datei nicht – denn für phpThumb sind diese beiden Pfade nicht identisch und kann sie nicht, wie anscheinend Strato, synonym verwenden.

Die Lösung ist also, die Pfade an phpThumb anpassen: in der /core/config/config.php und der /connectors/config.core.php alle Pfade auf die zweite Pfad-Variante umstellen, schon findet phpThumb die Bild-Dateien und die Fehlermeldungen hören auf.

wp-blank ist ein einfaches Starter-Theme für WordPress mit dem Fokus auf die wichtigsten Funktionen von WordPress und gutes Markup (sauberes und logisches HTML).

Nachdem ich nun seit einigen Jahren für Blogs und Websites individuelle Themes für WordPress baue, und diese Themes in gewisserweise immer aufeinander aufgebaut haben, wurde es Zeit die, meiner Ansicht nach, wichtigsten Funktionen in einem Starter-Theme für den schnellen Entwicklungs-Start zu bündeln.

Im Gegensatz zu den Standard-Themes von WordPress, die Twenty-Reihe (»Twenty Eleven«, »Twenty Twelve«, etc.), soll wp-blank im Quellcode übersichtlicher und verständlicher sein; und im Gegensatz zu anderen Starter-Themes nutzt wp-blank nicht jede verfügbare WordPress-Funktion und hängt auch nicht von einem Frontend-Framework wie Bootstrap ab.

Screenshot des WordPress-Themes wp-blank 1.0

wp-blank soll einen schnellen Start in die Theme-Entwicklung bieten und gutes, sauberes Markup generieren, zudem man dann sein eigenes CSS für ein Design hinzugeben muss. Außerdem nimmt wp-blank Best-Practice-Ansätze aus der Webentwicklung auf, u.a. für Barrierefreiheit (Accessibility), Mikro-Daten nach Schema.org zur Suchmaschinen-Optimierung, Platzhalter-Grafiken mit Verknüpfungen für iOS- und Windows-Lesezeichen und viele weitere Details. Ein vollständige Liste der Features findet sich in der README.

Wie gesagt ist wp-blank nur ein Ausgangspunkt für sein einges Theme: Jede Funktionalität, die über den Standard hinausgeht, muss in das eigene Theme eingebaut werden und jedes zusätzliche, individuelle Seiten- oder Post-Template muss ebenfalls selbst angelegt werden. Aber genau das ist der Sinn bei wp-blank: ein minimaler aber optimaler Start-Punkt für ein individuelles WordPress-Theme.

Über Fragen, Anmerkungen oder Fehler-Hinweise freue ich mich sehr – wenn möglich am Besten als Issue auf GitHub einreichen.

Download und Sourcen bei GitHub.