diff --git a/README.md b/README.md index 34981849af1f420236229466374cba706e0351e3..4d97925949c0c7e4fff49c52ab5c8b445572f171 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,25 @@ Follow the usual install instructions (beginning from Manual Installation above), except, don't delete the setup/ folder. For this reason, such an installation is not recommended for a public-facing support system. +Upgrading +--------- +osTicket supports upgrading from 1.6-rc1 and later versions. As with any +upgrade, strongly consider a backup of your attachment files, database, and +osTicket codebase before embarking on an upgrade. + +To trigger the update process, fetch the osTicket-1.7 tarball from either +the osTicket [github](http://github.com/osTicket/osTicket-1.7) page or from +the osTicket website. Extract the tarball into the folder of you osTicket +codebase. This can also be accomplished with the zip file, and a FTP client +can of course be used to upload the new source code to your server. + +Any way you choose your adventure, when you have your codebase upgraded to +osTicket-1.7, visit the /scp page of you ticketing system. The upgrader will +be presented and will walk you through the rest of the process. (The couple +clicks needed to go through the process are pretty boring to describe). + +View the UPGRADING.txt file for other todo items to complete your upgrade. + Help ---- Visit the [wiki](http://osticket.com/wiki/Home) or the diff --git a/include/class.file.php b/include/class.file.php index b9bfbe1b7d2975ebdcc467bfb826ed35b8f1ec75..891a8b5bfb851415c1ab3cbe804284ae5217f229 100644 --- a/include/class.file.php +++ b/include/class.file.php @@ -172,10 +172,18 @@ class AttachmentFile { .',type='.db_input($file['type']) .',size='.db_input($file['size']) .',name='.db_input($file['name']) - .',hash='.db_input($file['hash']) - .',filedata='.db_input($file['data']); + .',hash='.db_input($file['hash']); - return db_query($sql)?db_insert_id():0; + if (!(db_query($sql) && ($id=db_insert_id()))) + return false; + + foreach (str_split($file['data'], 1024*100) as $chunk) { + if (!db_query('UPDATE '.FILE_TABLE.' SET filedata = CONCAT(filedata,' + .db_input($chunk).') WHERE id='.db_input($id))) + # Remove partially uploaded file contents + return false; + } + return $id; } /* Static functions */ diff --git a/include/class.migrater.php b/include/class.migrater.php index 72679537e9b59af366e69bca04a05f68f0dd9471..04f38be2af9c46c7705591e550bb993096d723d2 100644 --- a/include/class.migrater.php +++ b/include/class.migrater.php @@ -114,7 +114,7 @@ class AttachmentMigrater { */ function do_batch($time=30, $max=0) { - if(!$this->queueAttachments() || !$this->getQueueLength()) + if(!$this->queueAttachments($max) || !$this->getQueueLength()) return 0; $count = 0; @@ -123,7 +123,7 @@ class AttachmentMigrater { if($this->next() && $max && ++$count>=$max) break; - return $this->queueAttachments(); + return $this->queueAttachments($max); } @@ -131,7 +131,7 @@ class AttachmentMigrater { return $this->skipList; } - function queue($fileinfo) { + function enqueue($fileinfo) { $this->queue[] = $fileinfo; } @@ -159,8 +159,14 @@ class AttachmentMigrater { } # Get the mime/type of each file # XXX: Use finfo_buffer for PHP 5.3+ - if(function_exists('mime_content_type')) //XXX: function depreciated in newer versions of PHP!!!!! + if(function_exists('mime_content_type')) { + //XXX: function depreciated in newer versions of PHP!!!!! $info['type'] = mime_content_type($info['path']); + } elseif (function_exists('finfo_file')) { // PHP 5.3.0+ + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $info['type'] = finfo_file($finfo, $info['path']); + } + # TODO: Add extension-based mime-type lookup if (!($fileId = AttachmentFile::save($info))) { return $this->skip($info['attachId'], @@ -194,8 +200,8 @@ class AttachmentMigrater { $sql='SELECT attach_id, file_name, file_key, Ti.created' .' FROM '.TICKET_ATTACHMENT_TABLE.' TA' - .' JOIN '.TICKET_TABLE.' Ti ON Ti.ticket_id=TA.ticket_id' - .' WHERE NOT file_id '; //XXX: ignore orphaned attachments? + .' INNER JOIN '.TICKET_TABLE.' Ti ON (Ti.ticket_id=TA.ticket_id)' + .' WHERE NOT file_id '; if(($skipList=$this->getSkipList())) $sql.= ' AND attach_id NOT IN('.implode(',', db_input($skipList)).')'; @@ -253,10 +259,10 @@ class AttachmentMigrater { # anyway. $info['size'] = @filesize($info['path']); # Coroutines would be nice .. - $this->queue($info); + $this->enqueue($info); } - return $this->getQueueLength(); + return $this->queueAttachments($limit); } function skip($attachId, $error) { diff --git a/include/class.ostsession.php b/include/class.ostsession.php index 0bcd9449fb234c6b9a895da6b046527f7a7909a4..08cac02ce306f616ad0d6329e6a51436a78d9e7d 100644 --- a/include/class.ostsession.php +++ b/include/class.ostsession.php @@ -67,10 +67,13 @@ class osTicketSession { function write($id, $data){ global $thisstaff; + $ttl = ($this && get_class($this) == 'osTicketSession') + ? $this->getTTL() : SESSION_TTL; + $sql='REPLACE INTO '.SESSION_TABLE.' SET session_updated=NOW() '. ',session_id='.db_input($id). ',session_data='.db_input($data). - ',session_expire=(NOW() + INTERVAL '.$this->getTTL().' SECOND)'. + ',session_expire=(NOW() + INTERVAL '.$ttl.' SECOND)'. ',user_id='.db_input($thisstaff?$thisstaff->getId():0). ',user_ip='.db_input($_SERVER['REMOTE_ADDR']). ',user_agent='.db_input($_SERVER['HTTP_USER_AGENT']); diff --git a/include/class.upgrader.php b/include/class.upgrader.php index 69dd760fda40c4e1bdc73454565a05e96b202aa7..de11aee3a2e6f054d334205b9538fe73be2b0907 100644 --- a/include/class.upgrader.php +++ b/include/class.upgrader.php @@ -181,9 +181,11 @@ class Upgrader extends SetupWizard { function doTasks() { + global $ost; if(!($tasks=$this->getPendingTasks())) return true; //Nothing to do. + $ost->logDebug('Upgrader', sprintf('There are %d pending upgrade tasks', count($tasks))); $start_time = Misc::micro_time(); foreach($tasks as $k => $task) { //TODO: check time used vs. max execution - break if need be @@ -238,6 +240,9 @@ class Upgrader extends SetupWizard { $shash = substr($phash, 9, 8); $_SESSION['ost_upgrader'][$shash]['tasks'] = $tasks; $_SESSION['ost_upgrader'][$shash]['state'] = 'upgrade'; + + $ost->logDebug('Upgrader', sprintf('Found %d tasks to be executed for %s', + count($tasks), $shash)); break; } @@ -253,13 +258,16 @@ class Upgrader extends SetupWizard { case 'c00511c7-7be60a84': //V1.6 ST- 1.7 * {{MD5('1.6 ST') -> c00511c7c1db65c0cfad04b4842afc57}} $tasks[] = array('func' => 'migrateAttachments2DB', 'desc' => 'Migrating attachments to database, it might take a while depending on the number of files.'); + $tasks[] = array('func' => 'migrateSessionFile2DB', + 'desc' => 'Transitioning to db-backed sessions'); break; } //Check IF SQL cleanup is exists. $file=$this->getSQLDir().$phash.'.cleanup.sql'; if(file_exists($file)) - $tasks[] = array('func' => 'cleanup', 'desc' => 'Post-upgrade cleanup!'); + $tasks[] = array('func' => 'cleanup', 'desc' => 'Post-upgrade cleanup!', + 'phash' => $phash); return $tasks; @@ -267,8 +275,11 @@ class Upgrader extends SetupWizard { /************* TASKS **********************/ function cleanup($taskId) { + global $ost; + + $phash = $this->tasks[$taskId]['phash']; + $file=$this->getSQLDir().$phash.'.cleanup.sql'; - $file=$this->getSQLDir().$this->getShash().'-cleanup.sql'; if(!file_exists($file)) //No cleanup script. return 0; @@ -276,11 +287,13 @@ class Upgrader extends SetupWizard { if($this->load_sql_file($file, $this->getTablePrefix(), false, true)) return 0; - //XXX: ??? - return false; + $ost->logDebug('Upgrader', sprintf("%s: Unable to process cleanup file", + $phash)); + return 0; } function migrateAttachments2DB($taskId) { + global $ost; if(!($max_time = ini_get('max_execution_time'))) $max_time = 30; //Default to 30 sec batches. @@ -291,5 +304,11 @@ class Upgrader extends SetupWizard { return $att_migrater->getQueueLength(); } + + function migrateSessionFile2DB($taskId) { + # How about 'dis for a hack? + osTicketSession::write(session_id(), session_encode()); + return 0; + } } ?> diff --git a/include/upgrader/patches/60fcbee1-f8856d56.patch.sql b/include/upgrader/patches/60fcbee1-f8856d56.patch.sql index 2b7e48599816e88702f709f50557189b160a727e..624e88968ef3f673bea2f1a96d4b1733fbff9c8a 100644 --- a/include/upgrader/patches/60fcbee1-f8856d56.patch.sql +++ b/include/upgrader/patches/60fcbee1-f8856d56.patch.sql @@ -15,5 +15,47 @@ CREATE TABLE `%TABLE_PREFIX%ticket_event` ( DROP TABLE IF EXISTS `%TABLE_PREFIX%ticket_history`; DROP TABLE IF EXISTS `%TABLE_PREFIX%history`; +-- Transfer ticket statistics from the %ticket table (inaccurate) +-- REOPENED +INSERT INTO `%TABLE_PREFIX%ticket_event` + (`ticket_id`, `staff_id`, `team_id`, `dept_id`, `topic_id`, + `state`, `staff`, `timestamp`) + SELECT `ticket_id`, T1.`staff_id`, `team_id`, T1.`dept_id`, `topic_id`, + 'reopened', T2.`username`, `reopened` + FROM `%TABLE_PREFIX%ticket` T1 + INNER JOIN `%TABLE_PREFIX%staff` T2 + ON (T1.`staff_id` = T2.`staff_id`) + WHERE `status` = 'open' and `reopened` is not null; + +-- CLOSED +INSERT INTO `%TABLE_PREFIX%ticket_event` + (`ticket_id`, `staff_id`, `team_id`, `dept_id`, `topic_id`, + `state`, `staff`, `timestamp`) + SELECT `ticket_id`, T1.`staff_id`, `team_id`, T1.`dept_id`, `topic_id`, + 'closed', COALESCE(T2.`username`,'unknown'), `closed` + FROM `%TABLE_PREFIX%ticket` T1 + LEFT JOIN `%TABLE_PREFIX%staff` T2 + ON (T1.`staff_id` = T2.`staff_id`) + WHERE `status` = 'closed' and `closed` is not null; + +-- OVERDUE +INSERT INTO `%TABLE_PREFIX%ticket_event` + (`ticket_id`, `staff_id`, `team_id`, `dept_id`, `topic_id`, + `state`, `staff`, `timestamp`) + SELECT `ticket_id`, T1.`staff_id`, `team_id`, T1.`dept_id`, `topic_id`, + 'overdue', 'SYSTEM', `duedate` + FROM `%TABLE_PREFIX%ticket` T1 + INNER JOIN `%TABLE_PREFIX%staff` T2 + ON (T1.`staff_id` = T2.`staff_id`) + WHERE `status` = 'open' and `isoverdue`; + +-- OPENED +INSERT INTO `%TABLE_PREFIX%ticket_event` + (`ticket_id`, `staff_id`, `team_id`, `dept_id`, `topic_id`, + `state`, `staff`, `timestamp`) + SELECT `ticket_id`, 0, 0, 0, `topic_id`, + 'created', 'SYSTEM', T1.`created` + FROM `%TABLE_PREFIX%ticket` T1; + UPDATE `%TABLE_PREFIX%config` SET `schema_signature`='f8856d56e51c5cc3416389de78b54515'; diff --git a/include/upgrader/patches/7be60a84-522e5b78.patch.sql b/include/upgrader/patches/7be60a84-522e5b78.patch.sql index acdaf7d0d3c1f8baaedd40bd68e33b01b97e72c9..a31af302d3b10908fdded3c2359b61b426c5a87d 100644 --- a/include/upgrader/patches/7be60a84-522e5b78.patch.sql +++ b/include/upgrader/patches/7be60a84-522e5b78.patch.sql @@ -1,9 +1,9 @@ /** + * No longer necessary -- don't clobber email templates for previous + * osTicket administrators + * * @version v1.7-DPR1 (P1) - */ -UPDATE `%TABLE_PREFIX%email_template` - SET `ticket_overlimit_subj` = 'Open Tickets Limit Reached' - WHERE `tpl_id` = 1 AND `cfg_id` = 1; + */ UPDATE `%TABLE_PREFIX%config` SET `schema_signature`='522e5b783c2824c67222260ee22baa93'; diff --git a/include/upgrader/patches/c00511c7-7be60a84.cleanup.sql b/include/upgrader/patches/c00511c7-7be60a84.cleanup.sql new file mode 100644 index 0000000000000000000000000000000000000000..01d69e2d72b732b2d7c3f618fd6e595ccb7c67f7 --- /dev/null +++ b/include/upgrader/patches/c00511c7-7be60a84.cleanup.sql @@ -0,0 +1,25 @@ +-- Drop columns we nolonger need - (must be at the very bottom or after session table is created) +ALTER TABLE `%TABLE_PREFIX%config` + DROP COLUMN `ostversion`, + DROP COLUMN `timezone_offset`, + DROP COLUMN `api_passphrase`; + +-- Drop fields we no longer need in the reference table. +ALTER TABLE `%TABLE_PREFIX%ticket_attachment` + DROP `file_size`, + DROP `file_name`, + DROP `file_key`, + DROP `updated`, + DROP `isdeleted`; + +-- Drop fields we no longer need in staff table. +ALTER TABLE `%TABLE_PREFIX%staff` + DROP `append_signature`, + DROP `timezone_offset`; + +-- Drop fields we no longer need in department table. +ALTER TABLE `%TABLE_PREFIX%department` + DROP `can_append_signature`; + +-- Banlist table has been migrated to the email_filter_rule table +DROP TABLE `%TABLE_PREFIX%email_banlist`; diff --git a/include/upgrader/patches/c00511c7-7be60a84.patch.sql b/include/upgrader/patches/c00511c7-7be60a84.patch.sql index 89dbb31435482baa65fc842dcf58e3edbba40cc6..638248b976019a670c773578b564d99a3daacc6a 100644 --- a/include/upgrader/patches/c00511c7-7be60a84.patch.sql +++ b/include/upgrader/patches/c00511c7-7be60a84.patch.sql @@ -302,12 +302,6 @@ CREATE TABLE IF NOT EXISTS `%TABLE_PREFIX%faq_topic` ( PRIMARY KEY (`faq_id`,`topic_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; --- Drop columns we nolonger need - (must be at the very bottom or after session table is created) -ALTER TABLE `%TABLE_PREFIX%config` - DROP COLUMN `ostversion`, - DROP COLUMN `timezone_offset`, - DROP COLUMN `api_passphrase`; - UPDATE `%TABLE_PREFIX%config` SET `schema_signature`='7be60a8432e44989e782d5914ef784d2'; diff --git a/include/upgrader/patches/f8856d56-abe9c0cb.patch.sql b/include/upgrader/patches/f8856d56-abe9c0cb.patch.sql index 192b2c644a80da9ac2ed00bc6974fd985358bbc3..6650754645ae363775d68ac3101f8f5584196f3a 100644 --- a/include/upgrader/patches/f8856d56-abe9c0cb.patch.sql +++ b/include/upgrader/patches/f8856d56-abe9c0cb.patch.sql @@ -28,6 +28,7 @@ CREATE TABLE `%TABLE_PREFIX%ticket_thread` ( PRIMARY KEY (`id`), KEY `ticket_id` (`ticket_id`), KEY `staff_id` (`staff_id`), + KEY `old_pk` (`old_pk`), FULLTEXT KEY `body` (`body`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; @@ -57,7 +58,9 @@ INSERT INTO `%TABLE_PREFIX%ticket_thread` -- Connect responses to (new) messages CREATE TABLE `%TABLE_PREFIX%T_resp_links` - SELECT `id`, `old_pk`, `old_pid` FROM `%TABLE_PREFIX%ticket_thread`; + SELECT `id`, `old_pk`, `old_pid`, `thread_type` + FROM `%TABLE_PREFIX%ticket_thread` + WHERE `thread_type` = 'M'; UPDATE `%TABLE_PREFIX%ticket_thread` SET `pid` = ( SELECT T2.`id` FROM `%TABLE_PREFIX%T_resp_links` T2 diff --git a/scp/logout.php b/scp/logout.php index 32d62d14abb29363df9a7da033a1f0873821cbc9..f167d5a876082b0628f1e64929626444f28a3bb0 100644 --- a/scp/logout.php +++ b/scp/logout.php @@ -21,7 +21,6 @@ $ost->logDebug('Staff logout', $_SESSION['_staff']=array(); session_unset(); session_destroy(); -session_write_close(); @header('Location: login.php'); require('login.php'); ?> diff --git a/scp/upgrade.php b/scp/upgrade.php index d13dc4c3392e90cb7b9e2e225b2a74b244ae002c..c441bd5b71f21addf50d9dd704e92cbaba4128b4 100644 --- a/scp/upgrade.php +++ b/scp/upgrade.php @@ -27,9 +27,10 @@ if($_POST && $_POST['s'] && !$upgrader->isAborted()) { $errors['err']=' Nothing to do! System already upgraded to the current version'; elseif(!$upgrader->isUpgradable()) $errors['err']='The upgrader does NOT support upgrading from the current vesion!'; - elseif($upgrader->check_prereq()) + elseif($upgrader->check_prereq()) { $upgrader->setState('upgrade'); - else + $_SESSION['ost_upgrader'] = null; + } else $errors['prereq']='Minimum requirements not met!'; break; case 'upgrade': //Manual upgrade.... when JS (ajax) is not supported.