justinmassiot
9/11/2015 - 6:03 PM

[2010 - Sono SGDF] MODx photo album

MODx snippet to show a photo album with the integration of HighslideJS for beautiful navigation.

<?php
// example use: [!HighSlide4? &lang=`fr` &CBposition=`bottom center` &outline=`rounded-white` &timePerPix=`5` &fadeDuration=`0.8` &repeat=`false`!]

/******************************************************************************
Highslide for MODx

Version 4.0.10 (November 25 2008)
Adapted for MODx CMF by Just1 ( 28 / 09 / 2010 )

Author:  Torstein Hønsi
Support: http://vikjavev.no/highslide/forum
Email:   See http://highslide.com/

Licence:
Highslide JS is licensed under a Creative Commons Attribution-NonCommercial 2.5
License (http://creativecommons.org/licenses/by-nc/2.5/).

You are free:
    * to copy, distribute, display, and perform the work
    * to make derivative works

Under the following conditions:
    * Attribution. You must attribute the work in the manner  specified by  the
      author or licensor.
    * Noncommercial. You may not use this work for commercial purposes.

* For  any  reuse  or  distribution, you  must make clear to others the license
  terms of this work.
* Any  of  these  conditions  can  be  waived  if  you  get permission from the 
  copyright holder.

Your fair use and other rights are in no way affected by the above.

******************************************************************************/



// ######################################## //
// Snippet hard config

$siteName = $modx->config['site_name'];

//This is using the gallery .js file
$modx->regClientStartupScript("assets_/snippets/highslide4/highslide-with-gallery.js");
//This is using the standard .css file
$modx->regClientCSS("assets_/snippets/highslide4/highslide.css");
//This will set the folder for the outline images
$graphicsDir = "assets_/snippets/highslide4/graphics/";
// subfolders : tumbnails and fullsize images
$thumbsDir  = "thumbs";
$filesDir   = "fullsize";

// end of snippet hard config
// ######################################## //



// ######################################## //
// Snippet call options.

// ******************** //
// Folders configuration
// ********** //
// gallery images folder (to select a subfolder)
// base galleries directory
$baseDir = (isset($baseDir))? $baseDir : "assets_/galleries/";
if (substr($baseDir, strlen($baseDir)-1, strlen($baseDir)) != '/') $baseDir .= '/';
// subfolder to explore
if (!empty($_GET["folder"]) and !ereg("\.", $_GET["folder"])) $subfolder = $_GET["folder"].'/';
else if (!empty($subfolder)) $subfolder = $subfolder.'/';
// ******************** //

// ******************** //
// Highslide configuration
// ********** //
// left margin for the fullsize image.
$Lmargin = isset($Lmargin)? $Lmargin : 15;
// right margin for the fullsize image.
$Rmargin = isset($Rmargin)? $Rmargin : 15;
// top margin for the fullsize image.
$Tmargin = isset($Tmargin)? $Tmargin : 15;
// bottom margin for the fullsize image.
$Bmargin = isset($Bmargin)? $Bmargin : 15;
// popup position in the user window
$popupPosition = isset($popupPosition)? $popupPosition : "center";
// position for the control bar on the fullsize image. Options are top/bottom & left/right.
$CBposition = isset($CBposition)? $CBposition : "bottom center";
// outline effect for the fullsize image. Options are beveled, drop-shadow (default), outer-glow & rounded-white.
$outline = isset($outline)? $outline : "rounded-white";
// wrapperClassName ; options are "highslide-wrapper" (default), "controls-in-heading", ??
$wrapperClass = isset($wrapperClass)? $wrapperClass : "highslide-wrapper";
// automatically hide controls on mouse out
$automaticControlsHide = isset($automaticControlsHide)? $automaticControlsHide : "true";
// defines if transitions must be fade in / fade out
$withFade = isset($withFade)? $withFade : "true";
// time per picture
$timePerPix = isset($timePerPix)? $timePerPix : "5";
// transition duration
$fadeDuration = isset($fadeDuration)? $fadeDuration : "0.5";
// reading in loop
$repeat = isset($repeat)? $repeat : "false";
// specific album alignement
$albumStyle = isset($align)? " style=\"text-align: ".$align.";\"" : "";
// ******************** //

