Search:

# CWIS Developers Documentation

- Main Page
- Classes
- Files

- File List
- File Members

# File.php

Go to the documentation of this file.

    00001 <?PHP
    00002
    00003 #
    00004 #   FILE:  File.php
    00005 #
    00006 #   Copyright 2010 Edward Almasy and Internet Scout
    00007 #   http://scout.wisc.edu
    00008 #
    00009
    00010
    00011 class File {
    00012
    00013     # ---- PUBLIC INTERFACE --------------------------------------------------
    00014
    00015     # status codes (set by constructor and returned by File::Status())
    00016     const FILESTAT_OK =             0;
    00017     const FILESTAT_COPYERROR =      1;
    00018     const FILESTAT_PARAMERROR =     2;
    00019     const FILESTAT_ZEROLENGTH =     3;
    00020     const FILESTAT_DOESNOTEXIST =   4;
    00021     const FILESTAT_UNREADABLE =     5;
    00022
    00023     # object constructor
    00024     function File($IdOrFileName, $ResourceId = NULL, $FieldId = NULL,
    00025             $DesiredFileName = NULL, $CheckFileLength = TRUE)
    00026     {
    00027         # assume constructor will succeed
    00028         $this->Status = self::FILESTAT_OK;
    00029
    00030         # get our own database handle
    00031         $DB = new Database();
    00032         $this->DB = $DB;
    00033
    00034         # if ID supplied
    00035         if (is_int($IdOrFileName))
    00036         {
    00037             # set file ID from supplied value
    00038             $this->Id = intval($IdOrFileName);
    00039
    00040             # load file info from database
    00041             $DB->Query("SELECT * FROM Files WHERE FileId = ".$this->Id);
    00042             $this->DBFields = $DB->FetchRow();
    00043         }
    00044         # else if file name and resource ID and field ID supplied
    00045         elseif (strlen($IdOrFileName) && ($ResourceId != NULL) && ($FieldId != NULL))
    00046         {
    00047             # if file does not exist
    00048             $TempFileName = $IdOrFileName;
    00049             if (!file_exists($TempFileName) || !is_readable($TempFileName))
    00050             {
    00051                 # set status indicating appropriate error
    00052                 $this->Status = file_exists($TempFileName)
    00053                         ? self::FILESTAT_DOESNOTEXIST : self::FILESTAT_UNREADABLE;
    00054             }
    00055             else
    00056             {
    00057                 # if we were asked to check file length and file was zero length
    00058                 $FileLength = filesize($TempFileName);
    00059                 if ($CheckFileLength && !$FileLength)
    00060                 {
    00061                     # set status indicating zero length file
    00062                     $this->Status = self::FILESTAT_ZEROLENGTH;
    00063                 }
    00064                 else
    00065                 {
    00066                     # generate secret string (used to protect from unauthorized download)
    00067                     srand((double)microtime() * 1000000);
    00068                     $SecretString = sprintf("%04X", rand(1, 30000));
    00069
    00070                     # attempt to get file type
    00071                     $FileType = "";
    00072                     if (function_exists("finfo_open"))
    00073                     {
    00074                         $FInfoHandle = finfo_open(FILEINFO_MIME);
    00075
    00076                         if ($FInfoHandle)
    00077                         {
    00078                             $FInfoMime = finfo_file($FInfoHandle, $TempFileName);
    00079                             finfo_close($FInfoHandle);
    00080
    00081                             if ($FInfoMime)
    00082                             {
    00083                                 $FileType = $FInfoMime;
    00084                             }
    00085                         }
    00086                     }
    00087                     else if (function_exists("mime_content_type"))
    00088                     {
    00089                         # mime_content_type has been deprecated, but it may be
    00090                         # the only way to get the mimetype for PHP < 5.3
    00091                         $MimeType = mime_content_type($TempFileName);
    00092
    00093                         if ($MimeType)
    00094                         {
    00095                             $FileType = $MimeType;
    00096                         }
    00097                     }
    00098
    00099                     # add file info to database
    00100                     $BaseFileName = $DesiredFileName
    00101                             ? basename($DesiredFileName) : basename($TempFileName);
    00102                     $DB->Query("INSERT INTO Files"
    00103                             ." (ResourceId, FieldId, FileName, FileLength, FileType,"
    00104                                 ." SecretString)"
    00105                             ." VALUES ("
    00106                                 .intval($ResourceId).", "
    00107                                 .intval($FieldId).", "
    00108                                 ."'".addslashes($BaseFileName)."', "
    00109                                 .$FileLength.", "
    00110                                 ."'".$FileType."', "
    00111                                 ."'".$SecretString."')");
    00112
    00113                     # retrieve ID of new file
    00114                     $this->Id = $DB->LastInsertId("Files");
    00115
    00116                     # load file info back in from database
    00117                     $DB->Query("SELECT * FROM Files WHERE FileId = ".$this->Id);
    00118                     $this->DBFields = $DB->FetchRow();
    00119
    00120                     # copy file to storage
    00121                     $CopySucceeded = copy($IdOrFileName, $this->GetNameOfStoredFile());
    00122
    00123                     # if copy failed
    00124                     if (!$CopySucceeded)
    00125                     {
    00126                         # remove file info from database
    00127                         $DB->Query("DELETE FROM Files WHERE FileId = ".$this->Id);
    00128
    00129                         # set status indicating constructor failed
    00130                         $this->Status = self::FILESTAT_COPYERROR;
    00131                     }
    00132                 }
    00133             }
    00134         }
    00135         else
    00136         {
    00137             # set status indicating constructor failed
    00138             $this->Status = self::FILESTAT_PARAMERROR;
    00139         }
    00140     }
    00141
    00142     # return object status (used to report errors occurring in constructor)
    00143     function Status() {  return $this->Status;  }
    00144
    00145     # get various attributes
    00146     function Id() {  return $this->Id;  }
    00147     function Name() {  return $this->DBFields["FileName"];  }
    00148     function GetLength() {  return $this->DBFields["FileLength"];  }
    00149     function GetType() {  return $this->DBFields["FileType"];  }
    00150
    00151     # get/set various attributes
    00152     function Comment($NewValue = DB_NOVALUE)
    00153             {  return $this->UpdateValue("FileComment", $NewValue);  }
    00154     function FieldId($NewValue = DB_NOVALUE)
    00155             {  return $this->UpdateValue("FieldId", $NewValue);  }
    00156     function ResourceId($NewValue = DB_NOVALUE)
    00157             {  return $this->UpdateValue("ResourceId", $NewValue);  }
    00158
    00159     # get MIME type (defaults to "application/octet-stream" if not available)
    00160     function GetMimeType()
    00161     {
    00162         return strlen($this->GetType())
    00163                 ? $this->GetType() : "application/octet-stream";
    00164     }
    00165
    00166     # get link for downloading file
    00167     function GetLink()
    00168     {
    00169         global $AF;
    00170
    00171         # if .htaccess files are supported, use the redirect that includes
    00172         # the file name so that browsers don't use index.php as the name
    00173         # for the downloaded file
    00174         if ($AF->HtaccessSupport())
    00175         {
    00176             return "downloads/".$this->Id."/".rawurlencode($this->Name());
    00177         }
    00178
    00179         # otherwise use the download portal
    00180         else
    00181         {
    00182             return "index.php?P=DownloadFile&Id=".$this->Id;
    00183         }
    00184     }
    00185
    00186     # delete file (other methods are invalid after calling this!)
    00187     function Delete()
    00188     {
    00189         # remove file entry from DB
    00190         $this->DB->Query("DELETE FROM Files WHERE FileId = ".$this->Id);
    00191
    00192         # delete file
    00193         $FileName = $this->GetNameOfStoredFile();
    00194         if (file_exists($FileName))
    00195         {
    00196             unlink($FileName);
    00197         }
    00198     }
    00199
    00200     # retrieve actual name of stored file
    00201     function GetNameOfStoredFile()
    00202     {
    00203         return sprintf("FileStorage/%06d-%s-%s",
    00204                 $this->Id, $this->DBFields["SecretString"], $this->Name());
    00205     }
    00206
    00207
    00208     # ---- PRIVATE INTERFACE -------------------------------------------------
    00209
    00210     private $DB;
    00211     private $Status;
    00212     private $Id;
    00213     private $DBFields;
    00214
    00215     # convenience function to supply parameters to Database->UpdateValue()
    00216     private function UpdateValue($FieldName, $NewValue)
    00217     {
    00218         return $this->DB->UpdateValue("Files", $FieldName, $NewValue,
    00219                                "FileId = ".intval($this->Id),
    00220                                $this->DBFields, TRUE);
    00221     }
    00222 }
    00223
    00224
    00225 ?>