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