Weil es doch immer wichtiger wird zu kontrollieren wer im Internet Bilder sehen darf und wer nicht kann man Inhalte in WordPress recht einfach mit einem Passwort schützen.
Ich nutze das beliebte NextGen Gallery PlugIn für WordPress. Dabei bleibt aber leider das Problem, dass der direkte Link zu dem Bild weiterhin ohne Schutz ist. Eigentlich ist das kein so großes Problem, da ich ja nichts verbotenes online stelle und man den Link zum Bild erraten müsste, aber irgendwie unbefriedigend ist es schon. Denn die Pfade und Bildnamen sind jetzt nicht so kompliziert.
Also habe ich mal geschaut, was es da so für Möglichkeiten schon gibt, habe aber auf die Schnelle nichts gefunden und bevor ich viel weiter suche, programmiere ich mir halt selbst schnell was zusammen.
Um die Bilder zu schützen dürfen sie nicht direkt ausgeliefert werden. Daher habe ich eine .htaccess Datei einmal in den Nextgen Ordner mit den Bilder-Subfoldern und einmal in das Uploads Verzeichnis gelegt, der per mod_rewrite bei Aufruf einer .jpg Datei auf eine PHP umleitet.
.htaccess <FilesMatch "\.(jpg|jpe?g)$"> RewriteEngine on RewriteCond %{REQUEST_URI} !.*/thumbs/.* RewriteRule (.*) /image.php?i=%{REQUEST_URI} [R] </FilesMatch>
Die Nextgen Thumbs habe ich jedoch ausgeschlossen, da die auch ohne Passworteingabe angezeigt werden müssen.
Die PHP Datei image.php im Root empfängt den Bild-Pfad und prüft nun die Rechte.
- Ist das Bild in der Nextgen Datenbank hinterlegt?
- Ist es von der Anzeige ausgeschlossen?
- Gehört es zu einer Passwort-geschützen Nextgen Gallery Seite?
- Ist das richtige Passwort gesetzt?
Wenn das Bild nicht zu einer Galerie gehört…
- Ist das Original-/Vollbild ein Anhang zu einer geschützten Seite?
- Ist das Passwort gesetzt?
Die Vorschaubilder und Bilder die zu keiner Seite gehören sind davon ausgenommen und werden direkt angezeigt.
Wenn das Bild nicht ausgeliefert werden darf wird ein transparentes 1×1 Pixel PNG ausgeliefert.
image.php <?php require_once($_SERVER['DOCUMENT_ROOT'].'/wp-config.php'); $pathinfo = pathinfo($_GET['i']); if ($pathinfo['extension'] == 'jpg'){ $path = $pathinfo['dirname']; $file = $pathinfo['basename']; $filename = $pathinfo['filename']; if (file_exists($_SERVER['DOCUMENT_ROOT'].$path.'/'.$file)){ $gallery_row = $wpdb->get_row($wpdb->prepare("SELECT gid, pageid FROM " . $table_prefix . "ngg_gallery WHERE path = %s ", substr($path, 1))); $gid = $gallery_row->gid; $pageid = $gallery_row->pageid; if($pageid > 0){ $pic_row = $wpdb->get_row($wpdb->prepare("SELECT pid, COUNT(*) AS 'counter' FROM " . $table_prefix . "ngg_pictures WHERE galleryid = %s AND filename = %s AND exclude = 0", $gid, $file)); $pid = $pic_row->pid; $filecount = $wpdb->get_var($query); if($filecount > 0){ $thispost = get_post($pageid); if (!post_password_required($pageid)){ deliverImage($path, $file); } } } else { $pageid = $wpdb->get_var($wpdb->prepare("SELECT post_parent FROM " . $table_prefix . "posts WHERE post_type = 'attachment' AND post_mime_type = 'image/jpeg' AND post_name = %s ", $filename)); if($pageid > 0){ $thispost = get_post($pageid); if (!post_password_required($pageid)){ deliverImage($path, $file); } } else { deliverImage($path, $file); } } } } header('Content-disposition: inline; filename="_.png"'); header('Content-transfer-encoding: binary'); header('Content-type: image/png'); $im = imagecreate(1, 1); $white = ImageColorAllocate($im, 0xFF, 0xFF, 0xFF); ImageFilledRectangle($im, 0, 0, 1, 1, $white); imagecolortransparent($im, $white); ImagePng($im); ImageDestroy($im); exit(); function deliverImage($path, $file){ header('Content-disposition: inline; filename="' . $file . '"'); header('Content-transfer-encoding: binary'); header('Content-type: image/jpeg'); readfile($_SERVER['DOCUMENT_ROOT'] . $path . '/' . $file); exit(); } ?>
Also eigentlich recht einfach und effektiv. Diese Funktionalität lässt sich natürlich recht einfach auf andere Dateitypen erweitern. Viel Spaß beim Nachbauen…