Kategorien
Web-Development

Lightbox Bilder speichern bzw. downloaden

Es gab ein größeres Lightbox Update, deshalb habe ich das Lightbox Projekt auf GitHub geforkt und angepasst für Version 2.51: https://github.com/nooblucker/lightbox2 

Ich nutze Lightbox v2.05 auf vielen Websites, um Bilder bzw. Bildergalerien ansprechend zu präsentieren. Leider wissen viele User nicht, wie sie das angezeigte Bild speichern bzw. downloaden können. In manchen Browsern funktioniert es über einen Rechtsklick auf den Link und „Ziel speichern unter“. In anderen Browsern wird der Rechtsklick aber von Lightbox abgeblockt. Darum habe ich beschlossen, Lightbox um einen Download-Button zu erweitern.

Hierzu erweitern wir zunächst das LightboxOptions Objekt um eine Variable, die den Pfad zum Download-Button beinhaltet. Dazu öffnen wir die mitgelieferte Datei „lightbox.js“.

LightboxOptions = Object.extend({
    fileLoadingImage:        '/images/loading.gif',
    fileBottomNavCloseImage: '/images/closelabel.gif',
    fileBottomNavDownloadImage: '/images/download-icon.gif',

    overlayOpacity: 0.8,   // controls transparency of shadow overlay

In der selben Datei ändern wir den Konstruktor der Lightbox Klasse, also die Methode initialize. Wir fügen einen Link mit der ID „bottomNavDownload“ und die Download-Grafik hinzu.

Builder.node('div', {id:'imageDataContainer'},
 Builder.node('div',{id:'imageData'}, [
  Builder.node('div',{id:'imageDetails'}, [
   Builder.node('span',{id:'caption'}),
   Builder.node('span',{id:'numberDisplay'})
  ]),
  Builder.node('div',{id:'bottomNav'}, [
   Builder.node('a',{id:'bottomNavDownload', href: '#', target: '_blank' },
    Builder.node('img', { src: LightboxOptions.fileBottomNavDownloadImage })
   ),
   Builder.node('a',{id:'bottomNavClose', href: '#' },
    Builder.node('img', { src: LightboxOptions.fileBottomNavCloseImage })
   )
  ])
 ])
)

Nun müssen wir nur noch das richtige Ziel für den Link setzen. Dazu nutzen wir die updateDetails Methode.

    //
    //  updateDetails()
    //  Display caption, image number, and bottom nav.
    //
    updateDetails: function() {

        this.caption.update(this.imageArray[this.activeImage][1]).show();

        $('bottomNavDownload').href = '/download.php?filename='+$('lightboxImage').src;

Mein Download-Button ist ein Diskettensymbol. Als Ergebnis erhalte ich dann also links neben dem Close-Button das Diskettensymbol. Ein Linksklick öffnet das Bild in einem Download-Dialog. Und zwar erreicht man dies durch die Datei download.php mit folgendem Inhalt:

<?php

// from http://www.php.net/manual/de/function.header.php#102175
function downloadFile( $fullPath ){

 // Must be fresh start
 if( headers_sent() )
 die('Headers Sent');

 // Required for some browsers
 if(ini_get('zlib.output_compression'))
 ini_set('zlib.output_compression', 'Off');

 // File Exists?
 if( file_exists($fullPath) ){

 // Parse Info / Get Extension
 $fsize = filesize($fullPath);
 $path_parts = pathinfo($fullPath);
 $ext = strtolower($path_parts["extension"]);

 // Determine Content Type
 switch ($ext) {
 case "pdf": $ctype="application/pdf"; break;
 case "exe": $ctype="application/octet-stream"; break;
 case "zip": $ctype="application/zip"; break;
 case "doc": $ctype="application/msword"; break;
 case "xls": $ctype="application/vnd.ms-excel"; break;
 case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
 case "gif": $ctype="image/gif"; break;
 case "png": $ctype="image/png"; break;
 case "jpeg":
 case "jpg": $ctype="image/jpg"; break;
 default: $ctype="application/force-download";
 }

 header("Pragma: public"); // required
 header("Expires: 0");
 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
 header("Cache-Control: private",false); // required for certain browsers
 header("Content-Type: $ctype");
 header("Content-Disposition: attachment; filename=\"".basename($fullPath)."\";" );
 header("Content-Transfer-Encoding: binary");
 header("Content-Length: ".$fsize);
 ob_clean();
 flush();
 readfile( $fullPath );

 } else die('File Not Found');
} 

$filename = str_replace("http://www.domain.de", "", $_GET['filename']);
downloadFile(getcwd().$filename);

?>

Je nachdem wie die Website aufgebaut ist, muss man hier Pfade anpassen.

Kategorien
Symfony

Symfony – Benutzerprofil für sfGuardUser erstellen

Das allseits beliebte Symfony Plugin sfDoctrineGuardPlugin kann leicht um ein beliebig detailreiches Benutzerprofil ergänzt werden. Da die Readme des Plugins nicht mehr auf der Höhe der Zeit ist, möchte ich im Folgenden eine Anleitung geben, wie man das mit Symfony 1.4 und Doctrine macht.

Zunächst definieren wir ein Profil:

# schema.yml
sf_guard_user_profile:
  columns:
    user_id: integer
    photo: varchar(255)
    phone: varchar(20)
  relations:
    type: one
    foreignType: one
    local: user_id
    foreign: id
    onDelete: CASCADE

Durch diese one-to-one Relation kann man von einem sfGuardUser-Objekt auf das Profil folgendermaßen zugreifen:

$profile = $user->getSfGuardUserProfile();
echo $profile->getPhoto(); // liefert das Photo des Profils