5 # Part of the Collection Workflow Integration System (CWIS) 6 # Copyright 2010-2013 Edward Almasy and Internet Scout Research Group 7 # http://scout.wisc.edu/cwis/ 16 # ---- PUBLIC INTERFACE -------------------------------------------------- 18 # status codes (set by constructor and returned by File::Status()) 39 public function __construct($IdOrFileName, $ResourceId = NULL, $FieldId = NULL,
40 $DesiredFileName = NULL, $CheckFileLength = TRUE)
42 # assume constructor will succeed 43 $this->
Status = self::FILESTAT_OK;
45 # get our own database handle 50 if (is_numeric($IdOrFileName))
52 # set file ID from supplied value 53 $this->
Id = intval($IdOrFileName);
55 # load file info from database 56 $DB->Query(
"SELECT * FROM Files WHERE FileId = ".$this->
Id);
57 $this->DBFields = $DB->FetchRow();
59 # if the image wasn't found in the database 60 if (!$DB->NumRowsSelected())
62 $this->
Status = self::FILESTAT_DOESNOTEXIST;
65 # else if file name and resource ID and field ID supplied 66 elseif (strlen($IdOrFileName) && ($ResourceId != NULL) && ($FieldId != NULL))
68 # if file does not exist 69 $TempFileName = $IdOrFileName;
70 if (!file_exists($TempFileName) || !is_readable($TempFileName))
72 # set status indicating appropriate error 73 $this->
Status = file_exists($TempFileName)
74 ? self::FILESTAT_DOESNOTEXIST : self::FILESTAT_UNREADABLE;
78 # if we were asked to check file length and file was zero length 79 $FileLength = filesize($TempFileName);
80 if ($CheckFileLength && !$FileLength)
82 # set status indicating zero length file 83 $this->
Status = self::FILESTAT_ZEROLENGTH;
87 # generate secret string (used to protect from unauthorized download) 88 srand((
double)microtime() * 1000000);
89 $SecretString = sprintf(
"%04X", rand(1, 30000));
91 # attempt to get file type 93 if (function_exists(
"finfo_open"))
95 $FInfoHandle = finfo_open(FILEINFO_MIME);
99 $FInfoMime = finfo_file($FInfoHandle, $TempFileName);
100 finfo_close($FInfoHandle);
104 $FileType = $FInfoMime;
108 else if (function_exists(
"mime_content_type"))
110 # mime_content_type has been deprecated, but it may be 111 # the only way to get the mimetype for PHP < 5.3 112 $MimeType = mime_content_type($TempFileName);
116 $FileType = $MimeType;
120 # handle Office XML formats 121 # These are recognized by PHP as zip files (because they are), but 122 # IE (and maybe other things?) need a special-snowflake MIME type to 123 # handle them properly. 124 # For a list of the required types, see 125 # https://technet.microsoft.com/en-us/library/ee309278(office.12).aspx 126 if ($FileType ==
"application/zip; charset=binary")
128 $MstfPrefix =
"application/vnd.openxmlformats-officedocument";
130 $FileNameForExt = is_null($DesiredFileName) ?
131 $TempFileName : $DesiredFileName ;
133 $FileExt = strtolower(pathinfo(
134 $FileNameForExt, PATHINFO_EXTENSION));
139 $FileType = $MstfPrefix.
".wordprocessingml.document";
143 $FileType = $MsftPrefix.
".spreadsheetml.sheet";
147 $FileType = $MsftPrefix.
".presentationml.slideshow";
155 # add file info to database 156 $BaseFileName = $DesiredFileName
157 ? basename($DesiredFileName) : basename($TempFileName);
158 $DB->Query(
"INSERT INTO Files" 159 .
" (ResourceId, FieldId, FileName, FileLength, FileType," 162 .intval($ResourceId).
", " 163 .intval($FieldId).
", " 164 .
"'".addslashes($BaseFileName).
"', " 166 .
"'".addslashes($FileType).
"', " 167 .
"'".$SecretString.
"')");
169 # retrieve ID of new file 170 $this->
Id = $DB->LastInsertId();
172 # load file info back in from database 173 $DB->Query(
"SELECT * FROM Files WHERE FileId = ".$this->
Id);
174 $this->DBFields = $DB->FetchRow();
176 # copy file to storage 182 # remove file info from database 183 $DB->Query(
"DELETE FROM Files WHERE FileId = ".$this->
Id);
185 # set status indicating constructor failed 186 $this->
Status = self::FILESTAT_COPYERROR;
193 # set status indicating constructor failed 194 $this->
Status = self::FILESTAT_PARAMERROR;
204 return $this->Status;
222 return $this->DBFields[
"FileName"];
231 return $this->DBFields[
"FileLength"];
240 return $this->DBFields[
"FileType"];
250 return $this->UpdateValue(
"FileComment", $NewValue);
260 return $this->UpdateValue(
"FieldId", $NewValue);
270 return $this->UpdateValue(
"ResourceId", $NewValue);
279 return strlen($this->
GetType())
280 ? $this->
GetType() :
"application/octet-stream";
290 # if CleanURLs are enabled, use the redirect that includes 291 # the file name so that browsers don't use index.php as the name 292 # for the downloaded file 293 if ($GLOBALS[
"G_PluginManager"]->PluginEnabled(
"CleanURLs"))
295 return "downloads/".$this->Id.
"/".rawurlencode($this->
Name());
298 # otherwise use the download portal 301 return "index.php?P=DownloadFile&Id=".$this->Id;
311 # remove file entry from DB 312 $this->DB->Query(
"DELETE FROM Files WHERE FileId = ".$this->
Id);
316 if (file_exists($FileName))
328 # for each possible storage location 329 foreach (self::$StorageLocations as $Dir)
331 # build file name for that location 332 $FileName = sprintf($Dir.
"/%06d-%s-%s",
333 $this->Id, $this->DBFields[
"SecretString"], $this->Name());
335 # if file can be found in that location 336 if (file_exists($FileName))
338 # return file name to caller 343 # build file name for default (most preferred) location 344 $FileName = sprintf(self::GetStorageDirectory().
"/%06d-%s-%s",
345 $this->
Id, $this->DBFields[
"SecretString"], $this->
Name());
347 # return file name to caller 357 # for each possible storage location 358 foreach (self::$StorageLocations as $Dir)
360 # if location exists and is writeable 361 if (is_dir($Dir) && is_writeable($Dir))
363 # return location to caller 368 # return default (most preferred) location to caller 369 return self::$StorageLocations[0];
373 # ---- PRIVATE INTERFACE ------------------------------------------------- 381 static private $StorageLocations = array(
392 private function UpdateValue($FieldName, $NewValue)
394 return $this->DB->UpdateValue(
"Files", $FieldName, $NewValue,
395 "FileId = ".intval($this->
Id),
396 $this->DBFields, TRUE);
const FILESTAT_ZEROLENGTH
GetNameOfStoredFile()
Returns the relative link to the stored file.
const FILESTAT_UNREADABLE
GetType()
Gets the file's type.
const FILESTAT_DOESNOTEXIST
SQL database abstraction object with smart query caching.
FieldId($NewValue=DB_NOVALUE)
Gets or sets the field ID of the File.
Id()
Gets the object's ID.
GetLink()
Returns the relative download link to download the file.
const FILESTAT_PARAMERROR
Delete()
Deletes the file and removes its entry from the database.
Status()
Gets the object's status.
__construct($IdOrFileName, $ResourceId=NULL, $FieldId=NULL, $DesiredFileName=NULL, $CheckFileLength=TRUE)
Constructs a File object using either an existing file or a new file.
GetMimeType()
Gets the MIME type of the file.
GetLength()
Gets the length of the file.
static GetStorageDirectory()
Get file storage directory.
ResourceId($NewValue=DB_NOVALUE)
Gets or sets the resource ID of the File.
Name()
Gets the name of the object.
Class representing a stored (usually uploaded) file.
Comment($NewValue=DB_NOVALUE)
Gets or sets the comment on the file.