Das realpath() Problem

Dieser Artikel beschreibt das realpath Problem mit der Mediathek unter WordPress.

Auf der Suche nach einer Lösung kam ich bei meinen Recherchen auf die Support Anfrage: http://wordpress.org/support/topic/225717. Ich hatte bereits viele der mehr oder weniger glücklichen Lösungsvorschläge ausprobiert ohne mich der Lösung des Problems auch nur ansatzweise zu nähern. Aber ZeroChaos hat einen Ansatz geliefert der bereits auf den ersten Blick vielversprechend war, so dass ich auch diesen Ansatz ausprobierte. Der Dank des Tages geht für mich an ZeroChaos! Lösung gefunden.

Bevor ich die Einzelschritte nochmal zusammenfasse, möchte ich die Entwicklungsumgebung und Produktivumgebung beschreiben. Die Entwicklungsumgebung war  XAMPP mit einem WordPress 2.9.1. (es traten keine Probleme auf). Die Kundenistallation lief auf einem ubuntu 5.5, vor dem update auf einem WordPress 2.8.6. Unabhängig von der WordPress Version funktionierte die Mediathek sowohl in der Version 2.8.6 als auch 2.9.1 vollkommen einwandfrei für die Installation der Topleveldomäne. Erst als das System um eine Installation mit einer Subdomain erweitert wurde, gab es für die Subdomain die realpath-Probleme.

Das upload-Verzeichnis im Dashboard unter Verschiedenes stand standardmäßig auf wp-content/uploads und per FTP waren die Verzeichnisrechte auf 777 gesetzt. Dennoch quitierte die Mediathek jeden upload mit der Warnung: realpath() [function.realpath]: Unable to access /var/www/vhosts/NAMEDERDOMÄNE.de/subdomains/SUBDOMÄNE/httpdocs/wp-admin/wp-content/uploads in  /var/www/vhosts/****.de/subdomains/***/httpdocs/wp-includes/functions.php. Auffällig war das die Mediathek nicht auf das richtige Verzeichnis zeigte, denn im Verzeichnisbaum unterhalb von wp-admin existierte ja kein entsprechendes Verzeichnis (wp-content/uploads). Interessanterweise trat für die entsprechende Toplevel-Domäne das realpath-Problem nicht auf. Nun zum Glück hat ZeroChaos eine schmerzfreie Lösung aufgezeigt, die explizit für die Installation in der Subdomäne bei meinem Problem half.
 

Die Schritte im Einzelnen:

  1. im Dashboard >>> Verschiedenes sollte bei "Uploads in folgendem Ordner speichern:" wp-contents/uploads stehen (selbstverständlich kann da auch was anderes stehen – wichtig ist, das dieser Verzeichniszweig unter wp-admin gespiegelt wird)
  2. Der Eintrag unter "Kompletter Pfad zu den Dateien:" sollte frei bleiben
  3. das Verzeichnis wp-contents/uploads erhält via FTP die Verzeichnisrechte 755 bzw. 777
  4. das uploads-Verzeichnis in wp-contents (also wp-contents/uploads) wird nochmal im Verzeichnis wp-admin  erzeugt und mit den Verzeichnisrechten (755 bzw 777) ausgestattet. Es existiert also jetzt folgendes Verzeichnis auf dem Server: wp-admin/wp-contents/uploads (oder das entsprechend angepasste Uploadverzeichnis)
  5. jetzt muss noch eine Funktion angepasst werden, deshalb wird von der Datei  wp-includes/functions.php eine Sicherheitskopie angelegt (falls diese Anpassung nicht zum gewünschten Ergebnis führt)
  6. die Funktion: function path_is_absolute($path) suchen
  7. … und auf folgende Weise auskommentieren (der rotmarkierte Teil ist der entscheidende):
     /*
    function path_is_absolute( $path ) {
        // this is definitive if true but fails if $path does not exist or contains a symbolic link
        if ( realpath($path) == $path )
            return true;

        if ( strlen($path) == 0 || $path{0} == '.' )
            return false;

        // windows allows absolute paths like this
        if ( preg_match('#^[a-zA-Z]:\\\\#', $path) )
            return true;

        // a path starting with / or \ is absolute; anything else is relative
        return (bool) preg_match('#^[/\\\\]#', $path);
    }
    */

  8. dann die folgende Funktion einsetzen (der rotmarkierte Teil ist der entscheidende):
    function path_is_absolute( $path ) {
        // this is definitive if true but fails if $path does not exist or contains a symbolic link
        if ( realpath($path) != $path )
            $path == realpath($path);
        else
            return true;

        if ( strlen($path) == 0 || $path{0} == '.' )
            return false;

        // windows allows absolute paths like this
        if ( preg_match('#^[a-zA-Z]:\\\\#', $path) )
            return true;

        // a path starting with / or \ is absolute; anything else is relative
        return (bool) preg_match('#^[/\\\\]#', $path);
    }

mit diesem Hack konnte ich das ärgerliche realpath-Problem elegant umgehen. Das Lob gebührt hier ZeroChaos für den entscheidenden Hiweis (vgl. den Supporteintrag).

DAS SAGT DIE WELT

COMPANY CUSTOMER PACT

ein Herz für unsere KundenWir glauben an gute Kundenbeziehungen und offene Kommunikation miteinander.