diff --git a/include/class.config.php b/include/class.config.php index e54c0d7392d8268c9b273ed2f802a562dcaf20b3..95a5204e389b55c161cf192c1af9511793732e70 100644 --- a/include/class.config.php +++ b/include/class.config.php @@ -93,7 +93,7 @@ class Config { if($this->config['schema_signature']) return $this->config['schema_signature']; elseif($this->config['ostversion']) //old version 1.6 st. - return md5($this->config['ostversion']); + return md5(strtoupper($this->config['ostversion'])); return null; } diff --git a/setup/inc/class.installer.php b/setup/inc/class.installer.php new file mode 100644 index 0000000000000000000000000000000000000000..75ebdc7cdef148a89fd9016e1d1eb62e278f8e39 --- /dev/null +++ b/setup/inc/class.installer.php @@ -0,0 +1,202 @@ +<?php +/********************************************************************* + class.installer.php + + osTicket Intaller - installs the latest version. + + 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: +**********************************************************************/ +require_once INC_DIR.'class.setup.php'; + +class Installer extends SetupWizard { + + var $config; + + function Installer($configfile) { + $this->config =$configfile; + $this->errors=array(); + } + + function getConfigFile() { + return $this->config; + } + + function config_exists() { + return ($this->getConfigFile() && file_exists($this->getConfigFile())); + } + + function config_writable() { + return ($this->getConfigFile() && is_writable($this->getConfigFile())); + } + + function check_config() { + return ($this->config_exists() && $this->config_writable()); + } + + //XXX: Latest version insall logic...no carry over. + function install($vars) { + + $this->errors=$f=array(); + + $f['name'] = array('type'=>'string', 'required'=>1, 'error'=>'Name required'); + $f['email'] = array('type'=>'email', 'required'=>1, 'error'=>'Valid email required'); + $f['fname'] = array('type'=>'string', 'required'=>1, 'error'=>'First name required'); + $f['lname'] = array('type'=>'string', 'required'=>1, 'error'=>'Last name required'); + $f['admin_email'] = array('type'=>'email', 'required'=>1, 'error'=>'Valid email required'); + $f['username'] = array('type'=>'username', 'required'=>1, 'error'=>'Username required'); + $f['passwd'] = array('type'=>'password', 'required'=>1, 'error'=>'Password required'); + $f['passwd2'] = array('type'=>'string', 'required'=>1, 'error'=>'Confirm password'); + $f['prefix'] = array('type'=>'string', 'required'=>1, 'error'=>'Table prefix required'); + $f['dbhost'] = array('type'=>'string', 'required'=>1, 'error'=>'Hostname required'); + $f['dbname'] = array('type'=>'string', 'required'=>1, 'error'=>'Database name required'); + $f['dbuser'] = array('type'=>'string', 'required'=>1, 'error'=>'Username required'); + $f['dbpass'] = array('type'=>'string', 'required'=>1, 'error'=>'password required'); + + + if(!Validator::process($f,$vars,$this->errors) && !$this->errors['err']) + $this->errors['err']='Missing or invalid data - correct the errors and try again.'; + + + //Staff's email can't be same as system emails. + if($vars['admin_email'] && $vars['email'] && !strcasecmp($vars['admin_email'],$vars['email'])) + $this->errors['admin_email']='Conflicts with system email above'; + //Admin's pass confirmation. + if(!$this->errors && strcasecmp($vars['passwd'],$vars['passwd2'])) + $this->errors['passwd2']='passwords to not match!'; + //Check table prefix underscore required at the end! + if($vars['prefix'] && substr($vars['prefix'], -1)!='_') + $this->errors['prefix']='Bad prefix. Must have underscore (_) at the end. e.g \'ost_\''; + + //Make sure admin username is not very predictable. XXX: feels dirty but necessary + if(!$this->errors['username'] && in_array(strtolower($vars['username']),array('admin','admins','username','osticket'))) + $this->errors['username']='Bad username'; + + //MYSQL: Connect to the DB and check the version & database (create database if it doesn't exist!) + if(!$this->errors) { + if(!db_connect($vars['dbhost'],$vars['dbuser'],$vars['dbpass'])) + $this->errors['db']='Unable to connect to MySQL server. Possibly invalid login info.'; + elseif(db_version()< $this->getMySQLVersion()) + $this->errors['db']=sprintf('osTicket requires MySQL %s or better!',$this->getMySQLVersion()); + elseif(!db_select_database($vars['dbname']) && !db_create_database($vars['dbname'])) { + $this->errors['dbname']='Database doesn\'t exist'; + $this->errors['db']='Unable to create the database.'; + } elseif(!db_select_database($vars['dbname'])) { + $this->errors['dbname']='Unable to select the database'; + } + } + + //bailout on errors. + if($this->errors) return false; + + /*************** We're ready to install ************************/ + define('ADMIN_EMAIL',$vars['admin_email']); //Needed to report SQL errors during install. + define('PREFIX',$vars['prefix']); //Table prefix + + $schemaFile =INC_DIR.'sql/osticket-v1.7-mysql.sql'; //DB dump. + $debug = true; //XXX:Change it to true to show SQL errors. + + //Last minute checks. + if(!file_exists($schemaFile)) + $this->errors['err']='Internal Error - please make sure your download is the latest (#1)'; + elseif(!file_exists($this->getConfigFile()) || !($configFile=file_get_contents($this->getConfigFile()))) + $this->errors['err']='Unable to read config file. Permission denied! (#2)'; + elseif(!($fp = @fopen($this->getConfigFile(),'r+'))) + $this->errors['err']='Unable to open config file for writing. Permission denied! (#3)'; + elseif(!$this->load_sql_file($schemaFile,$vars['prefix'], true, $debug)) + $this->errors['err']='Error parsing SQL schema! Get help from developers (#4)'; + + if(!$this->errors) { + //Create admin user. + $sql='INSERT INTO '.PREFIX.'staff SET created=NOW() ' + .', isactive=1, isadmin=1, group_id=1, dept_id=1, timezone_id=8, max_page_size=25 ' + .', email='.db_input($_POST['admin_email']) + .', firstname='.db_input($vars['fname']) + .', lastname='.db_input($vars['lname']) + .', username='.db_input($vars['username']) + .', passwd='.db_input(Passwd::hash($vars['passwd'])); + if(!mysql_query($sql) || !($uid=mysql_insert_id())) + $this->errors['err']='Unable to create admin user (#6)'; + } + + if(!$this->errors) { + //Create config settings---default settings! + //XXX: rename ostversion helpdesk_* ?? + $sql='INSERT INTO '.PREFIX.'config SET updated=NOW(), isonline=0 ' + .', default_email_id=1, alert_email_id=2, default_dept_id=1 ' + .', default_sla_id=1, default_timezone_id=8, default_template_id=1 ' + .', admin_email='.db_input($vars['admin_email']) + .', schema_signature='.db_input(md5_file($schemaFile)) + .', helpdesk_url='.db_input(URL) + .', helpdesk_title='.db_input($vars['name']); + if(!mysql_query($sql) || !($cid=mysql_insert_id())) + $this->errors['err']='Unable to create config settings (#7)'; + } + + if($this->errors) return false; //Abort on internal errors. + + + //Rewrite the config file - MUST be done last to allow for installer recovery. + $configFile= str_replace("define('OSTINSTALLED',FALSE);","define('OSTINSTALLED',TRUE);",$configFile); + $configFile= str_replace('%ADMIN-EMAIL',$vars['admin_email'],$configFile); + $configFile= str_replace('%CONFIG-DBHOST',$vars['dbhost'],$configFile); + $configFile= str_replace('%CONFIG-DBNAME',$vars['dbname'],$configFile); + $configFile= str_replace('%CONFIG-DBUSER',$vars['dbuser'],$configFile); + $configFile= str_replace('%CONFIG-DBPASS',$vars['dbpass'],$configFile); + $configFile= str_replace('%CONFIG-PREFIX',$vars['prefix'],$configFile); + $configFile= str_replace('%CONFIG-SIRI',Misc::randcode(32),$configFile); + if(!$fp || !ftruncate($fp,0) || !fwrite($fp,$configFile)) { + $this->errors['err']='Unable to write to config file. Permission denied! (#5)'; + return false; + } + @fclose($fp); + + /************* Make the system happy ***********************/ + //Create default emails! + $email = $vars['email']; + list(,$domain)=explode('@',$vars['email']); + $sql='INSERT INTO '.PREFIX.'email (`email_id`, `dept_id`, `name`,`email`,`created`,`updated`) VALUES ' + ." (1,1,'Support','$email',NOW(),NOW())" + .",(2,1,'osTicket Alerts','alerts@$domain',NOW(),NOW())" + .",(3,1,'','noreply@$domain',NOW(),NOW())"; + @mysql_query($sql); + + //Create a ticket to make the system warm and happy. + $sql='INSERT INTO '.PREFIX.'ticket SET created=NOW(), status="open", source="Web" ' + .' ,priority_id=2, dept_id=1, topic_id=1 ' + .' ,ticketID='.db_input(Misc::randNumber(6)) + .' ,email="support@osticket.com" ' + .' ,name="osTicket Support" ' + .' ,subject="osTicket Installed!"'; + if(mysql_query($sql) && ($tid=mysql_insert_id())) { + if(!($msg=file_get_contents(INC_DIR.'msg/installed.txt'))) + $msg='Congratulations and Thank you for choosing osTicket!'; + + $sql='INSERT INTO '.PREFIX.'ticket_thread SET created=NOW()' + .', source="Web" ' + .', thread_type="M" ' + .', ticket_id='.db_input($tid) + .', title='.db_input('osTicket Installed') + .', body='.db_input($msg); + @mysql_query($sql); + } + //TODO: create another personalized ticket and assign to admin?? + + //Log a message. + $msg="Congratulations osTicket basic installation completed!\n\nThank you for choosing osTicket!"; + $sql='INSERT INTO '.PREFIX.'syslog SET created=NOW(), updated=NOW(), log_type="Debug" ' + .', title="osTicket installed!"' + .', log='.db_input($msg) + .', ip_address='.db_input($_SERVER['REMOTE_ADDR']); + @mysql_query($sql); + + return true; + } +} +?> diff --git a/setup/inc/class.migrater.php b/setup/inc/class.migrater.php new file mode 100644 index 0000000000000000000000000000000000000000..de8a3d9590e97b9d78ecb905528bcbc1bc2c03a5 --- /dev/null +++ b/setup/inc/class.migrater.php @@ -0,0 +1,67 @@ +<?php +/********************************************************************* + class.migrater.php + + SQL database migrater. This provides the engine capable of rolling the + database for an osTicket installation forward (and perhaps even + backward) in time using a set of included migration scripts. Each script + will roll the database between two database checkpoints. Where possible, + the migrater will roll several checkpoint scripts into one to be applied + together. + + Jared Hancock <jared@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 DatabaseMigrater { + + var $start; + var $end; + var $sqldir; + + function DatabaseMigrater($start, $end, $sqldir) { + + $this->start = $start; + $this->end = $end; + $this->sqldir = $sqldir; + + } + + function getPatches($stop=null) { + + $start= $this->start; + $stop = $stop?$stop:$this->end; + + $patches = array(); + while (true) { + $next = glob($this->sqldir . substr($start, 0, 8) + . '-*.patch.sql'); + if (count($next) == 1) { + $patches[] = $next[0]; + $start = substr(basename($next[0]), 9, 8); + } elseif (count($next) == 0) { + # There are no patches leaving the current signature. We + # have to assume that we've applied all the available + # patches. + break; + } else { + # Problem -- more than one patch exists from this snapshot. + # We probably need a graph approach to solve this. + break; + } + + # Break if we've reached our target stop. + if(!$start || !strncasecmp($start, $stop, 8)) + break; + } + + return $patches; + } +} +?> diff --git a/setup/inc/class.setup.php b/setup/inc/class.setup.php index add91be89f15299203d5ac4b4424f2af92b72957..34bc57486942bca10d9540459dfd8daf37a4f232 100644 --- a/setup/inc/class.setup.php +++ b/setup/inc/class.setup.php @@ -120,453 +120,4 @@ Class SetupWizard { return $this->setError($error); } } - -class Upgrader extends SetupWizard { - - var $prefix; - var $sqldir; - var $signature; - - function Upgrader($signature, $prefix, $sqldir) { - - $this->signature = $signature; - $this->shash = substr($signature, 0, 8); - $this->prefix = $prefix; - $this->sqldir = $sqldir; - $this->errors = array(); - - //Init persistent state of upgrade. - $this->state = &$_SESSION['ost_upgrader'][$this->getShash()]['state']; - - //Init the task Manager. - if(!isset($_SESSION['ost_upgrader'][$this->getShash()])) - $_SESSION['ost_upgrader'][$this->getShash()]['tasks']=array(); - - //Tasks to perform - saved on the session. - $this->tasks = &$_SESSION['ost_upgrader'][$this->getShash()]['tasks']; - } - - function onError($error) { - $this->setError($error); - $this->setState('aborted'); - } - - function isUpgradable() { - return (!$this->isAborted() && $this->getNextPatch()); - } - - function isAborted() { - return !strcasecmp($this->getState(), 'aborted'); - } - - function getSchemaSignature() { - return $this->signature; - } - - function getShash() { - return $this->shash; - } - - function getTablePrefix() { - return $this->prefix; - } - - function getSQLDir() { - return $this->sqldir; - } - - function getState() { - return $this->state; - } - - function setState($state) { - $this->state = $state; - } - - function getNextPatch() { - - if(!($patch=glob($this->getSQLDir().$this->getShash().'-*.patch.sql'))) - return null; - - return $patch[0]; - } - - function getThisPatch() { - - if(!($patch=glob($this->getSQLDir().'*-'.$this->getShash().'.patch.sql'))) - return null; - - return $patch[0]; - - } - - function getNextVersion() { - if(!$patch=$this->getNextPatch()) - return '(Latest)'; - - if(preg_match('/\*(.*)\*/', file_get_contents($patch), $matches)) - $info=$matches[0]; - else - $info=substr(basename($patch), 9, 8); - - return $info; - } - - function getNextAction() { - - $action='Upgrade osTicket to '.$this->getVersion(); - if($this->getNumPendingTasks() && ($task=$this->getNextTask())) { - $action = $task['desc']; - if($task['status']) //Progress report... - $action.=' ('.$task['status'].')'; - } elseif($this->isUpgradable() && ($nextversion = $this->getNextVersion())) { - $action = "Upgrade to $nextversion"; - } - - return $action; - } - - function getNextStepInfo() { - - if(($patches=$this->getPatches())) - return $patches[0]; - - if(($hooks=$this->getScriptedHooks())) - return $hooks[0]['desc']; - - return null; - } - - function getPatches($ToSignature) { - - $signature = $this->getSignature(); - $patches = array(); - while(($patch=glob($this->getSQLDir().substr($signature,0,8).'-*.patch.sql')) && $i++) { - $patches = array_merge($patches, $patch); - if(!($signature=substr(basename($patch[0]), 10, 8)) || !strncasecmp($signature, $ToSignature, 8)) - break; - } - - return $patches; - } - - function getNumPendingTasks() { - - return count($this->getPendingTasks()); - } - - function getPendingTasks() { - - $pending=array(); - if(($tasks=$this->getTasks())) { - foreach($tasks as $k => $task) { - if(!$task['done']) - $pending[$k] = $task; - } - } - - return $pending; - } - - function getTasks() { - return $this->tasks; - } - - function getNextTask() { - - if(!($tasks=$this->getPendingTasks())) - return null; - - return current($tasks); - } - - function removeTask($tId) { - - if(isset($this->tasks[$tId])) - unset($this->tasks[$tId]); - - return (!$this->tasks[$tId]); - } - - function setTaskStatus($tId, $status) { - if(isset($this->tasks[$tId])) - $this->tasks[$tId]['status'] = $status; - } - - function doTasks() { - - if(!($tasks=$this->getPendingTasks())) - return true; //Nothing to do. - - foreach($tasks as $k => $task) { - if(call_user_func(array($this, $task['func']), $k)===0) { - $this->tasks[$k]['done'] = true; - } else { //Task has pending items to process. - break; - } - } - - return (!$this->getPendingTasks()); - } - - function upgrade() { - - if($this->getPendingTasks() || !($patch=$this->getNextPatch())) - return false; - - if(!$this->load_sql_file($patch, $this->getTablePrefix(), true, true)) - return false; - - //TODO: Log the upgrade - - //Load up post install tasks. - $shash = substr(basename($patch), 9, 8); - $phash = substr(basename($patch), 0, 17); - - $tasks=array(); - $tasks[] = array('func' => 'sometask', - 'desc' => 'Some Task.... blah'); - switch($phash) { //Add patch specific scripted tasks. - case 'xxxx': //V1.6 ST- 1.7 * - $tasks[] = array('func' => 'migrateAttachments2DB', - 'desc' => 'Migrating attachments to database, it might take a while depending on the number of files.'); - break; - } - - $tasks[] = array('func' => 'cleanup', - 'desc' => 'Post-upgrade cleanup!'); - - - - //Load up tasks - NOTE: writing directly to the session - back to the future majic. - $_SESSION['ost_upgrader'][$shash]['tasks'] = $tasks; - $_SESSION['ost_upgrader'][$shash]['state'] = 'upgrade'; - - //clear previous patch info - - unset($_SESSION['ost_upgrader'][$this->getSHash()]); - - return true; - } - - /************* TASKS **********************/ - function sometask($tId) { - - $this->setTaskStatus($tId, 'Doing... '.time(). ' #'.$_SESSION['sometask']); - - sleep(2); - $_SESSION['sometask']+=1; - if($_SESSION['sometask']<4) - return 22; - - $_SESSION['sometask']=0; - - return 0; //Change to 1 for testing... - } - - function cleanup($tId=0) { - - $file=$this->getSQLDir().$this->getSchemaSignature().'-cleanup.sql'; - if(!file_exists($file)) //No cleanup script. - return 0; - - //We have a cleanup script ::XXX: Don't abort on error? - if($this->load_sql_file($file, $this->getTablePrefix(), false, true)) - return 0; - - //XXX: ??? - return false; - } - - - function migrateAttachments2DB($tId=0) { - echo "Process attachments here - $tId"; - return 0; - } -} - -/* - Installer class - latest version. - */ -class Installer extends SetupWizard { - - var $config; - - function Installer($configfile) { - $this->config =$configfile; - $this->errors=array(); - } - - function getConfigFile() { - return $this->config; - } - - function config_exists() { - return ($this->getConfigFile() && file_exists($this->getConfigFile())); - } - - function config_writable() { - return ($this->getConfigFile() && is_writable($this->getConfigFile())); - } - - function check_config() { - return ($this->config_exists() && $this->config_writable()); - } - - //XXX: Latest version insall logic...no carry over. - function install($vars) { - - $this->errors=$f=array(); - - $f['name'] = array('type'=>'string', 'required'=>1, 'error'=>'Name required'); - $f['email'] = array('type'=>'email', 'required'=>1, 'error'=>'Valid email required'); - $f['fname'] = array('type'=>'string', 'required'=>1, 'error'=>'First name required'); - $f['lname'] = array('type'=>'string', 'required'=>1, 'error'=>'Last name required'); - $f['admin_email'] = array('type'=>'email', 'required'=>1, 'error'=>'Valid email required'); - $f['username'] = array('type'=>'username', 'required'=>1, 'error'=>'Username required'); - $f['passwd'] = array('type'=>'password', 'required'=>1, 'error'=>'Password required'); - $f['passwd2'] = array('type'=>'string', 'required'=>1, 'error'=>'Confirm password'); - $f['prefix'] = array('type'=>'string', 'required'=>1, 'error'=>'Table prefix required'); - $f['dbhost'] = array('type'=>'string', 'required'=>1, 'error'=>'Hostname required'); - $f['dbname'] = array('type'=>'string', 'required'=>1, 'error'=>'Database name required'); - $f['dbuser'] = array('type'=>'string', 'required'=>1, 'error'=>'Username required'); - $f['dbpass'] = array('type'=>'string', 'required'=>1, 'error'=>'password required'); - - - if(!Validator::process($f,$vars,$this->errors) && !$this->errors['err']) - $this->errors['err']='Missing or invalid data - correct the errors and try again.'; - - - //Staff's email can't be same as system emails. - if($vars['admin_email'] && $vars['email'] && !strcasecmp($vars['admin_email'],$vars['email'])) - $this->errors['admin_email']='Conflicts with system email above'; - //Admin's pass confirmation. - if(!$this->errors && strcasecmp($vars['passwd'],$vars['passwd2'])) - $this->errors['passwd2']='passwords to not match!'; - //Check table prefix underscore required at the end! - if($vars['prefix'] && substr($vars['prefix'], -1)!='_') - $this->errors['prefix']='Bad prefix. Must have underscore (_) at the end. e.g \'ost_\''; - - //Make sure admin username is not very predictable. XXX: feels dirty but necessary - if(!$this->errors['username'] && in_array(strtolower($vars['username']),array('admin','admins','username','osticket'))) - $this->errors['username']='Bad username'; - - //MYSQL: Connect to the DB and check the version & database (create database if it doesn't exist!) - if(!$this->errors) { - if(!db_connect($vars['dbhost'],$vars['dbuser'],$vars['dbpass'])) - $this->errors['db']='Unable to connect to MySQL server. Possibly invalid login info.'; - elseif(db_version()< $this->getMySQLVersion()) - $this->errors['db']=sprintf('osTicket requires MySQL %s or better!',$this->getMySQLVersion()); - elseif(!db_select_database($vars['dbname']) && !db_create_database($vars['dbname'])) { - $this->errors['dbname']='Database doesn\'t exist'; - $this->errors['db']='Unable to create the database.'; - } elseif(!db_select_database($vars['dbname'])) { - $this->errors['dbname']='Unable to select the database'; - } - } - - //bailout on errors. - if($this->errors) return false; - - /*************** We're ready to install ************************/ - define('ADMIN_EMAIL',$vars['admin_email']); //Needed to report SQL errors during install. - define('PREFIX',$vars['prefix']); //Table prefix - - $schemaFile =INC_DIR.'sql/osticket-v1.7-mysql.sql'; //DB dump. - $debug = true; //XXX:Change it to true to show SQL errors. - - //Last minute checks. - if(!file_exists($schemaFile)) - $this->errors['err']='Internal Error - please make sure your download is the latest (#1)'; - elseif(!file_exists($this->getConfigFile()) || !($configFile=file_get_contents($this->getConfigFile()))) - $this->errors['err']='Unable to read config file. Permission denied! (#2)'; - elseif(!($fp = @fopen($this->getConfigFile(),'r+'))) - $this->errors['err']='Unable to open config file for writing. Permission denied! (#3)'; - elseif(!$this->load_sql_file($schemaFile,$vars['prefix'], true, $debug)) - $this->errors['err']='Error parsing SQL schema! Get help from developers (#4)'; - - if(!$this->errors) { - //Create admin user. - $sql='INSERT INTO '.PREFIX.'staff SET created=NOW() ' - .', isactive=1, isadmin=1, group_id=1, dept_id=1, timezone_id=8, max_page_size=25 ' - .', email='.db_input($_POST['admin_email']) - .', firstname='.db_input($vars['fname']) - .', lastname='.db_input($vars['lname']) - .', username='.db_input($vars['username']) - .', passwd='.db_input(Passwd::hash($vars['passwd'])); - if(!mysql_query($sql) || !($uid=mysql_insert_id())) - $this->errors['err']='Unable to create admin user (#6)'; - } - - if(!$this->errors) { - //Create config settings---default settings! - //XXX: rename ostversion helpdesk_* ?? - $sql='INSERT INTO '.PREFIX.'config SET updated=NOW(), isonline=0 ' - .', default_email_id=1, alert_email_id=2, default_dept_id=1 ' - .', default_sla_id=1, default_timezone_id=8, default_template_id=1 ' - .', admin_email='.db_input($vars['admin_email']) - .', schema_signature='.db_input(md5_file($schemaFile)) - .', helpdesk_url='.db_input(URL) - .', helpdesk_title='.db_input($vars['name']); - if(!mysql_query($sql) || !($cid=mysql_insert_id())) - $this->errors['err']='Unable to create config settings (#7)'; - } - - if($this->errors) return false; //Abort on internal errors. - - - //Rewrite the config file - MUST be done last to allow for installer recovery. - $configFile= str_replace("define('OSTINSTALLED',FALSE);","define('OSTINSTALLED',TRUE);",$configFile); - $configFile= str_replace('%ADMIN-EMAIL',$vars['admin_email'],$configFile); - $configFile= str_replace('%CONFIG-DBHOST',$vars['dbhost'],$configFile); - $configFile= str_replace('%CONFIG-DBNAME',$vars['dbname'],$configFile); - $configFile= str_replace('%CONFIG-DBUSER',$vars['dbuser'],$configFile); - $configFile= str_replace('%CONFIG-DBPASS',$vars['dbpass'],$configFile); - $configFile= str_replace('%CONFIG-PREFIX',$vars['prefix'],$configFile); - $configFile= str_replace('%CONFIG-SIRI',Misc::randcode(32),$configFile); - if(!$fp || !ftruncate($fp,0) || !fwrite($fp,$configFile)) { - $this->errors['err']='Unable to write to config file. Permission denied! (#5)'; - return false; - } - @fclose($fp); - - /************* Make the system happy ***********************/ - //Create default emails! - $email = $vars['email']; - list(,$domain)=explode('@',$vars['email']); - $sql='INSERT INTO '.PREFIX.'email (`email_id`, `dept_id`, `name`,`email`,`created`,`updated`) VALUES ' - ." (1,1,'Support','$email',NOW(),NOW())" - .",(2,1,'osTicket Alerts','alerts@$domain',NOW(),NOW())" - .",(3,1,'','noreply@$domain',NOW(),NOW())"; - @mysql_query($sql); - - //Create a ticket to make the system warm and happy. - $sql='INSERT INTO '.PREFIX.'ticket SET created=NOW(), status="open", source="Web" ' - .' ,priority_id=2, dept_id=1, topic_id=1 ' - .' ,ticketID='.db_input(Misc::randNumber(6)) - .' ,email="support@osticket.com" ' - .' ,name="osTicket Support" ' - .' ,subject="osTicket Installed!"'; - if(mysql_query($sql) && ($tid=mysql_insert_id())) { - if(!($msg=file_get_contents(INC_DIR.'msg/installed.txt'))) - $msg='Congratulations and Thank you for choosing osTicket!'; - - $sql='INSERT INTO '.PREFIX.'ticket_thread SET created=NOW(),source="Web" ' - .', poster="System"' - .', ticket_id='.db_input($tid) - .', body='.db_input($msg); - @mysql_query($sql); - } - //TODO: create another personalized ticket and assign to admin?? - - //Log a message. - $msg="Congratulations osTicket basic installation completed!\n\nThank you for choosing osTicket!"; - $sql='INSERT INTO '.PREFIX.'syslog SET created=NOW(),updated=NOW(),log_type="Debug" ' - .', title="osTicket installed!"' - .', log='.db_input($msg) - .', ip_address='.db_input($_SERVER['REMOTE_ADDR']); - @mysql_query($sql); - - return true; - } -} ?> diff --git a/setup/inc/class.upgrader.php b/setup/inc/class.upgrader.php new file mode 100644 index 0000000000000000000000000000000000000000..cd785a9d2f0b0709483a39e8ac4effaed67589ac --- /dev/null +++ b/setup/inc/class.upgrader.php @@ -0,0 +1,277 @@ +<?php +/********************************************************************* + class.upgrader.php + + osTicket Upgrader + + 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: +**********************************************************************/ + +require_once INC_DIR.'class.setup.php'; +require_once INC_DIR.'class.migrater.php'; + +class Upgrader extends SetupWizard { + + var $prefix; + var $sqldir; + var $signature; + + function Upgrader($signature, $prefix, $sqldir) { + + $this->signature = $signature; + $this->shash = substr($signature, 0, 8); + $this->prefix = $prefix; + $this->sqldir = $sqldir; + $this->errors = array(); + + //Init persistent state of upgrade. + $this->state = &$_SESSION['ost_upgrader'][$this->getShash()]['state']; + + //Init the task Manager. + if(!isset($_SESSION['ost_upgrader'][$this->getShash()])) + $_SESSION['ost_upgrader'][$this->getShash()]['tasks']=array(); + + //Tasks to perform - saved on the session. + $this->tasks = &$_SESSION['ost_upgrader'][$this->getShash()]['tasks']; + + //Database migrater + $this->migrater = new DatabaseMigrater($this->signature, SCHEMA_SIGNATURE, $this->sqldir); + } + + function getStops() { + return array('7be60a84' => 'migrateAttachments2DB'); + } + + function onError($error) { + $this->setError($error); + $this->setState('aborted'); + } + + function isUpgradable() { + return (!$this->isAborted() && $this->getNextPatch()); + } + + function isAborted() { + return !strcasecmp($this->getState(), 'aborted'); + } + + function getSchemaSignature() { + return $this->signature; + } + + function getShash() { + return $this->shash; + } + + function getTablePrefix() { + return $this->prefix; + } + + function getSQLDir() { + return $this->sqldir; + } + + function getState() { + return $this->state; + } + + function setState($state) { + $this->state = $state; + } + + function getPatches() { + return $this->migrater->getPatches(); + } + + function getNextPatch() { + $p = $this->getPatches(); + return (count($p)) ? $p[0] : false; + } + + function getNextVersion() { + if(!$patch=$this->getNextPatch()) + return '(Latest)'; + + $info = $this->readPatchInfo($patch); + return $info['version']; + } + + function readPatchInfo($patch) { + $info = array(); + if (preg_match('/\*(.*)\*/', file_get_contents($patch), $matches)) { + if (preg_match('/@([\w\d_-]+)\s+(.*)$/', $matches[0], $matches2)) + foreach ($matches2 as $match) + $info[$match[0]] = $match[1]; + } + if (!isset($info['version'])) + $info['version'] = substr(basename($patch), 9, 8); + return $info; + } + + function getNextAction() { + + $action='Upgrade osTicket to '.$this->getVersion(); + if($this->getNumPendingTasks() && ($task=$this->getNextTask())) { + $action = $task['desc']; + if($task['status']) //Progress report... + $action.=' ('.$task['status'].')'; + } elseif($this->isUpgradable() && ($nextversion = $this->getNextVersion())) { + $action = "Upgrade to $nextversion"; + } + + return $action; + } + + function getNextStepInfo() { + + if(($patches=$this->getPatches())) + return $patches[0]; + + if(($hooks=$this->getScriptedHooks())) + return $hooks[0]['desc']; + + return null; + } + + function getNumPendingTasks() { + + return count($this->getPendingTasks()); + } + + function getPendingTasks() { + + $pending=array(); + if(($tasks=$this->getTasks())) { + foreach($tasks as $k => $task) { + if(!$task['done']) + $pending[$k] = $task; + } + } + + return $pending; + } + + function getTasks() { + return $this->tasks; + } + + function getNextTask() { + + if(!($tasks=$this->getPendingTasks())) + return null; + + return current($tasks); + } + + function removeTask($tId) { + + if(isset($this->tasks[$tId])) + unset($this->tasks[$tId]); + + return (!$this->tasks[$tId]); + } + + function setTaskStatus($tId, $status) { + if(isset($this->tasks[$tId])) + $this->tasks[$tId]['status'] = $status; + } + + function doTasks() { + + if(!($tasks=$this->getPendingTasks())) + return true; //Nothing to do. + + foreach($tasks as $k => $task) { + if(call_user_func(array($this, $task['func']), $k)===0) { + $this->tasks[$k]['done'] = true; + } else { //Task has pending items to process. + break; + } + } + + return (!$this->getPendingTasks()); + } + + function upgrade() { + + if($this->getPendingTasks() || !($patches=$this->getPatches())) + return false; + + foreach ($patches as $patch) { + if (!$this->load_sql_file($patch, $this->getTablePrefix())) + return false; + + //TODO: Log the upgrade + + + //clear previous patch info - + unset($_SESSION['ost_upgrader'][$this->getSHash()]); + + //Load up post-upgrade tasks.... if any. + $phash = substr(basename($patch), 0, 17); + if(!($tasks=$this->getTasksForPatch($phash))) + continue; + + //We have tasks to perform - set the tasks and break. + $shash = substr($phash, 9, 8); + $_SESSION['ost_upgrader'][$shash]['tasks'] = $tasks; + $_SESSION['ost_upgrader'][$shash]['state'] = 'upgrade'; + break; + } + + return true; + + } + + function getTasksForPatch($phash) { + + $tasks=array(); + switch($phash) { //Add patch specific scripted tasks. + case 'd4fe13b1-7be60a84': //V1.6 ST- 1.7 * + $tasks[] = array('func' => 'migrateAttachments2DB', + 'desc' => 'Migrating attachments to database, it might take a while depending on the number of files.'); + break; + } + + //Check if cleanup p + $file=$this->getSQLDir().$phash.'.cleanup.sql'; + if(file_exists($file)) + $tasks[] = array('func' => 'cleanup', 'desc' => 'Post-upgrade cleanup!'); + + + return $tasks; + } + + /************* TASKS **********************/ + function cleanup($tId=0) { + + $file=$this->getSQLDir().$this->getSHash().'-cleanup.sql'; + if(!file_exists($file)) //No cleanup script. + return 0; + + //We have a cleanup script ::XXX: Don't abort on error? + if($this->load_sql_file($file, $this->getTablePrefix(), false, true)) + return 0; + + //XXX: ??? + return false; + } + + + function migrateAttachments2DB($tId=0) { + echo "Process attachments here - $tId"; + $att_migrater = new AttachmentMigrater(); + $att_migrater->start_migration(); + # XXX: Loop here (with help of task manager) + $att_migrater->do_batch(); + return 0; + } +} +?> diff --git a/setup/inc/sql/522e5b78-02decaa2.patch.sql b/setup/inc/sql/522e5b78-02decaa2.patch.sql index a6d9a6e09cc1c16aac70dc6a9b4a0f03987a6c9b..78c951d69cc10f255ffb3e4ba85fcf93dae6db58 100644 --- a/setup/inc/sql/522e5b78-02decaa2.patch.sql +++ b/setup/inc/sql/522e5b78-02decaa2.patch.sql @@ -1,4 +1,6 @@ -/* v1.7-DPR2-P2 */ +/** + * @version v1.7-DPR2-P2 + */ UPDATE `%TABLE_PREFIX%sla` SET `created` = NOW(), `updated` = NOW() diff --git a/setup/inc/sql/7be60a84-522e5b78.patch.sql b/setup/inc/sql/7be60a84-522e5b78.patch.sql index 35e744566d50f8a5e8d37d56c3fe3b795db2e1e5..acdaf7d0d3c1f8baaedd40bd68e33b01b97e72c9 100644 --- a/setup/inc/sql/7be60a84-522e5b78.patch.sql +++ b/setup/inc/sql/7be60a84-522e5b78.patch.sql @@ -1,4 +1,6 @@ -/* v1.7-DPR1 (P1) */ +/** + * @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; diff --git a/setup/install.php b/setup/install.php index 27b1388933d03ef9c0db5690dd147213848d750f..d019598e55de7099c9dbb517b4a9aa1663886ad0 100644 --- a/setup/install.php +++ b/setup/install.php @@ -15,6 +15,9 @@ **********************************************************************/ require('setup.inc.php'); +require_once INC_DIR.'class.installer.php'; + + //define('OSTICKET_CONFIGFILE','../include/ost-config.php'); //osTicket config file full path. define('OSTICKET_CONFIGFILE','../include/ost-config.php'); //XXX: Make sure the path is corrent b4 releasing. diff --git a/setup/p.php b/setup/p.php index b508c9303f1b33a951b15e7dbafc8e0047c3ff3a..ebc4128b3455ac4063425bb9802abc856ff2c0e9 100644 --- a/setup/p.php +++ b/setup/p.php @@ -27,7 +27,8 @@ if(!$thisstaff or !$thisstaff->isadmin()) { define('SETUPINC', true); define('INC_DIR', './inc/'); define('SQL_DIR', INC_DIR.'sql/'); -require_once INC_DIR.'class.setup.php'; + +require_once INC_DIR.'class.upgrader.php'; $upgrader = new Upgrader($cfg->getSchemaSignature(), TABLE_PREFIX, SQL_DIR); diff --git a/setup/setup.inc.php b/setup/setup.inc.php index d8108e079c5a0df0411ff57cce4d1ecb97eb9e87..44b2ad4d593f5521b66ad170c9e801a817cf74f1 100644 --- a/setup/setup.inc.php +++ b/setup/setup.inc.php @@ -52,7 +52,6 @@ ini_set('include_path', './'.PATH_SEPARATOR.INC_DIR.PATH_SEPARATOR.INCLUDE_DIR.P endif; #required files -require_once(INC_DIR.'class.setup.php'); require_once(INCLUDE_DIR.'class.validator.php'); require_once(INCLUDE_DIR.'class.format.php'); require_once(INCLUDE_DIR.'class.misc.php'); diff --git a/setup/upgrade.php b/setup/upgrade.php index c70d183ffe290de4a09ade74b1ff7ec47bd4acde..324c467efd72d887b7592af33f6ba201c6f26e22 100644 --- a/setup/upgrade.php +++ b/setup/upgrade.php @@ -30,7 +30,8 @@ if(!$thisstaff or !$thisstaff->isadmin()) { define('SETUPINC', true); define('INC_DIR', './inc/'); define('SQL_DIR', INC_DIR.'sql/'); -require_once INC_DIR.'class.setup.php'; + +require_once INC_DIR.'class.upgrader.php'; //$_SESSION['ost_upgrader']=null; $upgrader = new Upgrader($cfg->getSchemaSignature(), TABLE_PREFIX, SQL_DIR); @@ -48,7 +49,9 @@ if($_POST && $_POST['s'] && !$upgrader->isAborted()) { case 'prereq': //XXX: check if it's upgradable version?? if(!$cfg->isUpgradePending()) - $errors['err']=' Nothing to do! System already upgraded to the current version'; + $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()) $upgrader->setState('upgrade'); else @@ -88,6 +91,8 @@ switch(strtolower($upgrader->getState())) { $inc='upgrade-aborted.inc.php'; elseif(!$cfg->isUpgradePending()) $errors['err']='Nothing to do! System already upgraded to the latest version'; + elseif(!$upgrader->isUpgradable()) + $errors['err']='The upgrader does NOT support upgrading from the current vesion!'; } require(INC_DIR.'header.inc.php');