Tag: custom directory listing

  • Custom Apache Directory Listing using PHP

    Custom Apache Directory Listing using PHP

    This snippet overrides Apache’s default presentation of folder contents.

    /**
     * CustomDirectoryListing
     *
     * A simple script for custom directory listing. Adds support for
     * - maximum amount of items per row
     * - image listing with automatic resizing
     * - displaying images before other file types for a prettier layout
     *
     * The above options can be controlled via the corresponding $_GET variables,
     * @see below.
     *
     * USAGE
     * Simply put this file into the directory you want to be listed. You might want
     * to set the defaultWidth and defaultHeight, as well as maxItemsPerRow to your
     * needs.
     *
     * @author Matthias Kerstner info@kerstner.at
     * @copyright Matthias Kerstner info@kerstner.at
     * @version 1.0
     *
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
    
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
    
     * You should have received a copy of the GNU General Public License
     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    
    mb_internal_encoding('UTF-8');
    mb_regex_encoding('UTF-8');
    
    $maxItemsPerRow = (isset($_GET['maxItemsPerRow']) && (int)$_GET['maxItemsPerRow'] > 0)
            ? (int)$_GET['maxItemsPerRow']-1 : 4;
    $defaultWidth = (isset($_GET['defaultWidth']) && (int)$_GET['defaultWidth'] > 0)
            ? (int)$_GET['defaultWidth'] : 150;
    $defaultHeight = (isset($_GET['defaultHeight']) && (int)$_GET['defaultHeight'] > 0)
            ? (int)$_GET['defaultHeight'] : 100;
    $imagesFirst = isset($_GET['imagesFirst']);
    
    /**
     * Calculates resized size based on $dstHeight and $dstWidth by maintaining the
     * original width-height-ratio. Checks which dimension is greater and sets it to
     * a fixed value specified. The remaining dimension is resized using the
     * original ratio to the other dimension's new fixed value.
     * @param <string> $srcFile
     * @param <int> $dstHeight
     * @param <int> $dstWidth
     * @return <array> [0]=width, [1]=height
     */
    function getResizeSize($srcFile, $dstHeight, $dstWidth) {
    
        $srcFileInfo = getimagesize($srcFile); //[0]=width,[1]=height
    
        if(empty($srcFileInfo))
            throw new Exception('Failed to read image fileinfo.');
    
        if($srcFileInfo[0] <= (int)$dstWidth &&
                $srcFileInfo[1] <= (int)$dstHeight) {
            return array($srcFileInfo[0], $srcFileInfo[1]); //nothing to do
        }
    
        $newSize = array();
    
        if($srcFileInfo[0] >= $srcFileInfo[1]) { //calculate new dimensions while keeping current ratio
            $newSize[0] = $dstWidth;
            $newSize[1] = ($srcFileInfo[1]/$srcFileInfo[0]) * $dstWidth;
        } else {
            $newSize[0] = ($srcFileInfo[0]/$srcFileInfo[1]) * $dstHeight;
            $newSize[1] = $dstHeight;
        }
    
        return $newSize;
    }
    
    ?>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <title>Custom Directory Listing</title>
            <style type="text/css">
                html {
                    font-family: Courier, Verdana, sans-serif;
                    font-size: 9pt;
                    border: 0;
                }
            </style>
        </head>
        <body>
    
            <?php
    
            try {
    
                $handle = opendir('.');
                $file = null;
    
                if(!$handle)
                    throw new Exception('Failed to read directory.');
    
                $nonImageItems = array();
                $itemPerRowCount = 0;
    
                while(false !== ($file = readdir($handle))) {
    
                    if($itemPerRowCount >= $maxItemsPerRow) {
                        echo '<br/>';
                        $itemPerRowCount = 0;
                    }
    
                    if($file !== "." && $file !== "..") {
    
                        if(mb_eregi('.jpg$', $file) === 1) { //image
    
                            $filesize = getResizeSize($file, $defaultWidth, $defaultHeight);
    
                            echo '<a href="'.$file.'">'.
                                    '<img src="'.$file.'" width="'.$filesize[0].'" '.
                                    'height="'.$filesize[1].'" alt="'.$file.'" '.
                                    'border="0"/>'.
                                    '</a>&nbsp;&nbsp;';
    
                            $itemPerRowCount++;
                        } else {
                            if($imagesFirst)
                                $nonImageItems[] = $file;
                            else {
                                echo '<a href="'.$file.'">'.$file.'</a>&nbsp;&nbsp;';
                                $itemPerRowCount++;
                            }
                        }
                    }
                }
    
                closedir($handle);
    
                $itemPerRowCount = 0;
    
                foreach($nonImageItems as $v) { //display non-image files afterwards
                    if($itemPerRowCount >= $maxItemsPerRow) {
                        echo '<br/>';
                        $itemPerRowCount = 0;
                    }
    
                    echo '<a href="'.$v.'">'.$v.'</a>&nbsp;&nbsp;';
    
                    $itemPerRowCount++;
                }
    
            } catch(Exception $e) {
                echo 'Sorry an error occurred: '.$e->getMessage();
            }
    
            ?>
    
        </body>
    </html>