par hika - 2005-06-28 22:15:15
crée le 2005-06-28 22:04:40

gallery_engine.inc.php


<?php
/*
 *  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 2 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
/* 
 * Version 0.1
 * This is a gallery object, used to manage image gallery
 * and permission access to directories.
 * This can create thumbnails thanks to the GD library
 *
 */

define('GALLERY_SORT_FILETYPE_ASC', 0x01);
define('GALLERY_SORT_FILETYPE_DESC', 0x02);
define('GALLERY_SORT_FILENAME_ASC', 0x04);
define('GALLERY_SORT_FILENAME_DESC', 0x08);
define('GALLERY_SORT_FILEMTIME_ASC', 0x10);
define('GALLERY_SORT_FILEMTIME_DESC', 0x20);
define('GALLERY_SORT_FILESIZE_ASC', 0x40);
define('GALLERY_SORT_FILESIZE_DESC', 0x80);
 
Class Gallery {
  
  private $Conn;  /* Must be a Connect object */
  private $root_directory;
  private $cache_directory;
  private $use_cache;
  private $parent_folder_name;
  private $filter_filename_regexp;
  private $downloadable_filename_regexp;
  private $sort_type;
  
  private $privileges_table;
  private $current_user;
  
  private $error_msg;
  
  function __construct() {
    $this->Gallery();
  }

  function Gallery() {
  /* ---------------------------------------------------------------------------
   * Constructor
   * ------------------------------------------------------------------------ */
    if ((defined('GALLERY_ROOT'))
    && (is_dir(GALLERY_ROOT)))
      $this->root_directory = GALLERY_ROOT;
    else
      $this->root_directory = NULL;
    
    if ((defined('GALLERY_CACHE_DIR'))
    && (is_dir(GALLERY_CACHE_DIR)))
      $this->cache_directory = GALLERY_CACHE_DIR;
    else
      $this->cache_directory = NULL;
    
    if (defined('GALLERY_USE_CACHE'))
      $this->use_cache = GALLERY_USE_CACHE;
    else
      $this->use_cache = true;
      
    if (defined('GALLERY_PARENT_FOLDER_NAME'))
      $this->parent_folder_name = GALLERY_PARENT_FOLDER_NAME;
    else
      $this->parent_folder_name = NULL;
    
    if (defined('GALLERY_FILTER_FILENAME'))
      $this->filter_filename_regexp = GALLERY_FILTER_FILENAME;
    else
      $this->filter_filename_regexp = NULL;
    
    if (defined('GALLERY_DOWNLOADABLE_FILENAME'))
      $this->downloadable_filename_regexp = GALLERY_DOWNLOADABLE_FILENAME;
    else
      $this->downloadable_filename_regexp = NULL;
      
    if (defined('GALLERY_PRIVILEGE_TABLE'))
      $this->privileges_table = GALLERY_PRIVILEGE_TABLE;
    else
      $this->privileges_table = NULL;
    
    $this->sort_type = NULL;
    $this->Conn = NULL;
    $this->error_msg = array();
  }
  
  function setConnect(&$Conn) {
    if ((is_object($Conn))
    && (get_class($Conn) == "Connect")) {
      $this->Conn = $Conn;
      return true;
    }
    return false;
  }
  
  function setUser($user) {
    $this->current_user = $user;
  }
  
  function setSortType($sort_type) {
    $this->sort_type = $sort_type;
  }
  
  function isConnected() {
    return (is_object($this->Conn))
        && (get_class($this->Conn) == "Connect");
  }
  
  function canGetPrivileges() {
  /* ---------------------------------------------------------------------------
   * PRIVATE
   * Check if privileges can be fetched from SQL database
   *
   * @return boolean
   * ------------------------------------------------------------------------ */
    return ($this->isConnected() && !is_null($this->privileges_table));
  }
  
  function cleanPath($path) {
  /* ---------------------------------------------------------------------------
   * Convert any // to /
   * Also, remove the / at the end, if exists
   *
   * @param  string    a path
   * @return string
   * ------------------------------------------------------------------------ */
    $p = preg_replace("//{2,}/", "/", $path);
    $len = strlen($p);
    if ($len > 0) {
      if ($p{$len-1} == "/")
        $p = substr($p, 0, $len-1);
    }
    if ($p === "")
      $p = "/";
    return $p;
  }
  
  function safePath($path) {
  /* ---------------------------------------------------------------------------
   * Strip any ..
   *
   * @param  string    a path
   * @return string
   * ------------------------------------------------------------------------ */
    return $this->cleanPath(str_replace("..", "", $path));
  }
  
  function safeMkdir($path, $mode = 0700) {
  /* ---------------------------------------------------------------------------
   * Safely create directories recursively
   *
   * @param  string    a path
   * @param  octal     mode
   * @return boolean
   * ------------------------------------------------------------------------ */
    if (is_dir($path))
      return true;
    $p = dirname($path);
    if ($this->safeMkdir($p, $mode)) {
      if (is_writeable($p))
        return mkdir($path, $mode);
      else
        array_push($this->error_msg, "safeMkdir() : " . $p . " is not writeable");
    }
    return false;
  }
  
  function parentPath($path) {
  /* ---------------------------------------------------------------------------
   * PRIVATE 
   * Get the parent directory of a directory
   *
   * @param  string    a path
   * @return string    the parent path or the input path if no parent exists
   * ------------------------------------------------------------------------ */
    $len = strlen($path);
    if ($len == 0)
      return "/";    
    if ($path{$len-1} == "/")
      $p = substr($path, 0, $len-1);
    else
      $p = $path;
      
    $pos = strrpos($p, "/");
    if ($pos !== false)
      $p = substr($p, 0, $pos);
    if ($p === "")
      $p = "/";
    return $p;
  }
  
  function isFiltered($filename) {
  /* ---------------------------------------------------------------------------
   * PRIVATE 
   * Determine if the following filename must filtered or not
   *
   * @param  string    a path
   * @return boolean
   * ------------------------------------------------------------------------ */
    if (is_null($this->filter_filename_regexp)) {
    // Secure by default
      return false;
    }
    else if (!ereg($this->filter_filename_regexp, $filename)) {
      return false;
    }
    return true;
  }
  
  function isDownloadable($filename) {
  /* ---------------------------------------------------------------------------
   * PRIVATE 
   * Determine if the following filename is downloadable or not
   *
   * @param  string    a path
   * @return boolean
   * ------------------------------------------------------------------------ */
    if (is_null($this->downloadable_filename_regexp)) {
    // Secure by default
      return false;
    }
    else if (!ereg($this->downloadable_filename_regexp, $filename)) {
      return false;
    }
    return true;
  }
  
  function isImageFile($full_path) {
  /* ---------------------------------------------------------------------------
   * PRIVATE 
   * Determine if the following file is an image
   *
   * @param  string    a full path
   * @return boolean
   * ------------------------------------------------------------------------ */
    return (file_exists($full_path))
            && (is_file($full_path))
            && (@getimagesize($full_path) !== false);
  }
  
  function getLastErrorMessage() {
  /* --------------------------------------------------------------------------- 
   * Return the last error message
   *
   * @return string
   * ------------------------------------------------------------------------ */
    $nb_error = count($this->error_msg);
    if ($nb_error > 0)
      return $this->error_msg[$nb_error-1];
    return NULL;
  }
  
  function getStackErrorMessage() {
  /* --------------------------------------------------------------------------- 
   * Return the stack errors
   *
   * @return array
   * ------------------------------------------------------------------------ */
    return $this->error_msg; 
  }
  
  function getFolderAccess($relative_folderpath, $username = NULL, $inherit_only = false) {
  /* ---------------------------------------------------------------------------
   * PRIVATE
   * Determine the permission access to the given folder
   *
   * @param  string    the sub folder relative to the root directory
   * @param  string    permission by username (PRIVATE USE ONLY)
   * @param  boolean   get only the folder inherit permission (PRIVATE USE ONLY)
   * @return array or NULL
   * ------------------------------------------------------------------------ */
    if (!$this->canGetPrivileges()) {
      array_push($this->error_msg, "getFolderAccess() : Privileges cannot be fetched. Default to deny.");
      return NULL;
    }
    
    // Remove attempt to open parent directory (..)
    $safe_folderpath = $this->safePath($relative_folderpath);
    
    if (is_null($username)) {
    // Anonymous user
      $sql = "SELECT permit, visible, inherit " .
             "FROM " . $this->privileges_table . " " .
             "WHERE username IS NULL " .
             "AND path = " . STRING_SQL($safe_folderpath) . " " .
             "AND enable = 1 " .
             ($inherit_only ? "AND inherit = 1" : "");
    }
    else {
    // Authenticated user
      $sql = "SELECT permit, visible, inherit " .
             "FROM " . $this->privileges_table . " " .
             "WHERE username = " . STRING_SQL($username) . " " .
             "AND path = " . STRING_SQL($safe_folderpath) . " " .
             "AND enable = 1 " .
             ($inherit_only ? "AND inherit = 1" : "");
    }
    if ($result = $this->Conn->QueryDB($sql)) {
      if ($cur = $this->Conn->CursorDB($result)) {
        $this->Conn->FreeDB($result);
        return $cur;
      }
      else {
        $this->Conn->FreeDB($result);
        $parent_folder = $this->parentPath($relative_folderpath);
        if ($parent_folder !== $relative_folderpath) {
        // Get folder access from parent folder
          return $this->getFolderAccess($parent_folder, $username, true);
        }
      }
    }
    return NULL;
  }
  
  function getVisibleFolders($relative_paths, $username = NULL) {
  /* ---------------------------------------------------------------------------
   * PRIVATE
   * Determine all the visible files and folders 
   *
   * @param  array    sub folders relative to the root directory
   * @param  string   permission by username (PRIVATE USE ONLY)
   * @return array    array of files that can be visible
   * ------------------------------------------------------------------------ */
    return $this->getVisibleOrHiddenFolders($relative_paths, 1, $username);
  }
  
  function getHiddenFolders($relative_paths, $username = NULL) {
  /* ---------------------------------------------------------------------------
   * PRIVATE
   * Determine all the hidden files and folders 
   *
   * @param  array    sub folders relative to the root directory
   * @param  string   permission by username (PRIVATE USE ONLY)
   * @return array    array of files that must be hidden
   * ------------------------------------------------------------------------ */
    return $this->getVisibleOrHiddenFolders($relative_paths, 0, $username);
  }
  
  function getVisibleOrHiddenFolders($relative_paths, $visible, $username = NULL) {
  /* ---------------------------------------------------------------------------
   * PRIVATE
   * Determine all the hidden/visible files and folders 
   *
   * @param  array    sub folders relative to the root directory
   * @param  string   permission by username (PRIVATE USE ONLY)
   * @return array    array of files
   * ------------------------------------------------------------------------ */
    if (!$this->canGetPrivileges()) {
      array_push($this->error_msg, ($visible ? "getVisibleFolders()" : "getHiddenFolders()") . " : " .
                 "Privileges cannot be fetched. Default to deny.");
      return NULL;
    }
        
    $sql_where_path = array();
    foreach ($relative_paths as $path) {
      array_push($sql_where_path, STRING_SQL($this->safePath($path)));
    }
    
    if (is_null($username)) {
    // Anonymous user
      $sql = "SELECT path " .
             "FROM " . $this->privileges_table . " " .
             "WHERE username IS NULL " .
             "AND path IN (" . join(", ", $sql_where_path) . ") " .
             "AND visible = " . $visible . " " .
             "AND enable = 1";
    }
    else {
    // Authenticated user
      $sql = "SELECT path " .
             "FROM " . $this->privileges_table . " " .
             "WHERE username = " . STRING_SQL($username) . " " .
             "AND path IN (" . join(", ", $sql_where_path) . ") " .
             "AND visible = " . $visible . " " .
             "AND enable = 1";
    }
    if ($result = $this->Conn->QueryDB($sql)) {
      $arr_result = array();
      while ($cur = $this->Conn->CursorDB($result)) {
        array_push($arr_result, $cur['path']);
      }
      $this->Conn->FreeDB($result);
      return $arr_result;
    }
    return NULL;
  }
  
  function getElements($relative_folderpath) {
  /* ---------------------------------------------------------------------------
   * Get an array of image fullpath
   *
   * @param  string    the sub folder relative to the root directory
   * @param  boolean   include or not the .. parent folder
   * @return array     images path or NULL
   * ------------------------------------------------------------------------ */
    
    // Remove attempt to open parent directory (..)
    $safe_folderpath = $this->safePath($relative_folderpath);
   
    if (is_null($this->root_directory)) {
      array_push($this->error_msg, "getElements() : Please, set the GALLERY_ROOT constant to a valid folder.");
      return NULL;
    }
    
    if (!is_dir($this->root_directory)) {
      array_push($this->error_msg, "getElements() : GALLERY_ROOT " . $this->root_directory . " is not a valid directory.");
      return NULL;
    }
    
    if (!is_dir($this->root_directory . "/" . $safe_folderpath)) {
      array_push($this->error_msg, "getElements() : " . $safe_folderpath . " is not a valid directory.");
      return NULL;
    }
    
    if (!is_readable($this->root_directory . "/" . $safe_folderpath)) {
      $this->error_msg = "getElements() : " . $safe_folderpath . " is not a readable directory.";
      return NULL;
    }
    
    if (!is_null($this->current_user)) {
    // Authenticated user
      $permission = $this->getFolderAccess($relative_folderpath, $this->current_user);
      if (is_null($permission)) {
      // If no permision has been set for the user, get the permission for guest
        $permission = $this->getFolderAccess($relative_folderpath);
      }
    }
    else
      $permission = $this->getFolderAccess($relative_folderpath);
    
    if (is_null($permission)) {
    // No permission has been set for the given folder
    // Secure by default
      array_push($this->error_msg, "getElements() : No permission has been set for " . $safe_folderpath . " . " .
                         "Default to deny.");
      return NULL;
    }
    if (!$permission['permit']) {
    // This folder has been explicitly denied to the current user
      array_push($this->error_msg, "getElements() : Permission denied to access " . $safe_folderpath . " .");
      return NULL;
    }
    
    $d = opendir($this->root_directory . "/" . $safe_folderpath);
    if ($d === false) {
      array_push($this->error_msg, "getElements() : Failed to open directory " . $safe_folderpath . " .");
      return NULL;
    }
    
    $files = array();
    $folder_paths = array();
    while (($file = readdir($d)) !== false) {
      array_push($files, $file);
      if ($file != "..") {
      // Ignore parent directory
        array_push($folder_paths, $this->cleanPath($safe_folderpath . "/" . $file));
      }
    }
    closedir($d);
    
    // If the current permission is "visible" and "inherit",
    // it means that the current directory content is all visible
    if ((!$permission['visible'])
    || (!$permission['inherit'])) {
      // For each folder, determine only the visible ones
      
      if (!is_null($this->current_user)) {
      // Authenticated user
        $orig_folder_paths = $folder_paths;
        $folder_paths = $this->getVisibleFolders($orig_folder_paths, $this->current_user);
        if ((is_null($folder_paths))
        || (count($folder_paths) <= 0)) {
        // If no visible folders has been set for the user, get the folders for guest
          $folder_paths = $this->getVisibleFolders($orig_folder_paths);
        }
      }
      else
        $folder_paths = $this->getVisibleFolders($folder_paths);
      
      
      if ((is_null($folder_paths))
      || (count($folder_paths) <= 0)) {
        array_push($this->error_msg, "getElements() : No files, nor directories are visible in " . $safe_folderpath . " .");
        return NULL;
      }
    }
    else {
    // However, some folder or file can be explicitly hidden
      if (!is_null($this->current_user)) {
      // Authenticated user
        $hidden_paths = $this->getHiddenFolders($folder_paths, $this->current_user);
        if ((is_null($hidden_paths))
        || (count($hidden_paths) <= 0)) {
        // If no hidden folders has been set for the user, get the folders for guest
          $hidden_paths = $this->getHiddenFolders($folder_paths);
        }
      }
      else
        $hidden_paths = $this->getHiddenFolders($folder_paths);
        
      if ((count($folder_paths) > 0)
      && (count($hidden_paths) > 0)) {
        // Remove the hidden ones
        $folder_paths = array_diff($folder_paths, $hidden_paths);
      }
    }
    
    $arr_result = array();
    foreach ($files as $file) {
      if (($file != ".") && (($file != "..") || $safe_folderpath != "/")) {
        if ($file == "..") {
        // Get the parent directory
          $p = $this->parentPath($safe_folderpath);
          if (is_null($this->parent_folder_name))
            $entry = $file;
          else
            $entry = $this->parent_folder_name;
          
          $ok = true;
        }
        else {
          $p = $this->cleanPath($safe_folderpath . "/" . $file);
          $entry = $file;
          
          // If the given path is visible, ok = true
          // else the file or folder is hidden
          $ok = in_array($p, $folder_paths);
        }
        
        if ($ok) {
        
          $info = @getimagesize($this->root_directory . "/" . $p);
          
          $is_file = is_file($this->root_directory . "/" . $p);
          $is_image = is_file($this->root_directory . "/" . $p)
                      && ($info !== false);
          $is_dir = is_dir($this->root_directory . "/" . $p);
  
          if ($is_image) {
            $width = $info[0];
            $height = $info[1];
          }
          else {
            $width = NULL;
            $height = NULL;
          }
          
          $is_downloadable = true;
          if (!$is_dir && !$is_image) {
          // Check if the file (other than an image) is filtered or not
            $ok = $this->isFiltered($entry);
            $is_downloadable = $this->isDownloadable($entry);
          }
          
          if ($ok) {
            array_push($arr_result, 
              array(
                "fullpath" => $this->cleanPath($this->root_directory . "/" . $p),
                "path" => $this->cleanPath($p),
                "entry" => $entry,
                "filename" => $file,
                "is_file" => $is_file,
                "is_image" => $is_image,
                "width" => $width,
                "height" => $height,
                "is_dir" => $is_dir,
                "is_downloadable" => $is_downloadable,
                "filesize" => filesize($this->root_directory . "/" . $p),
                "filemtime" => filemtime($this->root_directory . "/" . $p),
                "filetype" => filetype($this->root_directory . "/" . $p)
              )
            );
          }
          
        }
        
      }
    }
    
    if ((count($arr_result) > 0)
    && (!is_null($this->sort_type))) {
      if (($this->sort_type & GALLERY_SORT_FILETYPE_ASC)
      || ($this->sort_type & GALLERY_SORT_FILETYPE_DESC)) {
        $arr_sort = array();
        foreach ($arr_result as $result) {  
          array_push($arr_sort, $result["filetype"]);
        }
        if ($this->sort_type & GALLERY_SORT_FILETYPE_ASC)
          array_multisort($arr_sort, SORT_ASC, $arr_result);
        else if ($this->sort_type & GALLERY_SORT_FILETYPE_DESC)
          array_multisort($arr_sort, SORT_DESC, $arr_result);
      }
      if (($this->sort_type & GALLERY_SORT_FILENAME_ASC)
      || ($this->sort_type & GALLERY_SORT_FILENAME_DESC)) {
        $arr_sort = array();
        foreach ($arr_result as $result) {  
          array_push($arr_sort, $result["filename"]);
        }
        if ($this->sort_type & GALLERY_SORT_FILENAME_ASC)
          array_multisort($arr_sort, SORT_ASC, $arr_result);
        else if ($this->sort_type & GALLERY_SORT_FILENAME_DESC)
          array_multisort($arr_sort, SORT_DESC, $arr_result);
      }
      if (($this->sort_type & GALLERY_SORT_FILEMTIME_ASC)
      || ($this->sort_type & GALLERY_SORT_FILEMTIME_DESC)) {
        $arr_sort = array();
        foreach ($arr_result as $result) {  
          array_push($arr_sort, $result["filemtime"]);
        }
        if ($this->sort_type & GALLERY_SORT_FILEMTIME_ASC)
          array_multisort($arr_sort, SORT_ASC, $arr_result);
        else if ($this->sort_type & GALLERY_SORT_FILEMTIME_DESC)
          array_multisort($arr_sort, SORT_DESC, $arr_result);
      }
      if (($this->sort_type & GALLERY_SORT_FILESIZE_ASC)
      || ($this->sort_type & GALLERY_SORT_FILESIZE_DESC)) {
        $arr_sort = array();
        foreach ($arr_result as $result) {  
          array_push($arr_sort, $result["filesize"]);
        }
        if ($this->sort_type & GALLERY_SORT_FILESIZE_ASC)
          array_multisort($arr_sort, SORT_ASC, $arr_result);
        else if ($this->sort_type & GALLERY_SORT_FILESIZE_DESC)
          array_multisort($arr_sort, SORT_DESC, $arr_result);
      }
    }
    
    return $arr_result;
  }
  
  function getThumbnails($relative_folderpath, $width = 0, $height = 0) {
  /* ---------------------------------------------------------------------------
   * Get an array of thumbnail image fullpath
   * if a thumbnail do not exists, it will be created
   *
   * @param  string   the sub folder relative to the root directory
   * @param  int      the new width
   * @param  int      the new height
   * @return array    images path or NULL
   * ------------------------------------------------------------------------ */
    if (is_null($this->cache_directory)) {
      array_push($this->error_msg, "getThumbnails() : Please, set the GALLERY_CACHE_DIR constant to a valid folder.");
      return NULL;
    }
    if (!is_dir($this->cache_directory)) {
      array_push($this->error_msg, "getThumbnails() : GALLERY_CACHE_DIR " . $this->cache_directory . " is not a valid directory.");
      return NULL;
    }
    
    if (($width <= 0) && ($height <= 0)) {
      array_push($this->error_msg, "getThumbnails() : You must define thumbnails by width OR height");
      return NULL;
    }
    if (($width > 0) && ($height > 0)) {
      array_push($this->error_msg, "getThumbnails() : You must define thumbnails by width OR height, not both");
      return NULL;
    }
    
    $elements = $this->getElements($relative_folderpath);
    if (!is_null($elements)) {
      foreach ($elements as $idx => $element) {
        if ($element["is_image"]) {
          
          // First, create directories inside the cache directory
          if ($this->safeMkdir(
                $this->cleanPath(
                  $this->cache_directory . "/" . dirname($element["path"])
                )
              )
          ) {
/*
            $relative_th = dirname($element["path"]) . "/" .
                  "th_" . 
                  ($width > 0 ? $width : "W") ."x" . ($height > 0 ? $height : "H") . "_" .
                  basename($element["fullpath"]);
*/

            $relative_th = $this->generateCacheFilename($element["path"], $width, $height);
            $th = $this->cleanPath($this->cache_directory . "/" . $relative_th);
            $elements[$idx]["th_path"] = $this->cleanPath($relative_th);
            if ((!file_exists($th))
            || (!$this->use_cache)) {
            // Generate a new thumbnail
              if ($this->resizeImage($element["fullpath"], $th, $width, $height)) {
                $elements[$idx]["th_fullpath"] = $th;
                $elements[$idx]["th_filesize"] = filesize($th);
                
                $info = getimagesize($th);
                if ($info !== false) {
                  $elements[$idx]["th_width"] = $info[0];
                  $elements[$idx]["th_height"] = $info[1];
                }
              }
              else {
                array_push($this->error_msg, "getThumbnails() : " . $this->getLastErrorMessage());
                return NULL;
              }
            }
            else {
            // Get the existing thumbnail
              $elements[$idx]["th_fullpath"] = $th;
              $elements[$idx]["th_filesize"] = filesize($th);
              
              $info = @getimagesize($th);
              if ($info !== false) {
                $elements[$idx]["th_width"] = $info[0];
                $elements[$idx]["th_height"] = $info[1];
              }
            }
          }
        }
      }
      reset($elements);
      return $elements;
    }
    
    return NULL;
  }
  
  function getCacheFileInfo($relative_filepath) {
  /* ---------------------------------------------------------------------------
   * Get file information from the root directory
   *
   * @param  string   the file path relative to the root directory
   * @return array or NULL
   * ------------------------------------------------------------------------ */
    if (is_null($this->cache_directory)) {
      array_push($this->error_msg, "getCacheFileInfo() : Please, set the GALLERY_CACHE_DIR constant to a valid folder.");
      return NULL;
    }
    if (!is_dir($this->cache_directory)) {
      array_push($this->error_msg, "getCacheFileInfo() : GALLERY_CACHE_DIR " . $this->cache_directory . " is not a valid directory.");
      return NULL;
    }
    
    $safe_filepath = $this->safePath($relative_filepath);
    
    if (file_exists($this->cache_directory . "/" . $safe_filepath)) {
      
      $is_file = is_file($this->cache_directory . "/" . $safe_filepath);
      $is_image = false;
      $width = NULL;
      $height = NULL;
      
      if ($is_file) {
        $info = @getimagesize($this->cache_directory . "/" . $safe_filepath);
        if ($info !== false) {
          $is_image = true;
          $width = $info[0];
          $height = $info[1];
        }
      }
      
      return array(
                "fullpath" => $this->cleanPath($this->cache_directory . "/" . $safe_filepath),
                "path" => $safe_filepath,
                "filename" => basename($safe_filepath),
                "is_file" => $is_file,
                "is_image" => $is_image,
                "width" => $width,
                "height" => $height,
                "filesize" => filesize($this->cache_directory . "/" . $safe_filepath),
                "filemtime" => filemtime($this->cache_directory . "/" . $safe_filepath),
                "filetype" => filetype($this->cache_directory . "/" . $safe_filepath)
              );
    }
    return NULL;
  }
  
  function getFileInfo($relative_filepath) {
  /* ---------------------------------------------------------------------------
   * Get file information from the root directory
   *
   * @param  string   the file path relative to the root directory
   * @return array or NULL
   * ------------------------------------------------------------------------ */
    if (is_null($this->root_directory)) {
      array_push($this->error_msg, "getFileInfo() : Please, set the GALLERY_ROOT constant to a valid folder.");
      return NULL;
    }
    if (!is_dir($this->root_directory)) {
      array_push($this->error_msg, "getFileInfo() : GALLERY_ROOT " . $this->root_directory . " is not a valid directory.");
      return NULL;
    }
    
    $safe_filepath = $this->safePath($relative_filepath);
    
    if (file_exists($this->root_directory . "/" . $safe_filepath)) {
      
      $is_file = is_file($this->root_directory . "/" . $safe_filepath);
      $is_image = false;
      $width = NULL;
      $height = NULL;
      
      if ($is_file) {
        $info = @getimagesize($this->root_directory . "/" . $safe_filepath);
        if ($info !== false) {
          $is_image = true;
          $width = $info[0];
          $height = $info[1];
        }
      }
      
      return array(
                "fullpath" => $this->cleanPath($this->root_directory . "/" . $safe_filepath),
                "path" => $safe_filepath,
                "filename" => basename($safe_filepath),
                "is_file" => $is_file,
                "is_image" => $is_image,
                "width" => $width,
                "height" => $height,
                "filesize" => filesize($this->root_directory . "/" . $safe_filepath),
                "filemtime" => filemtime($this->root_directory . "/" . $safe_filepath),
                "filetype" => filetype($this->root_directory . "/" . $safe_filepath)
              );
    }
    return NULL;
  }
  
  function generateCacheFile($relative_filepath, $width = 0, $height = 0) {
  /* ---------------------------------------------------------------------------
   * Generate a cache file image from a file in the root directory
   * and get information of the generated file
   *
   * @param  string   the file path relative to the root directory
   * @param  int      the new width
   * @param  int      the new height
   * @return array or NULL
   * ------------------------------------------------------------------------ */
    if (is_null($this->root_directory)) {
      array_push($this->error_msg, "generateCacheFile() : Please, set the GALLERY_ROOT constant to a valid folder.");
      return NULL;
    }
    if (!is_dir($this->root_directory)) {
      array_push($this->error_msg, "generateCacheFile() : GALLERY_ROOT " . $this->root_directory . " is not a valid directory.");
      return NULL;
    }
    if (is_null($this->cache_directory)) {
      array_push($this->error_msg, "generateCacheFile() : Please, set the GALLERY_CACHE_DIR constant to a valid folder.");
      return NULL;
    }
    if (!is_dir($this->cache_directory)) {
      array_push($this->error_msg, "generateCacheFile() : GALLERY_CACHE_DIR " . $this->cache_directory . " is not a valid directory.");
      return NULL;
    }
    if (($width <= 0) && ($height <= 0)) {
      array_push($this->error_msg, "generateCacheFile() : You must define thumbnails by width OR height");
      return NULL;
    }
    if (($width > 0) && ($height > 0)) {
      array_push($this->error_msg, "generateCacheFile() : You must define thumbnails by width OR height, not both");
      return NULL;
    }
    
    $safe_filepath = $this->safePath($relative_filepath);
    
    if ($this->isImageFile($this->root_directory . "/" . $safe_filepath)) {
    
      // First, create directories inside the cache directory
      if ($this->safeMkdir(
            $this->cleanPath(
              $this->cache_directory . "/" . dirname($safe_filepath)
            )
          )
      ) {
        $relative_th = $this->generateCacheFilename($safe_filepath, $width, $height);
        $th = $this->cleanPath($this->cache_directory . "/" . $relative_th);
        
        if ((!file_exists($th))
        || (!$this->use_cache)) {
          if ($this->resizeImage($this->root_directory . "/" . $safe_filepath, $th, $width, $height)) {
            return $this->getCacheFileInfo($relative_th);
          }
          else {
            array_push($this->error_msg, "generateCacheFile() : " . $this->getLastErrorMessage());
            return NULL;
          }
        }
        else {
          return $this->getCacheFileInfo($relative_th);
        }
      }
      
    }
    return NULL;
  }
  
  function generateCacheFilename($relative_filepath, $width = 0, $height = 0) {
  /* ---------------------------------------------------------------------------
   * Simply generate a filename for the cache file
   *
   * @param  string   the file path relative to the root directory
   * @param  int      the new width
   * @param  int      the new height
   * @return boolean
   * ------------------------------------------------------------------------ */
    $safe_filepath = $this->safePath($relative_filepath);
    return dirname($safe_filepath) . "/" .
           "th_" . 
           ($width > 0 ? $width : "W") ."x" . ($height > 0 ? $height : "H") . "_" .
           basename($safe_filepath);
  }
  
  function displayCacheFile($relative_filepath, $bufsize = 1024) {
  /* ---------------------------------------------------------------------------
   * Read and display a file from the cache directory
   *
   * @param  string   the file path relative to the cache directory
   * @param  int      the size of the buffer, default : 1024
   * @return boolean
   * ------------------------------------------------------------------------ */
    if (is_null($this->cache_directory)) {
      array_push($this->error_msg, "displayCacheFile() : Please, set the GALLERY_CACHE_DIR constant to a valid folder.");
      return false;
    }
    if (!is_dir($this->cache_directory)) {
      array_push($this->error_msg, "displayCacheFile() : GALLERY_CACHE_DIR " . $this->cache_directory . " is not a valid directory.");
      return false;
    }
    
    $safe_filepath = $this->safePath($relative_filepath);
    
    // Get permission for the current folder
    $relative_folderpath = $this->parentPath($safe_filepath);
    
    if (!is_null($this->current_user)) {
    // Authenticated user
      $permission = $this->getFolderAccess($relative_folderpath, $this->current_user);
      if (is_null($permission)) {
      // If no permision has been set for the user, get the permission for guest
        $permission = $this->getFolderAccess($relative_folderpath);
      }
    }
    else
      $permission = $this->getFolderAccess($relative_folderpath);
      
    if (is_null($permission)) {
    // No permission has been set for the given folder
    // Secure by default
      array_push($this->error_msg, "displayCacheFile() : No permission has been set for " . $relative_folderpath . " . " .
                         "Default to deny.");
      return false;
    }
    
    if (!$permission['permit']) {
      array_push($this->error_msg, "displayCacheFile() : Permission denied to access " . $safe_filepath . " .");
      return false;
    }
    
    return $this->display($this->cleanPath(
          $this->cache_directory . "/" . $safe_filepath
        ), $bufsize);
  }
  
  function displayFile($relative_filepath, $bufsize = 1024) {
  /* ---------------------------------------------------------------------------
   * Read and display a file
   *
   * @param  string   the file path relative to the root directory
   * @param  int      the size of the buffer, default : 1024
   * @return boolean
   * ------------------------------------------------------------------------ */
    if (is_null($this->root_directory)) {
      array_push($this->error_msg, "displayFile() : Please, set the GALLERY_ROOT constant to a valid folder.");
      return false;
    }
    if (!is_dir($this->root_directory)) {
      array_push($this->error_msg, "displayFile() : GALLERY_ROOT " . $this->root_directory . " is not a valid directory.");
      return false;
    }
    
    $safe_filepath = $this->safePath($relative_filepath);
    
    // Get permission for the current folder
    $relative_folderpath = $this->parentPath($safe_filepath);
    
    if (!is_null($this->current_user)) {
    // Authenticated user
      $permission = $this->getFolderAccess($relative_folderpath, $this->current_user);
      if (is_null($permission)) {
      // If no permision has been set for the user, get the permission for guest
        $permission = $this->getFolderAccess($relative_folderpath);
      }
    }
    else
      $permission = $this->getFolderAccess($relative_folderpath);
      
    if (is_null($permission)) {
    // No permission has been set for the given folder
    // Secure by default
      array_push($this->error_msg, "displayFile() : No permission has been set for " . $relative_folderpath . " . " .
                         "Default to deny.");
      return false;
    }
    if (!$permission['permit']) {
      array_push($this->error_msg, "displayFile() : Permission denied to access " . $safe_filepath . " .");
      return false;
    }
    
    return $this->display($this->cleanPath(
          $this->root_directory . "/" . $safe_filepath
        ), $bufsize);
  }
  
  function display($full_filepath, $bufsize = 1024) {
  /* ---------------------------------------------------------------------------
   * PRIVATE
   * Read and display a file
   *
   * @param  string   the fullpath
   * @param  int      the size of the buffer, default : 1024
   * @return boolean
   * ------------------------------------------------------------------------ */ 
   
    if ((file_exists($full_filepath))
    && (is_file($full_filepath))) {
            
      $fd = fopen($full_filepath, "rb");
      if ($fd === false) {
        array_push($this->error_msg, "display() : Failed to open file " . basename($full_filepath));
        return false;
      }
      
      $info = @getimagesize($full_filepath);
      if ($info === false) {
        
        if (!$this->isDownloadable(basename($full_filepath))) {
          array_push($this->error_msg, "display() : Permission denied to download " . basename($full_filepath));
          return false;
        }
        
        header("Content-Type: application/octet-stream");
        header("Content-Disposition: attachment; filename=\"" . basename($full_filepath) . "\"");
      }
      else {
        switch($info[2]) {
        case 1: // GIF
          header("Content-Type: image/gif");
          header("Content-Disposition: filename=\"" . basename($full_filepath) . "\"");
          break;
        case 2: // JPEG
          header("Content-Type: image/jpeg");
          header("Content-Disposition: filename=\"" . basename($full_filepath) . "\"");
          break;
        case 3: // PNG
          header("Content-Type: image/png");
          header("Content-Disposition: filename=\"" . basename($full_filepath) . "\"");
          break;
        default:
          if (!$this->isDownloadable(basename($full_filepath))) {
            array_push($this->error_msg, "display() : Permission denied to download " . basename($full_filepath));
            return false;
          }
          header("Content-Type: application/octet-stream");
          header("Content-Disposition: attachment; filename=\"" . basename($full_filepath) . "\"");
          break;
        }
      }
      header("Content-Length: " . filesize($full_filepath));
      
      while(!feof($fd)) {
        echo fread($fd, $bufsize); 
      }
      fclose($fd);
      return true;
    }
    return false;
  }
  
  function resizeImage($src_path, $dst_path, $width = 0, $height = 0) {
  /* ---------------------------------------------------------------------------
   * Resize an image by width OR height
   *
   * @param  string   the image source fullpath
   * @param  string   the image destination fullpath
   * @param  int      the new width
   * @param  int      the new height
   * @return boolean
   * ------------------------------------------------------------------------ */
    if (($width <= 0) && ($height <= 0)) {
      array_push($this->error_msg, "resizeImage() : You must define thumbnails by width OR height");
      return false;
    }
    if (($width > 0) && ($height > 0)) {
      array_push($this->error_msg, "resizeImage() : You must resize by width OR height, not both");
      return false;
    }
      
    $info = @getimagesize($src_path);
    if ($info !== false) {
      $w = $info[0];
      $h = $info[1];
      $type = $info[2];
      
      switch($type) {
      case 1: // GIF
        $im_src = imagecreatefromgif($src_path);
        break;
      case 2: // JPEG
        $im_src = imagecreatefromjpeg($src_path);
        break;
      case 3: // PNG
        $im_src = imagecreatefrompng($src_path);
        break;
      default:
        array_push($this->error_msg, "resizeImage() : Unknown image type : " . $type);
        return false;
        break;
      }
      
      if ((isset($im_src))
      && ($im_src !== false)) {
        
        if ($width > 0) {
        // Resize by width
          if ($w == 0) {
            array_push($this->error_msg, "resizeImage() : Image has a width of 0px");
            return false;
          }          
          $ratio = $width / $w;
          $height = $h * $ratio;
        }
        else if ($height > 0) {
        // Resize by height
          if ($h == 0) {
            array_push($this->error_msg, "resizeImage() : Image has a height of 0px");
            return false;
          }          
          $ratio = $height / $h;
          $width = $w * $ratio;
        }
        
        $im_dst = imagecreatetruecolor($width, $height);
        if ($im_dst === false) {
          array_push($this->error_msg, "resizeImage() : Error in imagecreatetruecolor()");
          return false;
        }
        
        if (imagecopyresampled($im_dst, $im_src, 0, 0, 0, 0, $width, $height, $w, $h)) {
          switch($type) {
          case 1:
            imagegif($im_dst, $dst_path);
            break;
          case 2:
            imagejpeg($im_dst, $dst_path);
            break;
          case 3:
            imagepng($im_dst, $dst_path);
            break;
          }
          return true;
        }
        else {
          array_push($this->error_msg, "resizeImage() : Error in imagecopyresampled()");
        }
      }
    }
    else {
      array_push($this->error_msg, "resizeImage() : Invalid image file");
    }
    return false;
  }
  
}
 
?>

par hika - 2005-06-28 22:15:15
crée le 2005-06-28 22:04:40

FreeBSD Mall Smarty Template Engine Page générée le Samedi 26 Avril 2025 14:41:13 Powered by FreeBSD
POWERED BY FreeBSD, Apache, PHP, PostgreSQL, Code & design by Hika
BSD Daemon Copyright 1988 by Marshall Kirk McKusick. All Rights Reserved.