Newer
Older
<?php
/*********************************************************************
class.file.php
Peter Rotich <peter@osticket.com>
Copyright (c) 2006-2012 osTicket
http://www.osticket.com
Released under the GNU General Public License WITHOUT ANY WARRANTY.
See LICENSE.TXT for details.
vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
class AttachmentFile {
var $id;
var $ht;
function AttachmentFile($id) {
$this->id =0;
return ($this->load($id));
}
function load($id=0) {
if(!$id && !($id=$this->getId()))
return false;
$sql='SELECT id, type, size, name, hash, f.created, '
.' count(DISTINCT c.canned_id) as canned, count(DISTINCT t.ticket_id) as tickets '
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
.' FROM '.FILE_TABLE.' f '
.' LEFT JOIN '.CANNED_ATTACHMENT_TABLE.' c ON(c.file_id=f.id) '
.' LEFT JOIN '.TICKET_ATTACHMENT_TABLE.' t ON(t.file_id=f.id) '
.' WHERE f.id='.db_input($id)
.' GROUP BY f.id';
if(!($res=db_query($sql)) || !db_num_rows($res))
return false;
$this->ht=db_fetch_array($res);
$this->id =$this->ht['id'];
return true;
}
function reload() {
return $this->load();
}
function getHashtable() {
return $this->ht;
}
function getInfo() {
return $this->getHashtable();
}
function getNumTickets() {
return $this->ht['tickets'];
}
function isCanned() {
return ($this->ht['canned']);
}
function isInUse() {
return ($this->getNumTickets() || $this->isCanned());
}
function getId() {
return $this->id;
}
function getType() {
return $this->ht['type'];
}
function getMime() {
return $this->getType();
}
function getSize() {
return $this->ht['size'];
}
function getName() {
return $this->ht['name'];
}
function getHash() {
return $this->ht['hash'];
}
function sendData() {
# XXX: For maximum efficiency,
# do "show variables like 'max_allowed_packet'", and use the
# lesser of half of PHP's memory limit and that value as the
# chunk_size
$chunk_size = 256 * 1024;
for ($start=1; $start<$this->getSize(); $start+=$chunk_size) {
list($data) = db_fetch_row(db_query(
'SELECT SUBSTRING(filedata,'.$start.','.$chunk_size
.') FROM '.FILE_TABLE.' WHERE id='.db_input($this->getId())));
echo $data;
}
# XXX: This is horrible, and is subject to php's memory
# restrictions, etc. Don't use this function!
ob_start();
$this->sendData();
$data = &ob_get_contents();
ob_end_clean();
return $data;
}
function delete() {
$sql='DELETE FROM '.FILE_TABLE.' WHERE id='.db_input($this->getId()).' LIMIT 1';
return (db_query($sql) && db_affected_rows());
}
function display() {
header('Content-Type: '.($this->getType()?$this->getType():'application/octet-stream'));
exit();
}
function download() {
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: public');
header('Content-Type: '.($this->getType()?$this->getType():'application/octet-stream'));
$filename=basename($this->getName());
$user_agent = strtolower ($_SERVER['HTTP_USER_AGENT']);
if ((is_integer(strpos($user_agent,'msie'))) && (is_integer(strpos($user_agent,'win')))) {
header('Content-Disposition: filename='.$filename.';');
}else{
header('Content-Disposition: attachment; filename='.$filename.';' );
}
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.$this->getSize());
/* Function assumes the files types have been validated */
Peter Rotich
committed
if(!$file['name'] || $file['error'] || !is_uploaded_file($file['tmp_name']))
return false;
$info=array('type'=>$file['type'],
'size'=>$file['size'],
'name'=>$file['name'],
'hash'=>MD5(MD5_FILE($file['tmp_name']).time()),
'data'=>file_get_contents($file['tmp_name'])
);
return AttachmentFile::save($info);
}
function save($file) {
if(!$file['hash'])
$file['hash']=MD5(MD5($file['data']).time());
if(!$file['size'])
$file['size']=strlen($file['data']);
$sql='INSERT INTO '.FILE_TABLE.' SET created=NOW() '
.',type='.db_input($file['type'])
.',size='.db_input($file['size'])
.',name='.db_input($file['name'])
.',hash='.db_input($file['hash']);
if (!(db_query($sql) && ($id=db_insert_id())))
return false;
foreach (str_split($file['data'], 1024*100) as $chunk) {
Peter Rotich
committed
$sql='UPDATE '.FILE_TABLE
.' SET filedata = CONCAT(filedata,'.db_input($chunk).')'
.' WHERE id='.db_input($id);
if(!db_query($sql)) {
db_query('DELETE FROM '.FILE_TABLE.' WHERE id='.db_input($id).' LIMIT 1');
Peter Rotich
committed
}
Peter Rotich
committed
}
/* Static functions */
function getIdByHash($hash) {
$sql='SELECT id FROM '.FILE_TABLE.' WHERE hash='.db_input($hash);
if(($res=db_query($sql)) && db_num_rows($res))
list($id)=db_fetch_row($res);
return $id;
}
function lookup($id) {
$id = is_numeric($id)?$id:AttachmentFile::getIdByHash($id);
return ($id && ($file = new AttachmentFile($id)) && $file->getId()==$id)?$file:null;
}
/**
* Removes files and associated meta-data for files which no ticket,
* canned-response, or faq point to any more.
*/
/* static */ function deleteOrphans() {
$res=db_query(
'DELETE FROM '.FILE_TABLE.' WHERE id NOT IN ('
# DISTINCT implies sort and may not be necessary
.'SELECT DISTINCT(file_id) FROM ('
.'SELECT file_id FROM '.TICKET_ATTACHMENT_TABLE
.' UNION ALL '
.'SELECT file_id FROM '.CANNED_ATTACHMENT_TABLE
.' UNION ALL '
.'SELECT file_id FROM '.FAQ_ATTACHMENT_TABLE
.') still_loved'
.')');
return db_affected_rows();
}
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
}
class AttachmentList {
function AttachmentList($table, $key) {
$this->table = $table;
$this->key = $key;
}
function all() {
if (!isset($this->list)) {
$this->list = array();
$res=db_query('SELECT file_id FROM '.$this->table
.' WHERE '.$this->key);
while(list($id) = db_fetch_row($res)) {
$this->list[] = new AttachmentFile($id);
}
}
return $this->list;
}
function getCount() {
return count($this->all());
}
function add($fileId) {
db_query(
'INSERT INTO '.$this->table
.' SET '.$this->key
.' file_id='.db_input($fileId));
}
function remove($fileId) {
db_query(
'DELETE FROM '.$this->table
.' WHERE '.$this->key
.' AND file_id='.db_input($fileId));
}
}
?>