// ******************** //
// Language configurations
// ********** //
if ($lang == "fr") {
    // "or" word
    $lang_or = "ou";
    // error message : the folder does not exist
    $lang_doesnotExist = "n'existe pas";
    // error message : impossible to open
    $lang_impossibleToOpen = "est impossible à ouvrir";
    // link to go to parent folder
    $lang_parentFolder = "dossier parent";
    // root folder
    $lang_rootFolder = "racine des images";
    // back to root
    $lang_backToRootFolder = "Retour à la racine des images";
    // message in order to view some images
    $lang_chooseGallery = "Naviguez dans les dossiers pour afficher le contenu d'un album.";
    $lang_chooseGalleryRootFolder = "Vous êtes à la racine des images.<br />Déplacez vous dans un dossier pour en voir le contenu.";
    // title in help popup on image mousehover
    $lang_imageTitle = "cliquer pour agrandir";
    // global copyright to inform pictures are property of their owner(s)
    $lang_globalCopyright = "Les images affichées restent la propriété de leur auteur respectif et ne sont aucunement libres de droits.<br />Merci de ne pas réutiliser ces images sans accord préalable.";
    
    // Highslide specific text
    $lang_HS_cssDirection = "ltr";
    $lang_HS_loadingText = "Chargement...";
    $lang_HS_loadingTitle = "Cliquer pour annuler";
    $lang_HS_focusTitle = "Cliquer pour afficher";
    $lang_HS_fullExpandText = "Taille réelle";
    $lang_HS_fullExpandTitle = "Taille réelle (f)";
    $lang_HS_nextText = "Suivante";
    $lang_HS_previousTitle = "Précédente (flèche gauche)";
    $lang_HS_nextTitle = "Suivante (flèche droite)";
    $lang_HS_moveText = "Déplacer";
    $lang_HS_moveTitle = "Déplacer";
    $lang_HS_closeText = "Fermer";
    $lang_HS_closeTitle = "Fermer (Echap)"; 
    $lang_HS_resizeTitle = "Redimensionner";
    $lang_HS_playText = "Lecture";
    $lang_HS_playTitle = "Lire le diaporama (espace)";
    $lang_HS_pauseText = "Pause";
    $lang_HS_pauseTitle = "Mettre en pause (espace)";
    $lang_HS_number = "Image %1 sur %2";
    $lang_HS_restoreTitle = "Cliquer pour fermer, cliquer-déplacer pour déplacer. Utiliser les flèches pour aller à la suivante/précédente.";
    $lang_HS_creditsText = "Highslide JS";
    $lang_HS_creditsTitle = "Site web d\'Highslide JS";
}
else {
    // "or" word
    $lang_or = "or";
    // error message : the folder does not exist
    $lang_doesnotExist = "does not exist";
    // error message : impossible to open
    $lang_impossibleToOpen = "cannot be open";
    // link to go to parent folder
    $lang_parentFolder = "parent folder";
    // root folder
    $lang_rootFolder = "gallery root";
    // back to root
    $lang_backToRootFolder = "Back to images root folder";
    // message in order to view some images
    $lang_chooseGallery = "Please choose one of available folders to view its content.";
    $lang_chooseGalleryRootFolder = "You are in root folder.<br />Move to an other directory to see its content.";
    // title in help popup on image mousehover
    $lang_imageTitle = "click to enlarge";
    // global copyright to inform pictures are property of their owner(s)
    $lang_globalCopyright = "These pictures stay property of their respective author and owner, and are not free to copy.";
    
    // Highslide specific text
    $lang_HS_cssDirection = "ltr";
    $lang_HS_loadingText = "Loading...";
    $lang_HS_loadingTitle = "Click to cancel";
    $lang_HS_focusTitle = "Click to bring to front";
    $lang_HS_fullExpandTitle = "Expand to actual size (f)";
    $lang_HS_creditsText = "Powered by Highslide JS";
    $lang_HS_creditsTitle = "Go to the Highslide JS homepage";
    $lang_HS_nextText = "Next"; 
    $lang_HS_moveText = "Move";
    $lang_HS_closeText = "Close";
    $lang_HS_closeTitle = "Close (esc)"; 
    $lang_HS_resizeTitle = "Resize";
    $lang_HS_playText = "Play";
    $lang_HS_playTitle = "Play slideshow (spacebar)";
    $lang_HS_pauseText = "Pause";
    $lang_HS_pauseTitle = "Pause slideshow (spacebar)";
    $lang_HS_previousTitle = "Previous (arrow left)";
    $lang_HS_nextTitle = "Next (arrow right)";
    $lang_HS_moveTitle = "Move";
    $lang_HS_fullExpandText = "Full size";
    $lang_HS_number = "Image %1 of %2";
    $lang_HS_restoreTitle = "Click to close image, click and drag to move. Use arrow keys for next and previous.";
}
// ******************** //

