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         return "index.php?P=DownloadFile&Id=".$this->Id;
00170     }
00171 
00172     # delete file (other methods are invalid after calling this!)
00173     function Delete()
00174     {
00175         # remove file entry from DB
00176         $this->DB->Query("DELETE FROM Files WHERE FileId = ".$this->Id);
00177 
00178         # delete file
00179         $FileName = $this->GetNameOfStoredFile();
00180         if (file_exists($FileName))
00181         {
00182             unlink($FileName);
00183         }
00184     }
00185 
00186     # retrieve actual name of stored file
00187     function GetNameOfStoredFile()
00188     {
00189         return sprintf("FileStorage/%06d-%s-%s",
00190                 $this->Id, $this->DBFields["SecretString"], $this->Name());
00191     }
00192 
00193 
00194     # ---- PRIVATE INTERFACE -------------------------------------------------
00195 
00196     private $DB;
00197     private $Status;
00198     private $Id;
00199     private $DBFields;
00200 
00201     # convenience function to supply parameters to Database->UpdateValue()
00202     private function UpdateValue($FieldName, $NewValue)
00203     {
00204         return $this->DB->UpdateValue("Files", $FieldName, $NewValue,
00205                                "FileId = ".intval($this->Id),
00206                                $this->DBFields, TRUE);
00207     }
00208 }
00209 
00210 
00211 ?>

CWIS logo doxygen
Copyright 2010 Internet Scout