diff --git a/attachment.php b/attachment.php index dc26a66f4db1c2aa4827da3f541f3e674f8fc570..8e45d8e155c83cae6c31697f49f5b8bfd3910a9e 100644 --- a/attachment.php +++ b/attachment.php @@ -16,7 +16,7 @@ **********************************************************************/ require('secure.inc.php'); require_once(INCLUDE_DIR.'class.attachment.php'); -//Basic checks +// Basic checks if (!$thisclient || !$_GET['id'] || !$_GET['h'] @@ -30,16 +30,8 @@ if (!$thisclient ) Http::response(404, __('Unknown or invalid file')); -//Validate session access hash - we want to make sure the link is FRESH! and the user has access to the parent ticket!! -$vhash=md5($attachment->getFileId().session_id().strtolower($file->getKey())); -if (strcasecmp(trim($_GET['h']), $vhash) - || !($thread=$attachment->getThread()) - || !($object=$thread->getObject()) - || !$object instanceof Ticket - || !$object->checkUserAccess($thisclient)) - Http::response(404, __('Unknown or invalid file')); -//Download the file.. -$file->download(); +if (!$ticket->checkUserAccess($thisclient)) + die(__('Access Denied')); // Download the file.. $file->download(); diff --git a/bootstrap.php b/bootstrap.php index 354c9bd208acc4ecde10f0d75df299d53c0e4357..d16f10feefc17f3e4c462a7f792f553208cf00fb 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -92,7 +92,6 @@ class Bootstrap { define('THREAD_TABLE', $prefix.'thread'); define('THREAD_ENTRY_TABLE', $prefix.'thread_entry'); - define('THREAD_ENTRY_ATTACHMENT_TABLE', $prefix.'thread_entry_attachment'); define('THREAD_ENTRY_EMAIL_TABLE', $prefix.'thread_entry_email'); define('TICKET_TABLE',$prefix.'ticket'); diff --git a/include/class.attachment.php b/include/class.attachment.php index 90c168beb217c11802005220a79b7d799d308a22..a1ecfd97af55ea66d0ea9c684bb07ef96ab0ba03 100644 --- a/include/class.attachment.php +++ b/include/class.attachment.php @@ -21,31 +21,21 @@ class Attachment { var $file_id; var $ht; - var $thread; + var $object; - function Attachment($id, $tid=0) { + function Attachment($id) { - $sql = 'SELECT a.*, e.thread_id FROM '.THREAD_ENTRY_ATTACHMENT_TABLE.' a ' - . 'LEFT JOIN '.THREAD_ENTRY_TABLE.' e ON (e.id = a.thread_entry_id) ' + $sql = 'SELECT a.* FROM '.ATTACHMENT_TABLE.' a ' . 'WHERE a.id='.db_input($id); - if($tid) - $sql.=' AND a.thread_entry_id='.db_input($tid); + if (!($res=db_query($sql)) || !db_num_rows($res)) + return; - if(!($res=db_query($sql)) || !db_num_rows($res)) - return false; - - $this->ht=db_fetch_array($res); - - $this->id=$this->ht['id']; - $this->file_id=$this->ht['file_id']; - - $this->file = $this->thread = null; - - return true; + $this->ht = db_fetch_array($res); + $this->file = $this->object = null; } function getId() { - return $this->id; + return $this->ht['id']; } function getFileId() { @@ -67,32 +57,32 @@ class Attachment { return $this->getHashtable(); } - function getThread() { + function getObject() { - if (!isset($this->thread)) - $this->thread = Thread::lookup($this->ht['thread_id']); + if (!isset($this->object)) + $this->object = ObjectModel::lookup( + $this->ht['object_id'], $this->ht['type']); - return $this->thread; + return $this->object; } - /* Static functions */ - static function getIdByFileHash($hash, $tid=0) { - $sql='SELECT a.id FROM '.THREAD_ENTRY_ATTACHMENT_TABLE.' a ' + static function getIdByFileHash($hash, $objectId=0) { + $sql='SELECT a.id FROM '.ATTACHMENT_TABLE.' a ' .' INNER JOIN '.FILE_TABLE.' f ON(f.id=a.file_id) ' .' WHERE f.`key`='.db_input($hash); - if($tid) - $sql.=' AND a.thread_entry_id='.db_input($tid); + if ($objectId) + $sql.=' AND a.object_id='.db_input($objectId); return db_result(db_query($sql)); } - static function lookup($var, $tid=0) { + static function lookup($var, $objectId=0) { - $id = is_numeric($var) ? $var : self::getIdByFileHash($var, $tid); + $id = is_numeric($var) ? $var : self::getIdByFileHash($var, $oid); return ($id && is_numeric($id) - && ($attach = new Attachment($id, $tid)) + && ($attach = new Attachment($id, $oid)) && $attach->getId()==$id ) ? $attach : null; } diff --git a/include/class.file.php b/include/class.file.php index 74434bcdad9028e894334f4bd02949b834d3d409..caafae2bf9cab7018b6aee5d4a8503d2f7d84295 100644 --- a/include/class.file.php +++ b/include/class.file.php @@ -35,7 +35,7 @@ class AttachmentFile { .' FROM '.FILE_TABLE.' f ' .' LEFT JOIN '.ATTACHMENT_TABLE.' a ON(a.file_id=f.id) ' - .' LEFT JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' t + .' LEFT JOIN '.ATTACHMENT_TABLE.' t ON(t.file_id = f.id) ' .' WHERE f.id='.db_input($id) .' GROUP BY f.id'; @@ -581,8 +581,6 @@ class AttachmentFile { // table and are not logos //FIXME: Just user straight up left join $sql = 'SELECT id FROM '.FILE_TABLE.' WHERE id NOT IN (' - .'SELECT file_id FROM '.THREAD_ENTRY_ATTACHMENT_TABLE - .' UNION ' .'SELECT file_id FROM '.ATTACHMENT_TABLE .") AND `ft` = 'T' AND TIMESTAMPDIFF(DAY, `created`, CURRENT_TIMESTAMP) > 1"; diff --git a/include/class.thread.php b/include/class.thread.php index 5983988607b2304fdee913bc3fe8d87ee7463b4a..30d8e7799e0ee30ff146a8cc067fb9666f82aade 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -32,13 +32,13 @@ class Thread { return null; $sql='SELECT thread.* ' - .' ,count(DISTINCT attach.id) as attachments ' + .' ,count(DISTINCT a.id) as attachments ' .' ,count(DISTINCT entry.id) as entries ' .' FROM '.THREAD_TABLE.' thread ' .' LEFT JOIN '.THREAD_ENTRY_TABLE.' entry ON (entry.thread_id = thread.id) ' - .' LEFT JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' attach - ON (attach.thread_entry_id=entry.id) ' + .' LEFT JOIN '.ATTACHMENT_TABLE.' a + ON (a.object_id=entry.id AND a.`type` = "H") ' .' WHERE thread.id='.db_input($id) .' GROUP BY thread.id'; @@ -98,8 +98,8 @@ class Thread { ON (entry.user_id=user.id) ' .' LEFT JOIN '.STAFF_TABLE.' staff ON (entry.staff_id=staff.staff_id) ' - .' LEFT JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' attach - ON (attach.thread_entry_id = entry.id) ' + .' LEFT JOIN '.ATTACHMENT_TABLE.' attach + ON (attach.object_id = entry.id AND attach.`type`="H") ' .' WHERE entry.thread_id='.db_input($this->getId()); if($type && is_array($type)) @@ -129,9 +129,9 @@ class Thread { function deleteAttachments() { // Clear reference table - $sql = 'DELETE FROM '.THREAD_ENTRY_ATTACHMENT_TABLE. ' a ' + $sql = 'DELETE FROM '.ATTACHMENT_TABLE. ' a ' . 'INNER JOIN '.THREAD_ENTRY_TABLE.' e - ON(e.id = a.thread_entry_id) ' + ON(e.id = a.object_id AND a.`type`= "H") ' . ' WHERE e.thread_id='.db_input($this->getId()); $deleted=0; @@ -225,8 +225,8 @@ Class ThreadEntry { .' FROM '.THREAD_ENTRY_TABLE.' entry ' .' LEFT JOIN '.THREAD_ENTRY_EMAIL_TABLE.' email ON (email.thread_entry_id=entry.id) ' - .' LEFT JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' attach - ON (attach.thread_entry_id=entry.id) ' + .' LEFT JOIN '.ATTACHMENT_TABLE.' attach + ON (attach.object_id=entry.id AND attach.`type` = "H") ' .' WHERE entry.id='.db_input($id); if ($type) @@ -242,8 +242,7 @@ Class ThreadEntry { $this->ht = db_fetch_array($res); $this->id = $this->ht['id']; - - $this->attachments = array(); + $this->attachments = new GenericAttachments($this->id, 'H'); return true; } @@ -501,20 +500,7 @@ Class ThreadEntry { $inline = is_array($file) && @$file['inline']; - // TODO: Add a unique index to THREAD_ENTRY_ATTACHMENT_TABLE (file_id, - // thread_entry_id), and remove this block - if ($id = db_result(db_query('SELECT id FROM '.THREAD_ENTRY_ATTACHMENT_TABLE - .' WHERE file_id='.db_input($fileId) - .' AND thread_entry_id=' .db_input($this->getId())))) - - return $id; - - $sql ='INSERT IGNORE INTO '.THREAD_ENTRY_ATTACHMENT_TABLE.' SET created=NOW() ' - .' ,file_id='.db_input($fileId) - .' ,thread_entry_id='.db_input($this->getId()) - .' ,inline='.db_input($inline ? 1 : 0); - - return (db_query($sql) && ($id=db_insert_id()))?$id:0; + return $this->attachments->save($file, $inline); } function saveAttachments($files) { @@ -527,32 +513,15 @@ Class ThreadEntry { } function getAttachments() { - - if ($this->attachments) - return $this->attachments; - - //XXX: inner join the file table instead? - $sql='SELECT a.id, f.id as file_id, f.size, lower(f.`key`) as file_hash, f.name, a.inline ' - .' FROM '.FILE_TABLE.' f ' - .' INNER JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' a - ON(a.file_id=f.id) ' - .' WHERE a.thread_entry_id='.db_input($this->getId()); - - $this->attachments = array(); - if (($res=db_query($sql)) && db_num_rows($res)) { - while ($rec=db_fetch_array($res)) - $this->attachments[] = $rec; - } - - return $this->attachments; + return $this->attachments->getAll(true, false); } function getAttachmentUrls($script='image.php') { $json = array(); foreach ($this->getAttachments() as $att) { - $json[$att['file_hash']] = array( - 'download_url' => sprintf('attachment.php?id=%d&h=%s', $att['id'], - strtolower(md5($att['file_id'].session_id().$att['file_hash']))), + $json[$att['key']] = array( + 'download_url' => sprintf('attachment.php?id=%d&h=%s', + $att['attach_id'], $att['download']), 'filename' => $att['name'], ); } @@ -570,7 +539,13 @@ Class ThreadEntry { $size=sprintf('<em>(%s)</em>', Format::file_size($att['size'])); $str.=sprintf('<a class="Icon file no-pjax" href="%s?id=%d&h=%s" target="%s">%s</a>%s %s', - $file, $attachment['id'], $hash, $target, Format::htmlchars($attachment['name']), $size, $separator); + $file, + $att['attach_id'], + $att['download'], + $target, + Format::htmlchars($att['name']), + $size, + $separator); } return $str; diff --git a/include/class.ticket.php b/include/class.ticket.php index 3031e03d74df062d71366eb63adc678ba5320167..43c1ed87593ebfbd3acd76e592396288b3c6ae80 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -197,8 +197,8 @@ class Ticket { ON ( thread.object_id = ticket.ticket_id AND thread.object_type="T" ) ' .' LEFT JOIN '.THREAD_ENTRY_TABLE.' entry ON ( entry.thread_id = thread.id ) ' - .' LEFT JOIN '.THREAD_ENTRY_ATTACHMENT_TABLE.' attach - ON ( attach.thread_entry_id = entry.id ) ' + .' LEFT JOIN '.ATTACHMENT_TABLE.' attach + ON ( attach.object_id = entry.id AND attach.`type` = "H") ' .' WHERE ticket.ticket_id='.db_input($id) .' GROUP BY ticket.ticket_id'; diff --git a/include/client/tickets.inc.php b/include/client/tickets.inc.php index d0529ba3eed6a990c24420b454a0c7a738a521a6..e39e43671662b1eff01b62e89c79a9d843f1e6d8 100644 --- a/include/client/tickets.inc.php +++ b/include/client/tickets.inc.php @@ -68,6 +68,15 @@ $pageNav=new Pagenate($total, $page, PAGE_LIMIT); $pageNav->setURL('tickets.php',$qstr.'&sort='.urlencode($_REQUEST['sort']).'&order='.urlencode($_REQUEST['order'])); $pageNav->paginate($tickets); +//more stuff... +$qselect.=' ,count(DISTINCT attach.id) as attachments '; +$qfrom.=' LEFT JOIN '.THREAD_ENTRY_TABLE.' entry + ON (entry.thread_id=thread.id AND entry.`type` IN ("M", "R")) '; +$qfrom.=' LEFT JOIN '.ATTACHMENT_TABLE.' attach + ON (attach.object_id=entry.id AND attach.`type` = "H") '; +$qgroup=' GROUP BY ticket.ticket_id'; + +$query="$qselect $qfrom $qwhere $qgroup ORDER BY $order_by $order LIMIT ".$pageNav->getStart().",".$pageNav->getLimit(); //echo $query; $showing =$total ? $pageNav->showing() : ""; if(!$results_type) diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php index 4507c7bea5251831a134cc50b85dbd0207ffe8b2..f4b7840c2dcb6df064d4a4e1e96e2e0f0d4ba0ff 100644 --- a/include/staff/tickets.inc.php +++ b/include/staff/tickets.inc.php @@ -150,6 +150,7 @@ TicketForm::ensureDynamicDataView(); // Save the query to the session for exporting $_SESSION[':Q:tickets'] = $tickets; + ?> <!-- SEARCH FORM START --> diff --git a/include/upgrader/streams/core.sig b/include/upgrader/streams/core.sig index 90b6d124264702bc778822fabde3b0ffcf306508..252eb31ba78793be662ab22a616f2973246af4b4 100644 --- a/include/upgrader/streams/core.sig +++ b/include/upgrader/streams/core.sig @@ -1 +1 @@ -186868f53bf747f3d04a5ad701101690 +4b4daf9cf5e199673885f5ef58e743d1 diff --git a/include/upgrader/streams/core/b26f29a6-186868f5.cleanup.sql b/include/upgrader/streams/core/b26f29a6-186868f5.cleanup.sql deleted file mode 100644 index 27dca7f84160f3916b8e4bbb968af9622ae89979..0000000000000000000000000000000000000000 --- a/include/upgrader/streams/core/b26f29a6-186868f5.cleanup.sql +++ /dev/null @@ -1,9 +0,0 @@ -ALTER TABLE `%TABLE_PREFIX%thread` - DROP COLUMN `tid`; - -ALTER TABLE `%TABLE_PREFIX%thread_entry` - DROP COLUMN `ticket_id`; - -OPTIMIZE TABLE `%TABLE_PREFIX%ticket`; -OPTIMIZE TABLE `%TABLE_PREFIX%thread`; -OPTIMIZE TABLE `%TABLE_PREFIX%thread_entry`; diff --git a/include/upgrader/streams/core/b26f29a6-186868f5.patch.sql b/include/upgrader/streams/core/b26f29a6-186868f5.patch.sql deleted file mode 100644 index 7f1898fc6b35b62f35c6af30193337950f81d94f..0000000000000000000000000000000000000000 --- a/include/upgrader/streams/core/b26f29a6-186868f5.patch.sql +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @version v1.9.5 - * @signature 2257f6f22ca4b31bea6045b8b7d59d56 - * @title Threads revisited - * - * This patch adds ability to thread anything - * - */ - --- Add thread table -DROP TABLE IF EXISTS `%TABLE_PREFIX%thread`; -CREATE TABLE IF NOT EXISTS `%TABLE_PREFIX%thread` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `object_id` int(11) unsigned NOT NULL, - `object_type` char(1) NOT NULL, - `extra` text, - `created` datetime NOT NULL, - PRIMARY KEY (`id`), - KEY `object_id` (`object_id`), - KEY `object_type` (`object_type`) -) DEFAULT CHARSET=utf8; - --- create threads -INSERT INTO `%TABLE_PREFIX%thread` - (`object_id`, `object_type`, `created`) - SELECT t1.ticket_id, 'T', t1.created - FROM `%TABLE_PREFIX%ticket_thread` t1 - JOIN ( - SELECT ticket_id, MIN(id) as id - FROM `%TABLE_PREFIX%ticket_thread` - WHERE `thread_type` = 'M' - GROUP BY ticket_id - ) t2 - ON (t1.ticket_id=t2.ticket_id and t1.id=t2.id) - ORDER BY t1.created; - -ALTER TABLE `%TABLE_PREFIX%ticket_thread` - ADD `thread_id` INT( 11 ) UNSIGNED NOT NULL DEFAULT '0' AFTER `pid` , - ADD INDEX ( `thread_id` ); - -UPDATE `%TABLE_PREFIX%ticket_thread` t1 - LEFT JOIN `%TABLE_PREFIX%thread` t2 ON ( t2.object_id = t1.ticket_id ) - SET t1.thread_id = t2.id; - --- convert ticket_thread to thread_entry -ALTER TABLE `%TABLE_PREFIX%ticket_thread` - CHANGE `thread_type` `type` CHAR( 1 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, - ADD INDEX ( `type` ); - -RENAME TABLE `%TABLE_PREFIX%ticket_thread` TO `%TABLE_PREFIX%thread_entry` ; - --- add thread id to ticket table -ALTER TABLE `%TABLE_PREFIX%ticket` - ADD `thread_id` INT( 11 ) UNSIGNED NOT NULL DEFAULT '0' AFTER `number` , - ADD INDEX ( `thread_id` ); - -UPDATE `%TABLE_PREFIX%ticket` t1 - LEFT JOIN `%TABLE_PREFIX%thread` t2 ON ( t2.object_id = t1.ticket_id ) - SET t1.thread_id = t2.id; - --- convert ticket_attachment to thread_entry_attachment -ALTER TABLE `%TABLE_PREFIX%ticket_attachment` - CHANGE `attach_id` `id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT, - CHANGE `ref_id` `thread_entry_id` INT( 11 ) UNSIGNED NOT NULL DEFAULT '0'; - DROP `ticket_id`; - -RENAME TABLE `%TABLE_PREFIX%ticket_attachment` TO `%TABLE_PREFIX%thread_entry_attachment`; - --- convert ticket_email_info to thread_entry_mid -ALTER TABLE `%TABLE_PREFIX%ticket_email_info` - CHANGE `thread_id` `thread_entry_id` INT( 11 ) UNSIGNED NOT NULL, - CHANGE `email_mid` `mid` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, - ADD INDEX ( `thread_entry_id` ); - -RENAME TABLE `%TABLE_PREFIX%ticket_email_info` TO `%TABLE_PREFIX%thread_entry_email`; - --- Set new schema signature -UPDATE `%TABLE_PREFIX%config` - SET `value` = '2257f6f22ca4b31bea6045b8b7d59d56' - WHERE `key` = 'schema_signature' AND `namespace` = 'core'; diff --git a/scp/attachment.php b/scp/attachment.php index 02194c541d6c84294a6465320b041acf34c2ff77..ab6d45ab14d31d4122c085f40188c125bb74d897 100644 --- a/scp/attachment.php +++ b/scp/attachment.php @@ -16,7 +16,7 @@ require('staff.inc.php'); require_once(INCLUDE_DIR.'class.attachment.php'); -//Basic checks +// Basic checks if (!$thisstaff || !$_GET['id'] || !$_GET['h'] @@ -30,13 +30,7 @@ if (!$thisstaff ) Http::response(404, __('Unknown or invalid file')); -//Validate session access hash - we want to make sure the link is FRESH! and the user has access to the parent ticket!! -$vhash=md5($attachment->getFileId().session_id().strtolower($file->getKey())); -if (strcasecmp(trim($_GET['h']), $vhash) - || !($thread=$attachment->getThread()) - || !($object=$thread->getObject()) - || !$object instanceof Ticket - || !$object->checkStaffAccess($thisstaff)) +if (!$ticket->checkStaffAccess($thisstaff)) die(__('Access Denied')); //Download the file.. diff --git a/setup/inc/streams/core/install-mysql.sql b/setup/inc/streams/core/install-mysql.sql index 7f5fcedbbb1b1c92a29faab10e1374e372face0f..d91ce79ab86f5fed2f4d628a84c9a2b5ca1ec40a 100644 --- a/setup/inc/streams/core/install-mysql.sql +++ b/setup/inc/streams/core/install-mysql.sql @@ -646,18 +646,6 @@ CREATE TABLE `%TABLE_PREFIX%thread_entry` ( KEY `type` (`type`) ) DEFAULT CHARSET=utf8; -DROP TABLE IF EXISTS `%TABLE_PREFIX%thread_entry_attachment`; -CREATE TABLE `%TABLE_PREFIX%thread_entry_attachment` ( - `id` int(11) unsigned NOT NULL auto_increment, - `file_id` int(10) unsigned NOT NULL default '0', - `thread_entry_id` int(11) unsigned NOT NULL default '0', - `inline` tinyint(1) NOT NULL default '0', - `created` datetime NOT NULL, - PRIMARY KEY (`id`), - KEY `file_id` (`file_id`), - KEY `ref_id` (`thread_entry_id`) -) DEFAULT CHARSET=utf8; - DROP TABLE IF EXISTS `%TABLE_PREFIX%thread_entry_email`; CREATE TABLE `%TABLE_PREFIX%thread_entry_email` ( `id` int(11) unsigned NOT NULL auto_increment,