// end of snippet call options.
// ######################################## //




/******************************************************************************
**                 You DON'T need to edit below this line !                  **
******************************************************************************/

// ######################################## //
// SNIPPET CORE
// ########## //

$HighSlide_output = ""; // initialization of output string

// script settings that override those are defined in the "*.js" file
$HighSlide_output .= "
<script type=\"text/javascript\">
    hs.graphicsDir = '$graphicsDir';
    hs.align = '$popupPosition';
    hs.transitions = ['expand', 'crossfade'];
    hs.outlineType = '$outline';
    hs.wrapperClassName = '$wrapperClass';
    hs.fadeInOut = $withFade;
    hs.dimmingOpacity = 0.75;
    hs.transitionDuration = $fadeDuration*1000;
    hs.marginLeft = $Lmargin;
    hs.marginRight = $Rmargin;
    hs.marginTop = $Tmargin;
    hs.marginBottom = $Bmargin;
    
    // language variables
    hs.lang.cssDirection = '$lang_HS_cssDirection';
    hs.lang.loadingText = '$lang_HS_loadingText';
    hs.lang.loadingTitle = '$lang_HS_loadingTitle';
    hs.lang.focusTitle = '$lang_HS_focusTitle';
    hs.lang.fullExpandTitle = '$lang_HS_fullExpandTitle';
    hs.lang.creditsText = '$lang_HS_creditsText';
    hs.lang.creditsTitle = '$lang_HS_creditsTitle';
    hs.lang.restoreTitle = '$lang_HS_restoreTitle';
    hs.nextText = '$lang_HS_nextText';
    hs.moveText = '$lang_HS_moveText';
    hs.closeText = '$lang_HS_closeText'; 
    hs.closeTitle = '$lang_HS_closeTitle'; 
    hs.resizeTitle = '$lang_HS_resizeTitle';
    hs.playText = '$lang_HS_playText';
    hs.playTitle = '$lang_HS_playTitle';
    hs.pauseText = '$lang_HS_pauseText';
    hs.pauseTitle = '$lang_HS_pauseTitle';
    hs.previousTitle = '$lang_HS_previousTitle';
    hs.nextTitle = '$lang_HS_nextTitle';
    hs.moveTitle = '$lang_HS_moveTitle';
    hs.fullExpandText = '$lang_HS_fullExpandText';
    hs.number = '$lang_HS_number';
    
    // Add the controlbar
    if (hs.addSlideshow) hs.addSlideshow({
        //slideshowGroup: 'group1',
        interval: $timePerPix*1000,
        repeat: $repeat,
        useControls: true,
        fixedControls: 'fit',
        overlayOptions: {
            opacity: .75,
            position: '$CBposition',
            hideOnMouseOut: $automaticControlsHide
        }
    });
