CWIS Developer Documentation

- Home
- Main Page
- Classes
- Files

- File List
- File Members

File.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: File.php
4 #
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/
8 #
9
13 class File {
14
15 # ---- PUBLIC INTERFACE --------------------------------------------------
16
17 # status codes (set by constructor and returned by File::Status())
18 const FILESTAT_OK = 0;
19 const FILESTAT_COPYERROR = 1;
20 const FILESTAT_PARAMERROR = 2;
21 const FILESTAT_ZEROLENGTH = 3;
22 const FILESTAT_DOESNOTEXIST = 4;
23 const FILESTAT_UNREADABLE = 5;
24
38 function File($IdOrFileName, $ResourceId = NULL, $FieldId = NULL,
39 $DesiredFileName = NULL, $CheckFileLength = TRUE)
40 {
41 # assume constructor will succeed
42 $this->Status = self::FILESTAT_OK;
43
44 # get our own database handle
45 $DB = new Database();
46 $this->DB = $DB;
47
48 # if ID supplied
49 if (is_int($IdOrFileName))
50 {
51 # set file ID from supplied value
52 $this->Id = intval($IdOrFileName);
53
54 # load file info from database
55 $DB->Query("SELECT * FROM Files WHERE FileId = ".$this->Id);
56 $this->DBFields = $DB->FetchRow();
57
58 # if the image wasn't found in the database
59 if (!$DB->NumRowsSelected())
60 {
61 $this->Status = self::FILESTAT_DOESNOTEXIST;
62 }
63 }
64 # else if file name and resource ID and field ID supplied
65 elseif (strlen($IdOrFileName) && ($ResourceId != NULL) && ($FieldId != NULL))
66 {
67 # if file does not exist
68 $TempFileName = $IdOrFileName;
69 if (!file_exists($TempFileName) || !is_readable($TempFileName))
70 {
71 # set status indicating appropriate error
72 $this->Status = file_exists($TempFileName)
73 ? self::FILESTAT_DOESNOTEXIST : self::FILESTAT_UNREADABLE;
74 }
75 else
76 {
77 # if we were asked to check file length and file was zero length
78 $FileLength = filesize($TempFileName);
79 if ($CheckFileLength && !$FileLength)
80 {
81 # set status indicating zero length file
82 $this->Status = self::FILESTAT_ZEROLENGTH;
83 }
84 else
85 {
86 # generate secret string (used to protect from unauthorized download)
87 srand((double)microtime() * 1000000);
88 $SecretString = sprintf("%04X", rand(1, 30000));
89
90 # attempt to get file type
91 $FileType = "";
92 if (function_exists("finfo_open"))
93 {
94 $FInfoHandle = finfo_open(FILEINFO_MIME);
95
96 if ($FInfoHandle)
97 {
98 $FInfoMime = finfo_file($FInfoHandle, $TempFileName);
99 finfo_close($FInfoHandle);
100
101 if ($FInfoMime)
102 {
103 $FileType = $FInfoMime;
104 }
105 }
106 }
107 else if (function_exists("mime_content_type"))
108 {
109 # mime_content_type has been deprecated, but it may be
110 # the only way to get the mimetype for PHP < 5.3
111 $MimeType = mime_content_type($TempFileName);
112
113 if ($MimeType)
114 {
115 $FileType = $MimeType;
116 }
117 }
118
119 # add file info to database
120 $BaseFileName = $DesiredFileName
121 ? basename($DesiredFileName) : basename($TempFileName);
122 $DB->Query("INSERT INTO Files"
123 ." (ResourceId, FieldId, FileName, FileLength, FileType,"
124 ." SecretString)"
125 ." VALUES ("
126 .intval($ResourceId).", "
127 .intval($FieldId).", "
128 ."'".addslashes($BaseFileName)."', "
129 .$FileLength.", "
130 ."'".$FileType."', "
131 ."'".$SecretString."')");
132
133 # retrieve ID of new file
134 $this->Id = $DB->LastInsertId();
135
136 # load file info back in from database
137 $DB->Query("SELECT * FROM Files WHERE FileId = ".$this->Id);
138 $this->DBFields = $DB->FetchRow();
139
140 # copy file to storage
141 $CopySucceeded = copy($IdOrFileName, $this->GetNameOfStoredFile());
142
143 # if copy failed
144 if (!$CopySucceeded)
145 {
146 # remove file info from database
147 $DB->Query("DELETE FROM Files WHERE FileId = ".$this->Id);
148
149 # set status indicating constructor failed
150 $this->Status = self::FILESTAT_COPYERROR;
151 }
152 }
153 }
154 }
155 else
156 {
157 # set status indicating constructor failed
158 $this->Status = self::FILESTAT_PARAMERROR;
159 }
160 }
161
166 function Status() { return $this->Status; }
167
172 function Id() { return $this->Id; }
173
178 function Name() { return $this->DBFields["FileName"]; }
179
184 function GetLength() { return $this->DBFields["FileLength"]; }
185
190 function GetType() { return $this->DBFields["FileType"]; }
191
197 function Comment($NewValue = DB_NOVALUE)
198 { return $this->UpdateValue("FileComment", $NewValue); }
199
205 function FieldId($NewValue = DB_NOVALUE)
206 { return $this->UpdateValue("FieldId", $NewValue); }
207
213 function ResourceId($NewValue = DB_NOVALUE)
214 { return $this->UpdateValue("ResourceId", $NewValue); }
215
220 function GetMimeType()
221 {
222 return strlen($this->GetType())
223 ? $this->GetType() : "application/octet-stream";
224 }
225
231 function GetLink()
232 {
233 global $AF;
234
235 # if .htaccess files are supported, use the redirect that includes
236 # the file name so that browsers don't use index.php as the name
237 # for the downloaded file
238 if ($AF->HtaccessSupport())
239 {
240 return "downloads/".$this->Id."/".rawurlencode($this->Name());
241 }
242
243 # otherwise use the download portal
244 else
245 {
246 return "index.php?P=DownloadFile&Id=".$this->Id;
247 }
248 }
249
254 function Delete()
255 {
256 # remove file entry from DB
257 $this->DB->Query("DELETE FROM Files WHERE FileId = ".$this->Id);
258
259 # delete file
260 $FileName = $this->GetNameOfStoredFile();
261 if (file_exists($FileName))
262 {
263 unlink($FileName);
264 }
265 }
266
271 function GetNameOfStoredFile()
272 {
273 # for each possible storage location
274 foreach (self::$StorageLocations as $Dir)
275 {
276 # build file name for that location
277 $FileName = sprintf($Dir."/%06d-%s-%s",
278 $this->Id, $this->DBFields["SecretString"], $this->Name());
279
280 # if file can be found in that location
281 if (file_exists($FileName))
282 {
283 # return file name to caller
284 return $FileName;
285 }
286 }
287
288 # build file name for default (most preferred) location
289 $FileName = sprintf(self::GetStorageDirectory()."/%06d-%s-%s",
290 $this->Id, $this->DBFields["SecretString"], $this->Name());
291
292 # return file name to caller
293 return $FileName;
294 }
295
300 static function GetStorageDirectory()
301 {
302 # for each possible storage location
303 foreach (self::$StorageLocations as $Dir)
304 {
305 # if location exists and is writeable
306 if (is_dir($Dir) && is_writeable($Dir))
307 {
308 # return location to caller
309 return $Dir;
310 }
311 }
312
313 # return default (most preferred) location to caller
314 return self::$StorageLocations[0];
315 }
316
317
318 # ---- PRIVATE INTERFACE -------------------------------------------------
319
320 private $DB;
321 private $Status;
322 private $Id;
323 private $DBFields;
324
326 static private $StorageLocations = array(
327 "local/data/files",
328 "FileStorage",
329 );
330
337 private function UpdateValue($FieldName, $NewValue)
338 {
339 return $this->DB->UpdateValue("Files", $FieldName, $NewValue,
340 "FileId = ".intval($this->Id),
341 $this->DBFields, TRUE);
342 }
343 }
344
345
File\FILESTAT_ZEROLENGTH
const FILESTAT_ZEROLENGTH
Definition: File.php:21
File\GetNameOfStoredFile
GetNameOfStoredFile()
Returns the relative link to the stored file.
Definition: File.php:271
File\FILESTAT_UNREADABLE
const FILESTAT_UNREADABLE
Definition: File.php:23
File\FILESTAT_COPYERROR
const FILESTAT_COPYERROR
Definition: File.php:19
File\GetType
GetType()
Gets the file's type.
Definition: File.php:190
File\FILESTAT_DOESNOTEXIST
const FILESTAT_DOESNOTEXIST
Definition: File.php:22
Database
SQL database abstraction object with smart query caching.
Definition: Axis--Database.php:22
DB_NOVALUE
const DB_NOVALUE
Definition: Axis--Database.php:1267
File\FieldId
FieldId($NewValue=DB_NOVALUE)
Gets or sets the field ID of the File.
Definition: File.php:205
File\Id
Id()
Gets the object's ID.
Definition: File.php:172
File\GetLink
GetLink()
Returns the relative download link to download the file.
Definition: File.php:231
File\FILESTAT_PARAMERROR
const FILESTAT_PARAMERROR
Definition: File.php:20
File\Delete
Delete()
Deletes the file and removes its entry from the database.
Definition: File.php:254
File\Status
Status()
Gets the object's status.
Definition: File.php:166
File\GetMimeType
GetMimeType()
Gets the MIME type of the file.
Definition: File.php:220
PHP
PHP
Definition: OAIClient.php:39
File\GetLength
GetLength()
Gets the length of the file.
Definition: File.php:184
File\GetStorageDirectory
static GetStorageDirectory()
Get file storage directory.
Definition: File.php:300
File\ResourceId
ResourceId($NewValue=DB_NOVALUE)
Gets or sets the resource ID of the File.
Definition: File.php:213
File\FILESTAT_OK
const FILESTAT_OK
Definition: File.php:18
File\Name
Name()
Gets the name of the object.
Definition: File.php:178
File
Class representing a stored (usually uploaded) file.
Definition: File.php:13
File\Comment
Comment($NewValue=DB_NOVALUE)
Gets or sets the comment on the file.
Definition: File.php:197
File\File
File($IdOrFileName, $ResourceId=NULL, $FieldId=NULL, $DesiredFileName=NULL, $CheckFileLength=TRUE)
Constructs a File object using either an existing file or a new file.
Definition: File.php:38