</script>
";


function exifdate_sort($imgA, $imgB) {
    $exifA = @exif_read_data($imgA, 0, true);
    $exifB = @exif_read_data($imgB, 0, true);
    if ( $exifA !== false and $exifB !== false
                and !empty($exifA["EXIF"]["DateTimeOriginal"])
                and !empty($exifB["EXIF"]["DateTimeOriginal"]) ) {
        return strcasecmp( $exifA["EXIF"]["DateTimeOriginal"] , $exifB["EXIF"]["DateTimeOriginal"] );
    }
    else
        return strcasecmp($imgA,$imgB);
}


// logical gallery construction
$getVars = "?";
if (strpos($_SERVER["REQUEST_URI"], '?')) {
    $linkVars = $_GET;
    if (array_key_exists("q", $linkVars)) unset($linkVars["q"]);
    if (array_key_exists("folder", $linkVars)) unset($linkVars["folder"]);
    if (array_key_exists("action", $linkVars)) unset($linkVars["action"]);
    if (array_key_exists("focus", $linkVars)) unset($linkVars["focus"]);
    if (count($linkVars) > 1) {
        $firstVar = each($linkVars);
        $getVars .= $firstVar["key"]."=".$firstVar["value"];
        foreach ($linkVars as $key => $value) {
            $getVars .= "&amp;".$key."=".$value;
        }
    } else if (count($linkVars) == 1) {
        $firstVar = each($linkVars);
        $getVars .= $firstVar["key"]."=".$firstVar["value"];
    }
    if ($getVars != "?") $getVars .= "&amp;";
}

if ($handle = @opendir($baseDir.$subfolder)) {
    $HighSlide_output .= "\n<div class=\"highslide-album-content\">\n";
    
    $folderContent = array(
        "dirs" => array(),
        "imgs" => array(),
    );
    chdir($baseDir.$subfolder);

    // ******************** //
    // folders tree building
    // ********** //
    // first loop on the folder content
    while (false !== ($content = readdir($handle))) {
        if (is_dir($content) and $content != "." and $content != ".." and $content != ".htaccess") {
            if ($content == $filesDir) { // gallery found !
                if ($handleGallery = @opendir($content)) {
                    chdir($content);
                    
                    // second loop on each gallery content
                    while (false !== ($galleryContent = readdir($handleGallery))) {
                        if ($galleryContent != "." and $galleryContent != ".." and $galleryContent != ".htaccess") {
                            if (is_file($galleryContent)) {
                                $folderContent["imgs"][] = $galleryContent;
                            }
                        }
                    } // end while
                    
                    chdir(".."); // go to $content's parent
                }
                else { $HighSlide_output .= "\"".$content."\" : ".$lang_impossibleToOpen."<br />\n"; }
            }
            else if ($content != $thumbsDir) { // gallery does not exist in this folder
                $folderContent["dirs"][$content] = $content; // get the folder name
            }
        }
        else if ($content == ".." and is_dir($content) and !empty($subfolder)) { // link to parent, if we are in a subfolder
            $folderContent["dirs"][$content] = $lang_parentFolder;
        }
        // if !is_dir() => it's a file, so cannot be a gallery
    } // end while
    
    // tri de l'arborescence des dossiers
    if (array_key_exists("..", $folderContent["dirs"]))
        asort($folderContent["dirs"]); // tri classique
    else
        arsort($folderContent["dirs"]); // trie en ordre inverse (pour les années)
    
    // tri des images
    if ( is_dir($filesDir) ) {
        chdir($filesDir);
        usort($folderContent["imgs"], "exifdate_sort");
        chdir("..");
    }
    
//    echo "arborescence: "; print_r($folderContent);
    // ******************** //

    // ******************** //
    // navigation links
    // ********** //
    if (count($folderContent["dirs"]) != 0 or array_key_exists("..", $folderContent["dirs"])) {
        $HighSlide_output .= "\n<div class=\"highslide-folder-navigation\">\n<ul>\n";

        if (array_key_exists("..", $folderContent["dirs"])) {
            $folder = substr( $subfolder, 0, strrpos(substr($subfolder, 0, strlen($subfolder)-1), '/') );
            $folder = $getVars."folder=".urlencode($folder)."&amp;action=".urlencode($_GET["action"]);
// <ul class="highslide-parent-folder-link">
            $HighSlide_output .= '<li class="highslide-parent-folder-link"><a href="[~'.$modx->documentObject["id"].'~]'.$folder.'">'.$folderContent["dirs"][".."].'</a></li>'."\n";
            unset($folderContent["dirs"][".."]);
        }

        if (count($folderContent["dirs"]) != 0) {
            foreach ($folderContent["dirs"] as $dir => $name) {
                $HighSlide_output .= '<li><a href="[~'.$modx->documentObject["id"].'~]'.$getVars.'folder='.urlencode($subfolder.$dir).'&amp;action='.urlencode($_GET["action"]).'">'.$name.'</a></li>'."\n";
            }
        }

        $HighSlide_output .= "</ul>\n</div>\n\n";

        $HighSlide_output .= (!empty($subfolder))? '<h3 class="highslide-album-title">'.substr($subfolder, 0, strlen($subfolder)-1)."</h3>\n" : "";
    }
    // ******************** //

    // ******************** //
    // printing of gallery
    // ********** //
    if (count($folderContent["imgs"]) != 0) {
        $HighSlide_output .= '
        <div class="highslide-gallery"' . $albumStyle . '>
        ';
        foreach ($folderContent["imgs"] as $curFile) {
            $exif = @exif_read_data($filesDir.'/'.$curFile, 0, true);
            if ($exif !== false) {
                if ( isset($exif["IFD0"]) ) $ifd = $exif["IFD0"]; // EXIF file description
                if ( isset($exif["WINXP"]) ) $ixp = $exif["WINXP"]; // Windows XP file data
                $hexZero = chr(0);
                //
                $imageCaption = "";
                $imageCaption .= isset($exif["FILE"]["FileName"])? utf8_decode($exif["FILE"]["FileName"]) : utf8_decode($curFile); // image file name
                // Picture date
                if ( isset($exif["EXIF"]["DateTimeOriginal"]) ) {
                    $aDatetime = explode(' ', $exif["EXIF"]["DateTimeOriginal"]);
                    $aDate = explode(':', $aDatetime[0]);
                    $aDatetime[0] = $aDate[2].'/'.$aDate[1].'/'.$aDate[0];
                    $imageCaption .= " - ".implode(' ', $aDatetime);
                }
                $imageCaption .= isset($ifd["Model"])? " (".$ifd["Model"].")" : ""; // camera model
                // Image description
                if ( isset($ixp) ) {
                    // Title
                    if ( !empty($ixp["Title"]) and $ixp["Title"] != ' ' )
                        $imageCaption .= "<br />\n<strong>" . $ixp["Title"] . "</strong>";
                    // Comments
                    if ( !empty($ixp["Comments"]) and $ixp["Comments"] != ' ' )
                        $imageCaption .= "<br />\n<span style=\"font-style: italic\">" . $ixp["Comments"] . "</span>";
                }
                else if ( isset($ifd) ) {
                    // ImageDescription, or Title
                    if ( !empty($ifd["ImageDescription"]) and $ifd["ImageDescription"] != ' ' )
                        $imageCaption .= "<br />\n<strong>" . $ifd["ImageDescription"] . "</strong>";
                    else if ( !empty($ifd["Title"]) and $ifd["Title"] != ' ' )
                        $imageCaption .= "<br />\n<strong>" . str_replace($hexZero, '', $ifd["Title"]) . "</strong>";
                    // Comments
                    if ( !empty($ifd["Comments"]) and $ifd["Comments"] != ' ' )
                        $imageCaption .= "<br />\n<span style=\"font-style: italic\">" . str_replace($hexZero, '', $ifd["Comments"]) . "</span>";
                }
                $imageCaption .= "<div>\n";
                // Author
                if ( isset($ixp) ) {
                    // Author
                    /* affichage de l'auteur désactivé pour éviter l'association entre la photo et le nom de son auteur dans les moteurs de recherche
                    if ( !empty($ixp["Author"]) and $ixp["Author"] != ' ' )
                        $imageCaption .= "<span style=\"color: gray;\">Photographe : " . $ixp["Author"] . "</span>";
                    */
                }
                else if ( isset($ifd) ) {
                    // Artist, or Author
                    if ( !empty($ifd["Artist"]) and $ifd["Artist"] != ' ' )
                        $imageCaption .= "<span style=\"color: gray;\">Photographie : " . $ifd["Artist"] . "</span>";
                    else if ( !empty($ifd["Author"]) and $ifd["Author"] != ' ' )
                        $imageCaption .= "<span style=\"color: gray;\">Photographie : " . str_replace($hexZero, '', $ifd["Author"]) . "</span>";
                }
                // Copyright
                if ( isset($exif["COMPUTED"]["Copyright"]) )
                    $imageCaption .= "<span style=\"color: gray;\"> &copy;".$exif["COMPUTED"]["Copyright"]."</span>";
                //
                $imageCaption .= "\n</div>\n";
                //
                $imageCaption = utf8_encode($imageCaption); // to support ISO encoded files on server
            }
            else { $imageCaption = $curFile; }
            $HighSlide_output .= '
            <a href="'.$baseDir.$subfolder.$filesDir.'/'.$curFile.'" class="highslide" onclick="return hs.expand(this);">
                <img src="'.$baseDir.$subfolder.$thumbsDir.'/'.$curFile.'" alt="Highslide JS - '.$curFile.'"
                    title="'.$lang_imageTitle.' - '.$curFile.'" id="'.$curFile.'" />
            </a>
            <div class="highslide-caption">
            '.$imageCaption.'
            </div>
            ';
        }
        $HighSlide_output .= '
        </div>
        ';
    }
    else {
        if (empty($_GET["folder"])) {
            $HighSlide_output .= "<h3 class=\"highslide-album-title\">".$lang_rootFolder."</h3>\n";
            $HighSlide_output .= '<p style="text-align: center;">';
            $HighSlide_output .= '<br />'.$lang_chooseGalleryRootFolder.'</p>';
        }
        else {
            $HighSlide_output .= '<p style="text-align: center;">';
            $HighSlide_output .= '<br />'.$lang_chooseGallery.'</p>';
        }
    }
    // ******************** //

    $HighSlide_output .= "<div class=\"globalCopyright\">".$lang_globalCopyright."</div>\n";
    
    chdir(".."); // go to $baseDir.$subfolder's parent
    
    $HighSlide_output .= "\n</div>\n<!-- end Highslide album content -->\n";

    // ouverture automatique de l'image par clic sur un lien externe
    $HighSlide_output .= '
    <script type="text/javascript">
    <!--
    hs.expand( document.getElementById( "' . $_GET["focus"] . '" ).parentNode );
    //-->
    </script>';
}
else if ($baseDir != '/') { $HighSlide_output .= "\"".$baseDir.$subfolder."\" : ".$lang_doesnotExist." ".$lang_or." ".$lang_impossibleToOpen."<br /><a href=\"[~".$modx->documentObject["id"]."~]".$getVars."action=".$_GET["action"]."\">".$lang_backToRootFolder."</a>\n"; }
// else : l'utilisateur cherche simplement a inclure les elements necessaires au fonctionnement de HighslideJS
// ******************** //

// end of snippet core
// ######################################## //

return $HighSlide_output;
?>