diff --git a/phpgwapi/inc/class.setup.inc.php b/phpgwapi/inc/class.setup.inc.php new file mode 100644 index 0000000000..6195bb1011 --- /dev/null +++ b/phpgwapi/inc/class.setup.inc.php @@ -0,0 +1,761 @@ + * + * and Dan Kuykendall * + * and Mark Peters * + * and Miles Lott * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + class setup + { + var $db; + + var $detection = ''; + var $process = ''; + var $lang = ''; + var $html = ''; + var $appreg = ''; + + function setup($html=False, $translation=False) + { + $this->detection = CreateObject('phpgwapi.setup_detection'); + $this->process = CreateObject('phpgwapi.setup_process'); + $this->appreg = CreateObject('phpgwapi.app_registry'); + + /* The setup application needs these */ + $this->html = $html ? CreateObject('phpgwapi.setup_html') : ''; + $this->translation = $translation ? CreateObject('phpgwapi.setup_translation') : ''; + } + + /*! + @function loaddb + @abstract include api db class for the ConfigDomain and connect to the db + */ + function loaddb() + { + $GLOBALS['ConfigDomain'] = get_var('ConfigDomain',array('COOKIE','POST')); + + if(empty($GLOBALS['ConfigDomain'])) + { + /* This is to fix the reading of this value immediately after the cookie was set on login */ + $GLOBALS['ConfigDomain'] = @$GLOBALS['HTTP_POST_VARS']['FormDomain'] ? @$GLOBALS['HTTP_POST_VARS']['FormDomain'] : 'default'; + } + + $GLOBALS['phpgw_info']['server']['db_type'] = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_type']; + + $this->db = CreateObject('phpgwapi.db'); + $this->db->Host = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_host']; + $this->db->Type = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_type']; + $this->db->Database = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_name']; + $this->db->User = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_user']; + $this->db->Password = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_pass']; + } + + /*! + @function auth + @abstract authenticate the setup user + @param $auth_type ??? + */ + function auth($auth_type='Config') + { + $FormLogout = get_var('FormLogout', array('GET','POST')); + $ConfigLogin = get_var('ConfigLogin', array('POST','COOKIE')); + $HeaderLogin = get_var('HeaderLogin', array('POST','COOKIE')); + $FormDomain = get_var('FormDomain', array('POST')); + $FormPW = get_var('FormPW', array('POST')); + $ConfigDomain = get_var('ConfigDomain',array('POST','COOKIE')); + $ConfigPW = get_var('ConfigPW', array('POST','COOKIE')); + $HeaderPW = get_var('HeaderPW', array('COOKIE','POST')); + $ConfigLang = get_var('ConfigLang', array('POST','COOKIE')); + + if(isset($FormLogout) && !empty($FormLogout)) + { + if($FormLogout == 'config' || + $FormLogout == 'ldap' || + $FormLogout == 'ldapexport' || + $FormLogout == 'ldapimport' || + $FormLogout == 'sqltoarray') + { + setcookie('ConfigPW',''); /* scrub the old one */ + setcookie('ConfigDomain',''); /* scrub the old one */ + setcookie('ConfigLang',''); + $GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = 'You have successfully logged out'; + $GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = ''; + return False; + } + elseif($FormLogout == 'header') + { + setcookie('HeaderPW',''); /* scrub the old one */ + $GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = 'You have successfully logged out'; + $GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = ''; + return False; + } + } + elseif(isset($ConfigPW) && !empty($ConfigPW)) + { + if($ConfigPW != $GLOBALS['phpgw_domain'][$ConfigDomain]['config_passwd'] && $auth_type == 'Config') + { + setcookie('ConfigPW',''); /* scrub the old one */ + setcookie('ConfigDomain',''); /* scrub the old one */ + setcookie('ConfigLang',''); + $GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = 'Invalid session cookie (cookies must be enabled)'; + $GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = ''; + return False; + } + else + { + return True; + } + } + elseif(isset($FormPW) && !empty($FormPW)) + { + if(isset($ConfigLogin)) + { + if($FormPW == $GLOBALS['phpgw_domain'][$FormDomain]['config_passwd'] && $auth_type == 'Config') + { + setcookie('HeaderPW',''); /* scrub the old one */ + setcookie('ConfigPW',"$FormPW"); + setcookie('ConfigDomain',"$FormDomain"); + setcookie('ConfigLang',"$ConfigLang"); + $ConfigDomain = "$FormDomain"; + return True; + } + else + { + $GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = 'Invalid password'; + $GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = ''; + return False; + } + } + elseif(isset($HeaderLogin) && !empty($HeaderLogin)) + { + if($FormPW == $GLOBALS['phpgw_info']['server']['header_admin_password'] && $auth_type == 'Header') + { + setcookie('HeaderPW',"$FormPW"); + return True; + } + else + { + $GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = 'Invalid password'; + $GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = ''; + return False; + } + } + } + elseif(isset($HeaderPW) && !empty($HeaderPW)) + { + if($HeaderPW != $GLOBALS['phpgw_info']['server']['header_admin_password'] && $auth_type == 'Header') + { + setcookie('HeaderPW',''); /* scrub the old one */ + $GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = 'Invalid session cookie (cookies must be enabled)'; + $GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = ''; + return False; + } + else + { + return True; + } + } + else + { + return False; + } + } + + /*! + @function get_major + @abstract Return X.X.X major version from X.X.X.X versionstring + @param $ + */ + function get_major($versionstring) + { + if(!$versionstring) + { + return False; + } + + $version = ereg_replace('pre','.',$versionstring); + $varray = explode('.',$version); + $major = implode('.',array($varray[0],$varray[1],$varray[2])); + + return $major; + } + + /*! + @function clear_session_cache + @abstract Clear system/user level cache so as to have it rebuilt with the next access + @param None + */ + function clear_session_cache() + { + $tablenames = @$this->db->table_names(); + while(list($key,$val) = @each($tablenames)) + { + $tables[] = $val['table_name']; + } + if(in_array('phpgw_app_sessions',$tables)) + { + $this->db->lock(array('phpgw_app_sessions')); + @$this->db->query("DELETE FROM phpgw_app_sessions WHERE sessionid = '0' and loginid = '0' and app = 'phpgwapi' and location = 'config'",__LINE__,__FILE__); + @$this->db->query("DELETE FROM phpgw_app_sessions WHERE app = 'phpgwapi' and location = 'phpgw_info_cache'",__LINE__,__FILE__); + $this->db->unlock(); + } + } + + /*! + @function register_app + @abstract Add an application to the phpgw_applications table + @param $appname Application 'name' with a matching $setup_info[$appname] array slice + @param $enable optional, set to True/False to override setup.inc.php setting + */ + function register_app($appname,$enable=99) + { + $setup_info = $GLOBALS['setup_info']; + + if(!$appname) + { + return False; + } + + if($enable==99) + { + $enable = $setup_info[$appname]['enable']; + } + $enable = intval($enable); + + /* + Use old applications table if the currentver is less than 0.9.10pre8, + but not if the currentver = '', which probably means new install. + */ + if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.10pre8') && ($setup_info['phpgwapi']['currentver'] != '')) + { + $appstbl = 'applications'; + } + else + { + $appstbl = 'phpgw_applications'; + if($this->amorethanb($setup_info['phpgwapi']['currentver'],'0.9.13.014')) + { + $use_appid = True; + } + } + + if($GLOBALS['DEBUG']) + { + echo '
register_app(): ' . $appname . ', version: ' . $setup_info[$appname]['version'] . ', table: ' . $appstbl . '
'; + // _debug_array($setup_info[$appname]); + } + + if($setup_info[$appname]['version']) + { + if($setup_info[$appname]['tables']) + { + $tables = implode(',',$setup_info[$appname]['tables']); + } + if($use_appid) + { + $this->db->query("SELECT MAX(app_id) FROM $appstbl"); + $this->db->next_record(); + if($this->db->f(0)) + { + $app_id = ($this->db->f(0) + 1) . ','; + $app_idstr = 'app_id,'; + } + else + { + srand(100000); + $app_id = rand(1,100000) . ','; + $app_idstr = 'app_id,'; + } + } + $this->db->query("INSERT INTO $appstbl " + . "($app_idstr app_name,app_title,app_enabled,app_order,app_tables,app_version) " + . "VALUES (" + . $app_id + . "'" . $setup_info[$appname]['name'] . "'," + . "'" . $setup_info[$appname]['title'] . "'," + . $enable . "," + . intval($setup_info[$appname]['app_order']) . "," + . "'" . $tables . "'," + . "'" . $setup_info[$appname]['version'] . "');" + ); + $this->clear_session_cache(); + } + } + + /*! + @function app_registered + @abstract Check if an application has info in the db + @param $appname Application 'name' with a matching $setup_info[$appname] array slice + @param $enabled optional, set to False to not enable this app + */ + function app_registered($appname) + { + $setup_info = $GLOBALS['setup_info']; + + if(!$appname) + { + return False; + } + + if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.10pre8') && ($setup_info['phpgwapi']['currentver'] != '')) + { + $appstbl = 'applications'; + } + else + { + $appstbl = 'phpgw_applications'; + } + + if(@$GLOBALS['DEBUG']) + { + echo '
app_registered(): checking ' . $appname . ', table: ' . $appstbl; + // _debug_array($setup_info[$appname]); + } + + $this->db->query("SELECT COUNT(app_name) FROM $appstbl WHERE app_name='".$appname."'"); + $this->db->next_record(); + if($this->db->f(0)) + { + if(@$GLOBALS['DEBUG']) + { + echo '... app previously registered.'; + } + return True; + } + if(@$GLOBALS['DEBUG']) + { + echo '... app not registered'; + } + return False; + } + + /*! + @function update_app + @abstract Update application info in the db + @param $appname Application 'name' with a matching $setup_info[$appname] array slice + @param $enabled optional, set to False to not enable this app + */ + function update_app($appname) + { + $setup_info = $GLOBALS['setup_info']; + + if(!$appname) + { + return False; + } + + if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.10pre8') && ($setup_info['phpgwapi']['currentver'] != '')) + { + $appstbl = 'applications'; + } + else + { + $appstbl = 'phpgw_applications'; + } + + if($GLOBALS['DEBUG']) + { + echo '
update_app(): ' . $appname . ', version: ' . $setup_info[$appname]['currentver'] . ', table: ' . $appstbl . '
'; + // _debug_array($setup_info[$appname]); + } + + $this->db->query("SELECT COUNT(app_name) FROM $appstbl WHERE app_name='".$appname."'"); + $this->db->next_record(); + if(!$this->db->f(0)) + { + return False; + } + + if($setup_info[$appname]['version']) + { + //echo '
' . $setup_info[$appname]['version']; + if($setup_info[$appname]['tables']) + { + $tables = implode(',',$setup_info[$appname]['tables']); + } + + $sql = "UPDATE $appstbl " + . "SET app_name='" . $setup_info[$appname]['name'] . "'," + . " app_title='" . $setup_info[$appname]['title'] . "'," + . " app_enabled=" . intval($setup_info[$appname]['enable']) . "," + . " app_order=" . intval($setup_info[$appname]['app_order']) . "," + . " app_tables='" . $tables . "'," + . " app_version='" . $setup_info[$appname]['version'] . "'" + . " WHERE app_name='" . $appname . "'"; + //echo $sql; exit; + + $this->db->query($sql); + } + } + + /*! + @function update_app_version + @abstract Update application version in applications table, post upgrade + @param $setup_info Array of application information (multiple apps or single) + @param $appname Application 'name' with a matching $setup_info[$appname] array slice + @param $tableschanged ??? + */ + function update_app_version($setup_info, $appname, $tableschanged = True) + { + if(!$appname) + { + return False; + } + + if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.10pre8') && ($setup_info['phpgwapi']['currentver'] != '')) + { + $appstbl = 'applications'; + } + else + { + $appstbl = 'phpgw_applications'; + } + + if($tableschanged == True) + { + $GLOBALS['phpgw_info']['setup']['tableschanged'] = True; + } + if($setup_info[$appname]['currentver']) + { + $this->db->query("UPDATE $appstbl SET app_version='" . $setup_info[$appname]['currentver'] . "' WHERE app_name='".$appname."'"); + } + return $setup_info; + } + + /*! + @function deregister_app + @abstract de-Register an application + @param $appname Application 'name' with a matching $setup_info[$appname] array slice + */ + function deregister_app($appname) + { + if(!$appname) + { + return False; + } + $setup_info = $GLOBALS['setup_info']; + + if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.10pre8') && ($setup_info['phpgwapi']['currentver'] != '')) + { + $appstbl = 'applications'; + } + else + { + $appstbl = 'phpgw_applications'; + } + + //echo 'DELETING application: ' . $appname; + $this->db->query("DELETE FROM $appstbl WHERE app_name='". $appname ."'"); + $this->clear_session_cache(); + } + + /*! + @function register_hooks + @abstract Register an application's hooks + @param $appname Application 'name' with a matching $setup_info[$appname] array slice + */ + function register_hooks($appname) + { + $setup_info = $GLOBALS['setup_info']; + + if(!$appname) + { + return False; + } + + if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.8pre5') && ($setup_info['phpgwapi']['currentver'] != '')) + { + /* No phpgw_hooks table yet. */ + return False; + } + + $this->db->query("SELECT COUNT(hook_appname) FROM phpgw_hooks WHERE hook_appname='".$appname."'"); + $this->db->next_record(); + if($this->db->f(0)) + { + $this->deregister_hooks($appname); + } + + //echo "ADDING hooks for: " . $setup_info[$appname]['name']; + if(is_array($setup_info[$appname]['hooks'])) + { + while(list($key,$hook) = each($setup_info[$appname]['hooks'])) + { + $this->db->query("INSERT INTO phpgw_hooks " + . "(hook_appname,hook_location,hook_filename) " + . "VALUES (" + . "'" . $setup_info[$appname]['name'] . "'," + . "'" . $hook . "'," + . "'" . "hook_" . $hook . ".inc.php" . "');" + ); + } + } + } + + /*! + @function update_hooks + @abstract Update an application's hooks + @param $appname Application 'name' with a matching $setup_info[$appname] array slice + */ + function update_hooks($appname) + { + $setup_info = $GLOBALS['setup_info']; + + if(!$appname) + { + return False; + } + + if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.8pre5')) + { + /* No phpgw_hooks table yet. */ + return False; + } + + $this->db->query("SELECT COUNT(*) FROM phpgw_hooks WHERE hook_appname='".$appname."'"); + $this->db->next_record(); + if(!$this->db->f(0)) + { + return False; + } + + if($setup_info[$appname]['version']) + { + if(is_array($setup_info[$appname]['hooks'])) + { + $this->deregister_hooks($appname); + $this->register_hooks($appname); + } + } + } + + /*! + @function deregister_hooks + @abstract de-Register an application's hooks + @param $appname Application 'name' with a matching $setup_info[$appname] array slice + */ + function deregister_hooks($appname) + { + if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.8pre5')) + { + /* No phpgw_hooks table yet. */ + return False; + } + + if(!$appname) + { + return False; + } + + //echo "DELETING hooks for: " . $setup_info[$appname]['name']; + $this->db->query("DELETE FROM phpgw_hooks WHERE hook_appname='". $appname ."'"); + } + + /*! + @function hook + @abstract call the hooks for a single application + @param $location hook location - required + @param $appname application name - optional + */ + function hook($location, $appname='') + { + if(!$appname) + { + $appname = $GLOBALS['phpgw_info']['flags']['currentapp']; + } + $SEP = filesystem_separator(); + + $f = PHPGW_SERVER_ROOT . $SEP . $appname . $SEP . 'inc' . $SEP . 'hook_' . $location . '.inc.php'; + if(file_exists($f)) + { + include($f); + return True; + } + else + { + return False; + } + } + + /* + @function alessthanb + @abstract phpgw version checking, is param 1 < param 2 in phpgw versionspeak? + @param $a phpgw version number to check if less than $b + @param $b phpgw version number to check $a against + #return True if $a < $b + */ + function alessthanb($a,$b,$DEBUG=False) + { + $num = array('1st','2nd','3rd','4th'); + + if($DEBUG) + { + echo'
Input values: ' + . 'A="'.$a.'", B="'.$b.'"'; + } + $newa = ereg_replace('pre','.',$a); + $newb = ereg_replace('pre','.',$b); + $testa = explode('.',$newa); + if(@$testa[1] == '') + { + $testa[1] = 0; + } + if(@$testa[3] == '') + { + $testa[3] = 0; + } + $testb = explode('.',$newb); + if(@$testb[1] == '') + { + $testb[1] = 0; + } + if(@$testb[3] == '') + { + $testb[3] = 0; + } + $less = 0; + + for($i=0;$iChecking if '. intval($testa[$i]) . ' is less than ' . intval($testb[$i]) . ' ...'; } + if(intval($testa[$i]) < intval($testb[$i])) + { + if ($DEBUG) { echo ' yes.'; } + $less++; + if($i<3) + { + /* Ensure that this is definitely smaller */ + if($DEBUG) { echo" This is the $num[$i] octet, so A is definitely less than B."; } + $less = 5; + break; + } + } + elseif(intval($testa[$i]) > intval($testb[$i])) + { + if($DEBUG) { echo ' no.'; } + $less--; + if($i<2) + { + /* Ensure that this is definitely greater */ + if($DEBUG) { echo" This is the $num[$i] octet, so A is definitely greater than B."; } + $less = -5; + break; + } + } + else + { + if($DEBUG) { echo ' no, they are equal.'; } + $less = 0; + } + } + if($DEBUG) { echo '
Check value is: "'.$less.'"'; } + if($less>0) + { + if($DEBUG) { echo '
A is less than B'; } + return True; + } + elseif($less<0) + { + if($DEBUG) { echo '
A is greater than B'; } + return False; + } + else + { + if($DEBUG) { echo '
A is equal to B'; } + return False; + } + } + + /*! + @function amorethanb + @abstract phpgw version checking, is param 1 > param 2 in phpgw versionspeak? + @param $a phpgw version number to check if more than $b + @param $b phpgw version number to check $a against + #return True if $a < $b + */ + function amorethanb($a,$b,$DEBUG=False) + { + $num = array('1st','2nd','3rd','4th'); + + if($DEBUG) + { + echo'
Input values: ' + . 'A="'.$a.'", B="'.$b.'"'; + } + $newa = ereg_replace('pre','.',$a); + $newb = ereg_replace('pre','.',$b); + $testa = explode('.',$newa); + if($testa[3] == '') + { + $testa[3] = 0; + } + $testb = explode('.',$newb); + if($testb[3] == '') + { + $testb[3] = 0; + } + $less = 0; + + for($i=0;$iChecking if '. intval($testa[$i]) . ' is more than ' . intval($testb[$i]) . ' ...'; } + if(intval($testa[$i]) > intval($testb[$i])) + { + if($DEBUG) { echo ' yes.'; } + $less++; + if($i<3) + { + /* Ensure that this is definitely greater */ + if($DEBUG) { echo" This is the $num[$i] octet, so A is definitely greater than B."; } + $less = 5; + break; + } + } + elseif(intval($testa[$i]) < intval($testb[$i])) + { + if($DEBUG) { echo ' no.'; } + $less--; + if($i<2) + { + /* Ensure that this is definitely smaller */ + if($DEBUG) { echo" This is the $num[$i] octet, so A is definitely less than B."; } + $less = -5; + break; + } + } + else + { + if($DEBUG) { echo ' no, they are equal.'; } + $less = 0; + } + } + if($DEBUG) { echo '
Check value is: "'.$less.'"'; } + if($less>0) + { + if($DEBUG) { echo '
A is greater than B'; } + return True; + } + elseif($less<0) + { + if($DEBUG) { echo '
A is less than B'; } + return False; + } + else + { + if($DEBUG) { echo '
A is equal to B'; } + return False; + } + } + } +?> diff --git a/phpgwapi/inc/class.setup_detection.inc.php b/phpgwapi/inc/class.setup_detection.inc.php new file mode 100644 index 0000000000..f2366374ea --- /dev/null +++ b/phpgwapi/inc/class.setup_detection.inc.php @@ -0,0 +1,438 @@ + * + * and Miles Lott * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + class setup_detection + { + function get_versions() + { + $d = dir(PHPGW_SERVER_ROOT); + while($entry=$d->read()) + { + if(!ereg('setup',$entry) && is_dir(PHPGW_SERVER_ROOT . '/' . $entry)) + { + $f = PHPGW_SERVER_ROOT . '/' . $entry . '/setup/setup.inc.php'; + if (@file_exists ($f)) + { + include($f); + $setup_info[$entry]['filename'] = $f; + } + } + } + $d->close(); + + // _debug_array($setup_info); + @ksort($setup_info); + return $setup_info; + } + + function get_db_versions($setup_info='') + { + $GLOBALS['phpgw_setup']->db->Halt_On_Error = 'no'; + $tables = $GLOBALS['phpgw_setup']->db->table_names(); + while(list($key,$val) = @each($tables)) + { + $tname[] = $val['table_name']; + } + $newapps = in_array('phpgw_applications',$tname); + $oldapps = in_array('applications',$tname); + + if((is_array($tables)) && (count($tables) > 0) && ($newapps || $oldapps)) + { + /* one of these tables exists. checking for post/pre beta version */ + if($newapps) + { + $GLOBALS['phpgw_setup']->db->query('SELECT * FROM phpgw_applications',__LINE__,__FILE__); + while(@$GLOBALS['phpgw_setup']->db->next_record()) + { + $setup_info[$GLOBALS['phpgw_setup']->db->f('app_name')]['currentver'] = $GLOBALS['phpgw_setup']->db->f('app_version'); + $setup_info[$GLOBALS['phpgw_setup']->db->f('app_name')]['enabled'] = $GLOBALS['phpgw_setup']->db->f('app_enabled'); + } + /* This is to catch old setup installs that did not have phpgwapi listed as an app */ + $tmp = $setup_info['phpgwapi']['version']; /* save the file version */ + if(!@$setup_info['phpgwapi']['currentver']) + { + $setup_info['phpgwapi']['currentver'] = $setup_info['admin']['currentver']; + $setup_info['phpgwapi']['version'] = $setup_info['admin']['currentver']; + $setup_info['phpgwapi']['enabled'] = $setup_info['admin']['enabled']; + // _debug_array($setup_info['phpgwapi']);exit; +// There seems to be a problem here. If ['phpgwapi']['currentver'] is set, +// The GLOBALS never gets set. + $GLOBALS['setup_info'] = $setup_info; + $GLOBALS['phpgw_setup']->register_app('phpgwapi'); + } + else + { + $GLOBALS['setup_info'] = $setup_info; + } + $setup_info['phpgwapi']['version'] = $tmp; /* restore the file version */ + } + elseif($oldapps) + { + $GLOBALS['phpgw_setup']->db->query('select * from applications'); + while(@$GLOBALS['phpgw_setup']->db->next_record()) + { + if($GLOBALS['phpgw_setup']->db->f('app_name') == 'admin') + { + $setup_info['phpgwapi']['currentver'] = $GLOBALS['phpgw_setup']->db->f('app_version'); + } + $setup_info[$GLOBALS['phpgw_setup']->db->f('app_name')]['currentver'] = $GLOBALS['phpgw_setup']->db->f('app_version'); + } + } + } + // _debug_array($setup_info); + return $setup_info; + } + + /* app status values: + U Upgrade required/available + R upgrade in pRogress + C upgrade Completed successfully + D Dependency failure + P Post-install dependency failure + F upgrade Failed + V Version mismatch at end of upgrade (Not used, proposed only) + M Missing files at start of upgrade (Not used, proposed only) + */ + function compare_versions($setup_info) + { + reset ($setup_info); + while(list($key, $value) = each($setup_info)) + { + //echo '
'.$setup_info[$key]['name'].'STATUS: '.$setup_info[$key]['status']; + /* Only set this if it has not already failed to upgrade - Milosch */ + if(!( (@$setup_info[$key]['status'] == 'F') || (@$setup_info[$key]['status'] == 'C') )) + { + //if ($setup_info[$key]['currentver'] > $setup_info[$key]['version']) + if($GLOBALS['phpgw_setup']->amorethanb($setup_info[$key]['currentver'],@$setup_info[$key]['version'])) + { + $setup_info[$key]['status'] = 'V'; + } + elseif(@$setup_info[$key]['currentver'] == @$setup_info[$key]['version']) + { + $setup_info[$key]['status'] = 'C'; + } + elseif($GLOBALS['phpgw_setup']->alessthanb(@$setup_info[$key]['currentver'],@$setup_info[$key]['version'])) + { + $setup_info[$key]['status'] = 'U'; + } + else + { + $setup_info[$key]['status'] = 'U'; + } + } + } + // _debug_array($setup_info); + return $setup_info; + } + + function check_depends($setup_info) + { + reset($setup_info); + /* Run the list of apps */ + while(list ($key, $value) = each ($setup_info)) + { + /* Does this app have any depends */ + if(isset($value['depends'])) + { + /* If so find out which apps it depends on */ + while(list($depkey, $depvalue) = each($value['depends'])) + { + /* I set this to False until we find a compatible version of this app */ + $setup_info['depends'][$depkey]['status'] = False; + /* Now we loop thru the versions looking for a compatible version */ + while(list ($depskey, $depsvalue) = each($value['depends'][$depkey]['versions'])) + { + $major = $GLOBALS['phpgw_setup']->get_major($setup_info[$value['depends'][$depkey]['appname']]['currentver']); + if ($major == $depsvalue) + { + $setup_info['depends'][$depkey]['status'] = True; + } + else + { + } + } + } + /* + Finally, we loop through the dependencies again to look for apps that still have a failure status + If we find one, we set the apps overall status as a dependency failure. + */ + reset($value['depends']); + while(list($depkey, $depvalue) = each($value['depends'])) + { + if ($setup_info['depends'][$depkey]['status'] == False) + { + /* Only set this if it has not already failed to upgrade - Milosch */ + if($setup_info[$key]['status'] != 'F')//&& $setup_info[$key]['status'] != 'C') + { + if($setup_info[$key]['status'] == 'C') + { + $setup_info[$key]['status'] = 'D'; + } + else + { + $setup_info[$key]['status'] = 'P'; + } + } + } + } + } + } + return $setup_info; + } + + /* + Called during the mass upgrade routine (Stage 1) to check for apps + that wish to be excluded from this process. + */ + function upgrade_exclude($setup_info) + { + @reset ($setup_info); + while(list($key,$value) = @each($setup_info)) + { + if(isset($value['no_mass_update'])) + { + unset($setup_info[$key]); + } + } + return $setup_info; + } + + function check_header() + { + if(!file_exists('../header.inc.php')) + { + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage One'; + return '1'; + } + else + { + if (!isset($GLOBALS['phpgw_info']['server']['header_admin_password'])) + { + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage One (No header admin password set)'; + return '2'; + } + elseif (!isset($GLOBALS['phpgw_domain'])) + { + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage One (Upgrade your header.inc.php)'; + return '3'; + } + elseif ($GLOBALS['phpgw_info']['server']['versions']['header'] != $GLOBALS['phpgw_info']['server']['versions']['current_header']) + { + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage One (Upgrade your header.inc.php)'; + return '3'; + } + } + /* header.inc.php part settled. Moving to authentication */ + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage One (Completed)'; + return '10'; + } + + function check_db() + { + $setup_info = $GLOBALS['setup_info']; + + $GLOBALS['phpgw_setup']->db->Halt_On_Error = 'no'; + // _debug_array($setup_info); + + if(!isset($setup_info['phpgwapi']['currentver'])) + { + $setup_info = $this->get_db_versions($setup_info); + } + // _debug_array($setup_info); + if (isset($setup_info['phpgwapi']['currentver'])) + { + if($setup_info['phpgwapi']['currentver'] == $setup_info['phpgwapi']['version']) + { + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage 1 (Tables Complete)'; + return 10; + } + else + { + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage 1 (Tables need upgrading)'; + return 4; + } + } + else + { + /* no tables, so checking if we can create them */ + $GLOBALS['phpgw_setup']->db->query('CREATE TABLE phpgw_testrights ( testfield varchar(5) NOT NULL )'); + if(!$GLOBALS['phpgw_setup']->db->Errno) + { + $GLOBALS['phpgw_setup']->db->query('DROP TABLE phpgw_testrights'); + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage 3 (Install Applications)'; + return 3; + } + else + { + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage 1 (Create Database)'; + return 1; + } + } + } + + function check_config() + { + $GLOBALS['phpgw_setup']->db->Halt_On_Error = 'no'; + if($GLOBALS['phpgw_info']['setup']['stage']['db'] != 10) + { + return ''; + } + + /* Since 0.9.10pre6 config table is named as phpgw_config */ + $config_table = 'config'; + $ver = explode('.',$GLOBALS['phpgw_info']['server']['versions']['phpgwapi']); + + if(ereg("([0-9]+)(pre)([0-9]+)",$ver[2],$regs)) + { + if(($regs[1] == '10') && ($regs[3] >= '6')) + { + $config_table = 'phpgw_config'; + } + } + + @$GLOBALS['phpgw_setup']->db->query("select config_value from $config_table where config_name='freshinstall'"); + $GLOBALS['phpgw_setup']->db->next_record(); + $configed = $GLOBALS['phpgw_setup']->db->f('config_value'); + if($configed) + { + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage 2 (Needs Configuration)'; + return 1; + } + else + { + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage 2 (Configuration OK)'; + return 10; + } + } + + function check_lang() + { + $GLOBALS['phpgw_setup']->db->Halt_On_Error = 'no'; + if($GLOBALS['phpgw_info']['setup']['stage']['db'] != 10) + { + return ''; + } + + if($GLOBALS['phpgw_setup']->alessthanb($GLOBALS['setup_info']['phpgwapi']['currentver'], '0.9.15.002')) + { + $langtbl = 'lang'; + $langstbl = 'languages'; + } + else + { + $langtbl = 'phpgw_lang'; + $langstbl = 'phpgw_languages'; + } + + $GLOBALS['phpgw_setup']->db->query("SELECT DISTINCT lang FROM $langtbl",__LINE__,__FILE__); + if($GLOBALS['phpgw_setup']->db->num_rows() == 0) + { + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage 3 (No languages installed)'; + return 1; + } + else + { + while(@$GLOBALS['phpgw_setup']->db->next_record()) + { + $GLOBALS['phpgw_info']['setup']['installed_langs'][$GLOBALS['phpgw_setup']->db->f('lang')] = $GLOBALS['phpgw_setup']->db->f('lang'); + } + reset($GLOBALS['phpgw_info']['setup']['installed_langs']); + while(list($key, $value) = each($GLOBALS['phpgw_info']['setup']['installed_langs'])) + { + $sql = "SELECT lang_name FROM $langstbl WHERE lang_id = '".$value."';"; + $GLOBALS['phpgw_setup']->db->query($sql); + $GLOBALS['phpgw_setup']->db->next_record(); + $GLOBALS['phpgw_info']['setup']['installed_langs'][$value] = $GLOBALS['phpgw_setup']->db->f('lang_name'); + } + $GLOBALS['phpgw_info']['setup']['header_msg'] = 'Stage 3 (Completed)'; + return 10; + } + } + + /* + @function check_app_tables + @abstract Verify that all of an app's tables exist in the db + @param $appname + @param $any optional, set to True to see if any of the apps tables are installed + */ + function check_app_tables($appname,$any=False) + { + $none = 0; + $setup_info = $GLOBALS['setup_info']; + + if(@$setup_info[$appname]['tables']) + { + /* Make a copy, else we send some callers into an infinite loop */ + $copy = $setup_info; + $GLOBALS['phpgw_setup']->db->Halt_On_Error = 'no'; + $tablenames = $GLOBALS['phpgw_setup']->db->table_names(); + while(list($key,$val) = @each($tablenames)) + { + $tables[] = $val['table_name']; + } + while(list($key,$val) = @each($copy[$appname]['tables'])) + { + if($GLOBALS['DEBUG']) + { + echo '
check_app_tables(): Checking: ' . $appname . ',table: ' . $val; + } + if(!in_array($val,$tables)) + { + if($GLOBALS['DEBUG']) + { + echo '
check_app_tables(): ' . $val . ' missing!'; + } + if(!$any) + { + return False; + } + else + { + $none++; + } + } + else + { + if($any) + { + if($GLOBALS['DEBUG']) + { + echo '
check_app_tables(): Some tables installed'; + } + return True; + } + } + } + } + if($none && $any) + { + if($GLOBALS['DEBUG']) + { + echo '
check_app_tables(): No tables installed'; + } + return False; + } + else + { + if($GLOBALS['DEBUG']) + { + echo '
check_app_tables(): All tables installed'; + } + return True; + } + } + } +?> diff --git a/phpgwapi/inc/class.setup_html.inc.php b/phpgwapi/inc/class.setup_html.inc.php new file mode 100644 index 0000000000..7e4f9a75ed --- /dev/null +++ b/phpgwapi/inc/class.setup_html.inc.php @@ -0,0 +1,206 @@ + * + * and Miles Lott * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + class setup_html + { + /*! + @function generate_header + @abstract generate header.inc.php file output - NOT a generic html header function + */ + function generate_header() + { + $GLOBALS['header_template']->set_file(array('header' => 'header.inc.php.template')); + $var = Array(); + + while(list($k,$v) = @each($GLOBALS['HTTP_POST_VARS']['setting'])) + { + $var[strtoupper($k)] = $v; + } + $GLOBALS['header_template']->set_var($var); + return $GLOBALS['header_template']->parse('out','header'); + } + + function setup_tpl_dir($app_name='setup') + { + /* hack to get tpl dir */ + if (is_dir(PHPGW_SERVER_ROOT)) + { + $srv_root = PHPGW_SERVER_ROOT . SEP . "$app_name" . SEP; + } + else + { + $srv_root = ''; + } + + $tpl_typical = 'templates' . SEP . 'default'; + $tpl_root = "$srv_root" ."$tpl_typical"; + return $tpl_root; + } + + function show_header($title='',$nologoutbutton=False, $logoutfrom='config', $configdomain='') + { + $GLOBALS['setup_tpl']->set_var('lang_charset',lang('charset')); + if ($nologoutbutton) + { + $btn_logout = ' '; + } + else + { + $btn_logout = '' . lang('Logout').''; + } + + $GLOBALS['setup_tpl']->set_var('lang_setup', lang('setup')); + $GLOBALS['setup_tpl']->set_var('page_title',$title); + if ($configdomain == '') + { + $GLOBALS['setup_tpl']->set_var('configdomain',''); + } + else + { + $GLOBALS['setup_tpl']->set_var('configdomain',' - ' . lang('Domain') . ': ' . $configdomain); + } + $GLOBALS['setup_tpl']->set_var('pgw_ver',$GLOBALS['phpgw_info']['server']['versions']['phpgwapi']); + $GLOBALS['setup_tpl']->set_var('logoutbutton',$btn_logout); + $GLOBALS['setup_tpl']->pparse('out','T_head'); + /* $setup_tpl->set_var('T_head',''); */ + } + + function show_footer() + { + $GLOBALS['setup_tpl']->pparse('out','T_footer'); + unset($GLOBALS['setup_tpl']); + } + + function show_alert_msg($alert_word='Setup alert',$alert_msg='setup alert (generic)') + { + $GLOBALS['setup_tpl']->set_var('V_alert_word',$alert_word); + $GLOBALS['setup_tpl']->set_var('V_alert_msg',$alert_msg); + $GLOBALS['setup_tpl']->pparse('out','T_alert_msg'); + } + + function make_frm_btn_simple($pre_frm_blurb='',$frm_method='POST',$frm_action='',$input_type='submit',$input_value='',$post_frm_blurb='') + { + /* a simple form has simple components */ + $simple_form = $pre_frm_blurb ."\n" + . '
' . "\n" + . '' . "\n" + . '
' . "\n" + . $post_frm_blurb . "\n"; + return $simple_form; + } + + function make_href_link_simple($pre_link_blurb='',$href_link='',$href_text='default text',$post_link_blurb='') + { + /* a simple href link has simple components */ + $simple_link = $pre_link_blurb + . '' . $href_text . ' ' + . $post_link_blurb . "\n"; + return $simple_link; + } + + function login_form() + { + /* begin use TEMPLATE login_main.tpl */ + $GLOBALS['setup_tpl']->set_var('ConfigLoginMSG',$GLOBALS['phpgw_info']['setup']['ConfigLoginMSG']); + $GLOBALS['setup_tpl']->set_var('HeaderLoginMSG',$GLOBALS['phpgw_info']['setup']['HeaderLoginMSG']); + + if ($GLOBALS['phpgw_info']['setup']['stage']['header'] == '10') + { + /* + Begin use SUB-TEMPLATE login_stage_header, + fills V_login_stage_header used inside of login_main.tpl + */ + $GLOBALS['setup_tpl']->set_var('lang_select',lang_select()); + if (count($GLOBALS['phpgw_domain']) > 1) + { + // use BLOCK B_multi_domain inside of login_stage_header + $GLOBALS['setup_tpl']->parse('V_multi_domain','B_multi_domain'); + // in this case, the single domain block needs to be nothing + $GLOBALS['setup_tpl']->set_var('V_single_domain',''); + } + else + { + reset($GLOBALS['phpgw_domain']); + $default_domain = each($GLOBALS['phpgw_domain']); + $GLOBALS['setup_tpl']->set_var('default_domain_zero',$default_domain[0]); + + /* Use BLOCK B_single_domain inside of login_stage_header */ + $GLOBALS['setup_tpl']->parse('V_single_domain','B_single_domain'); + /* in this case, the multi domain block needs to be nothing */ + $GLOBALS['setup_tpl']->set_var('V_multi_domain',''); + } + /* + End use SUB-TEMPLATE login_stage_header + put all this into V_login_stage_header for use inside login_main + */ + $GLOBALS['setup_tpl']->parse('V_login_stage_header','T_login_stage_header'); + } + else + { + /* begin SKIP SUB-TEMPLATE login_stage_header */ + $GLOBALS['setup_tpl']->set_var('V_multi_domain',''); + $GLOBALS['setup_tpl']->set_var('V_single_domain',''); + $GLOBALS['setup_tpl']->set_var('V_login_stage_header',''); + } + /* + end use TEMPLATE login_main.tpl + now out the login_main template + */ + $GLOBALS['setup_tpl']->pparse('out','T_login_main'); + } + + function get_template_list() + { + $d = dir(PHPGW_SERVER_ROOT . '/phpgwapi/templates'); + + while($entry = $d->read()) + { + if ($entry != 'CVS' && $entry != '.' && $entry != '..') + { + $list[$entry]['name'] = $entry; + $f = PHPGW_SERVER_ROOT . '/phpgwapi/templates/' . $entry . '/details.inc.php'; + if (file_exists ($f)) + { + include($f); + $list[$entry]['title'] = 'Use ' . $GLOBALS['phpgw_info']['template'][$entry]['title'] . 'interface'; + } + else + { + $list[$entry]['title'] = $entry; + } + } + } + $d->close(); + reset ($list); + return $list; + } + + function list_themes() + { + $dh = dir(PHPGW_SERVER_ROOT . '/phpgwapi/themes'); + while ($file = $dh->read()) + { + if (eregi("\.theme$", $file)) + { + $list[] = substr($file,0,strpos($file,'.')); + } + } + $dh->close(); + reset ($list); + return $list; + } + } +?> diff --git a/phpgwapi/inc/class.setup_process.inc.php b/phpgwapi/inc/class.setup_process.inc.php new file mode 100644 index 0000000000..67979cc3cd --- /dev/null +++ b/phpgwapi/inc/class.setup_process.inc.php @@ -0,0 +1,794 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + /* app status values: + U Upgrade required/available + R upgrade in pRogress + C upgrade Completed successfully + D Dependency failure + F upgrade Failed + V Version mismatch at end of upgrade (Not used, proposed only) + M Missing files at start of upgrade (Not used, proposed only) + */ + + class setup_process + { + var $oProc; + var $tables; + var $updateincluded = array(); + + /*! + @function init_process + @abstract create schema_proc object + @param none + */ + function init_process() + { + $ConfigDomain = $GLOBALS['HTTP_COOKIE_VARS']['ConfigDomain'] ? $GLOBALS['HTTP_COOKIE_VARS']['ConfigDomain'] : $GLOBALS['HTTP_POST_VARS']['ConfigDomain']; + $phpgw_domain = $GLOBALS['phpgw_domain']; + $phpgw_info = $GLOBALS['phpgw_info']; + + $this->oProc = CreateObject('phpgwapi.schema_proc',$phpgw_domain[$ConfigDomain]['db_type']); + $this->oProc->m_odb = $GLOBALS['phpgw_setup']->db; + $this->oProc->m_odb->Host = $phpgw_domain[$ConfigDomain]['db_host']; + $this->oProc->m_odb->Database = $phpgw_domain[$ConfigDomain]['db_name']; + $this->oProc->m_odb->User = $phpgw_domain[$ConfigDomain]['db_user']; + $this->oProc->m_odb->Password = $phpgw_domain[$ConfigDomain]['db_pass']; + $this->oProc->m_odb->Halt_On_Error = 'report'; + $this->oProc->m_odb->connect(); + } + + /*! + @function pass + @abstract the mother of all multipass upgrade parental loop functions + @param $setup_info array of application info from setup.inc.php files + @param $type optional, defaults to new(install), could also be 'upgrade' + @param $DEBUG optional, print debugging info + @param $force_en optional, install english language files + */ + function pass($setup_info,$method='new',$DEBUG=False,$force_en=False) + { + if (!$method) + { + return False; + } + // Place api first + $pass['phpgwapi'] = $setup_info['phpgwapi']; + @reset($setup_info); + $setup_info = $GLOBALS['phpgw_setup']->detection->get_versions($setup_info); + @reset($setup_info); + + $i = 1; + $passed = array(); + $passing = array(); + $pass_string = implode (':', $pass); + $passing_string = implode (':', $passing); + while ($pass_string != $passing_string) + { + $passing = array(); + if ($DEBUG) { echo '
process->pass(): #' . $i . ' for ' . $method . ' processing' . "\n"; } + /* Check current versions and dependencies */ + $setup_info = $GLOBALS['phpgw_setup']->detection->get_db_versions($setup_info); + $setup_info = $GLOBALS['phpgw_setup']->detection->compare_versions($setup_info); + //_debug_array($setup_info);exit; + $setup_info = $GLOBALS['phpgw_setup']->detection->check_depends($setup_info); + //if($i==2) { _debug_array($passed);exit; } + + /* stuff the rest of the apps, but only those with available upgrades */ + while(list($key,$value) = @each($setup_info)) + { + if (($value['name'] != 'phpgwapi') && ($value['status'] == 'U')) + { + if ( ($passed[$value['name']]['status'] != 'F') && ($passed[$value['name']]['status'] != 'C') ) + { + $pass[$value['name']] = $setup_info[$value['name']]; + } + } + /* + Now if we are on the 2nd or more passes, add api in + if (!$pass['phpgwapi']) + { + $pass['phpgwapi'] = $setup_info['phpgwapi']; + } + */ + } + + switch ($method) + { + case 'new': + /* Create tables and insert new records for each app in this list */ + $passing = $this->current($pass,$DEBUG); + $passing = $this->default_records($passing,$DEBUG); + $passing = $this->add_langs($passing,$DEBUG,$force_en); + break; + case 'upgrade': + /* Run upgrade scripts on each app in the list */ + $passing = $this->upgrade($pass,$DEBUG); + $passing = $this->upgrade_langs($passing,$DEBUG); + //_debug_array($pass);exit; + break; + default: + /* What the heck are you doing? */ + return False; + break; + } + + $pass = array(); + @reset($passing); + while(list($key,$value) = @each($passing)) + { + if($value['status'] == 'C') + { + $passed[$value['name']] = $passing[$value['name']]; + if ($DEBUG) { echo '
process->pass(): '.$passed[$value['name']]['name'] . ' install completed'."\n"; } + } + elseif($value['status'] == 'F') + { + $setup_info[$value['name']] = $passing[$value['name']]; + if ($DEBUG) { echo '
process->pass(): '.$setup_info[$value['name']]['name'] . ' install failed'."\n"; } + } + elseif($value['status'] == 'D') + { + $pass[$value['name']] = $setup_info[$value['name']]; + if ($DEBUG) { echo '
process->pass(): '.$pass[$value['name']]['name'] . ' fails dependency check on this pass'."\n"; } + } + else + { + $tmp = $passing[$value['name']]['name']; + if ($DEBUG) { echo '
process->pass(): '.$tmp . ' skipped on this pass'."\n"; } + } + } + + $i++; + if ($i == 20) /* Then oops it broke */ + { + echo '
Setup failure: excess looping in process->pass():'."\n"; + echo '
Pass:
'."\n"; + _debug_array($pass); + echo '
Passed:
'."\n"; + _debug_array($passed); + exit; + } + $pass_string = implode (':', $pass); + $passing_string = implode (':', $passing); + } + + /* now return the list */ + @reset($passed); + while(list($key,$value) = @each($passed)) + { + $setup_info[$value['name']] = $passed[$value['name']]; + } + + return ($setup_info); + } + + /*! + @function droptables + @abstract drop tables per application, check that they are in the db first + @param $setup_info array of application info from setup.inc.php files, etc. + */ + function droptables($setup_info,$DEBUG=False) + { + if (!$this->oProc) + { + $this->init_process(); + } + $this->oProc->m_bDeltaOnly = False; + + /* The following is built so below we won't try to drop a table that isn't there. */ + $tablenames = $GLOBALS['phpgw_setup']->db->table_names(); + while(list($key,$val) = @each($tablenames)) + { + $tables[] = $val['table_name']; + } + + @reset($setup_info); + while (list($key,$null) = @each($setup_info)) + { + if ($setup_info[$key]['tables']) + { + while (list($a,$table) = @each($setup_info[$key]['tables'])) + { + //echo $table; + if (in_array($table,$tables)) + { + if ($DEBUG){ echo '
process->droptables(): Dropping :'. $setup_info[$key]['name'] . ' table: ' . $table; } + $this->oProc->DropTable($table); + // Update the array values for return below + $setup_info[$key]['status'] = 'U'; + } + } + } + } + + /* Done, return current status */ + return ($setup_info); + } + + /*! + @function current + @abstract process current table setup in each application/setup dir + @param $appinfo array of application info from setup.inc.php files, etc. + @discussion This duplicates the old newtables behavior, using schema_proc + */ + function current($setup_info,$DEBUG=False) + { + if (!$this->oProc) + { + $this->init_process(); + } + $this->oProc->m_bDeltaOnly = False; + + @reset($setup_info); + while (list($key,$null) = @each($setup_info)) + { + $enabled = False; + $appname = $setup_info[$key]['name']; + $apptitle = $setup_info[$key]['title']; + + if($DEBUG) { echo '
process->current(): Incoming status: ' . $appname . ',status: '. $setup_info[$key]['status']; } + + $appdir = PHPGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; + + if ($setup_info[$key]['tables'] && file_exists($appdir.'tables_current.inc.php')) + { + if($DEBUG) { echo '
process->current(): Including: ' . $appdir.'tables_current.inc.php'; } + include ($appdir.'tables_current.inc.php'); + $ret = $this->post_process($phpgw_baseline,$DEBUG); + if($ret) + { + if ($GLOBALS['phpgw_setup']->app_registered($appname)) + { + $GLOBALS['phpgw_setup']->update_app($appname); + $GLOBALS['phpgw_setup']->update_hooks($appname); + } + else + { + $GLOBALS['phpgw_setup']->register_app($appname); + $GLOBALS['phpgw_setup']->register_hooks($appname); + } + // Update the array values for return below + $setup_info[$key]['status'] = 'C'; + } + else + { + /* script processing failed */ + if($DEBUG) { echo '
process->current(): Failed for ' . $appname . ',status: '. $setup_info[$key]['status']; } + $setup_info[$key]['status'] = 'F'; + } + } + else + { + if($DEBUG) { echo '
process->current(): No current tables for ' . $apptitle . "\n"; } + /* + Add the app, but disable it if it has tables defined. + A manual sql script install is needed, but we do add the hooks + */ + $enabled = 99; + if ($setup_info[$key]['tables'][0] != '') + { + $enabled = False; + } + if ($GLOBALS['phpgw_setup']->app_registered($appname)) + { + $GLOBALS['phpgw_setup']->update_app($appname); + $GLOBALS['phpgw_setup']->update_hooks($appname); + } + else + { + $GLOBALS['phpgw_setup']->register_app($appname,$enabled); + $GLOBALS['phpgw_setup']->register_hooks($appname); + } + $setup_info[$key]['status'] = 'C'; + } + if($DEBUG) { echo '
process->current(): Outgoing status: ' . $appname . ',status: '. $setup_info[$key]['status']; } + } + + /* Done, return current status */ + return ($setup_info); + } + + /*! + @function default_records + @abstract process default_records.inc.php in each application/setup dir + @param $setup_info array of application info from setup.inc.php files, etc. + */ + function default_records($setup_info,$DEBUG=False) + { + if (!$this->oProc) + { + $this->init_process(); + } + $this->oProc->m_bDeltaOnly = False; + $oProc = $this->oProc; + + @reset($setup_info); + while (list($key,$null) = @each($setup_info)) + { + $appname = $setup_info[$key]['name']; + $appdir = PHPGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; + + if ($setup_info[$key]['tables'] && file_exists($appdir.'default_records.inc.php')) + { + if ($DEBUG) + { + echo '
process->default_records(): Including default records for ' . $appname . "\n"; + } + $this->oProc->m_odb->transaction_begin(); + include ($appdir.'default_records.inc.php'); + $this->oProc->m_odb->transaction_commit(); + } + /* $setup_info[$key]['status'] = 'C'; */ + } + + /* Done, return current status */ + return ($setup_info); + } + + /*! + @function add_langs + @abstract process application lang files and uninstall + @param $setup_info array of application info from setup.inc.php files, etc. + */ + function add_langs($setup_info,$DEBUG=False,$force_en=False) + { + @reset($setup_info); + while (list($key,$null) = @each($setup_info)) + { + $appname = $setup_info[$key]['name']; + /* This is in the setup_lang class */ + $this->add_langs($appname,$DEBUG,$force_en); + if($DEBUG) + { + echo '
process->add_langs(): Translations added for ' . $appname . "\n"; + } + } + /* Done, return current status */ + return ($setup_info); + } + + /*! + @function drop_langs + @abstract process application lang files and install + @param $setup_info array of application info from setup.inc.php files, etc. + */ + function drop_langs($setup_info,$DEBUG=False) + { + @reset($setup_info); + while (list($key,$null) = @each($setup_info)) + { + $appname = $setup_info[$key]['name']; + /* This is in the setup_lang class */ + $this->drop_langs($appname,$DEBUG); + if($DEBUG) + { + echo '
process->drop_langs(): Translations removed for ' . $appname . "\n"; + } + } + /* Done, return current status */ + return ($setup_info); + } + + /*! + @function upgrade_langs + @abstract process application lang files and reinstall + @param $setup_info array of application info from setup.inc.php files, etc. + */ + function upgrade_langs($setup_info,$DEBUG=False) + { + @reset($setup_info); + while (list($key,$null) = @each($setup_info)) + { + /* Don't upgrade lang files in the middle of an upgrade */ + if($setup_info[$key]['status'] == 'R') + { + continue; + } + $appname = $setup_info[$key]['name']; + /* These are in the setup_lang class */ + $this->drop_langs($appname,$DEBUG); + $this->add_langs($appname,$DEBUG); + if($DEBUG) + { + echo '
process->upgrade_langs(): Translations reinstalled for ' . $appname . "\n"; + } + } + /* Done, return current status */ + return ($setup_info); + } + /*! + @function test_data + @abstract process test_data.inc.php in each application/setup dir for developer tests + This data should work with the baseline tables + @param $setup_info array of application info from setup.inc.php files, etc. + */ + function test_data($setup_info,$DEBUG=False) + { + if (!$this->oProc) + { + $this->init_process(); + } + $this->oProc->m_bDeltaOnly = False; + $oProc = $this->oProc; + + @reset($setup_info); + while (list($key,$null) = @each($setup_info)) + { + $appname = $setup_info[$key]['name']; + $appdir = PHPGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; + + if (file_exists($appdir.'test_data.inc.php')) + { + if ($DEBUG) + { + echo '
process->test_data(): Including baseline test data for ' . $appname . "\n"; + } + $this->oProc->m_odb->transaction_begin(); + include ($appdir.'test_data.inc.php'); + $this->oProc->m_odb->transaction_commit(); + } + } + + /* Done, return current status */ + return ($setup_info); + } + + /*! + @function baseline + @abstract process baseline table setup in each application/setup dir + @param $appinfo array of application info from setup.inc.php files, etc. + */ + function baseline($setup_info,$DEBUG=False) + { + if (!$this->oProc) + { + $this->init_process(); + } + + @reset($setup_info); + while (list($key,$null) = @each($setup_info)) + { + $appname = $setup_info[$key]['name']; + $appdir = PHPGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; + + if (file_exists($appdir.'tables_baseline.inc.php')) + { + if ($DEBUG) + { + echo '
process->baseline(): Including baseline tables for ' . $appname . "\n"; + } + include ($appdir.'tables_baseline.inc.php'); + $this->oProc->GenerateScripts($phpgw_baseline, $DEBUG); + $this->post_process($phpgw_baseline,$DEBUG); + + /* Update the array values for return below */ + /* $setup_info[$key]['status'] = 'R'; */ + } + else + { + if ($DEBUG) + { + echo '
process->baseline(): No baseline tables for ' . $appname . "\n"; + } + //$setup_info[$key]['status'] = 'C'; + } + } + + /* Done, return current status */ + return ($setup_info); + } + + /*! + @function upgrade + @abstract process available upgrades in each application/setup dir + @param $appinfo array of application info from setup.inc.php files, etc. + */ + function upgrade($setup_info,$DEBUG=False) + { + if (!@$this->oProc) + { + $this->init_process(); + } + $this->oProc->m_odb->HaltOnError = 'no'; + $this->oProc->m_bDeltaOnly = True; + + @reset($setup_info); + while (list($key,$null) = @each($setup_info)) + { + /* Don't try to upgrade an app that is not installed */ + if(!$GLOBALS['phpgw_setup']->app_registered($setup_info[$key]['name'])) + { + if ($DEBUG) + { + echo '
process->upgrade(): Application not installed: ' . $appname . "\n"; + } + unset($setup_info[$key]); + continue; + } + + /* if upgrade required, or if we are running again after an upgrade or dependency failure */ + if ($DEBUG) { echo '
process->upgrade(): Incoming : appname: '.$setup_info[$key]['name'] . ' status: ' . $setup_info[$key]['status']; } + if ($setup_info[$key]['status'] == 'U' || + $setup_info[$key]['status'] == 'D' || + $setup_info[$key]['status'] == 'V' || + $setup_info[$key]['status'] == '') // TODO this is not getting set for api upgrade, sometimes ??? + { + $appname = $setup_info[$key]['name']; + $apptitle = $setup_info[$key]['title']; + $currentver = $setup_info[$key]['currentver']; + $targetver = $setup_info[$key]['version']; // The version we need to match when done + $appdir = PHPGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; + + $test = array(); + $this->oProc->m_aTables = $phpgw_baseline = array(); +/* + $phpgw_baseline = array(); + + $tmpapp = array(); + $tmpapp[] = $setup_info[$key]; + $this->baseline($tmpapp,$DEBUG); + $this->oProc->m_aTables = $phpgw_baseline; + // So far, including the baseline file is not helping. + // Only AlterColumn/RenameColumn seem to be failing silently. + // This is because we are not keeping up with table changes, so a table in baseline + // either does not exist anymore, or the baseline is being lost. +*/ + if ($setup_info[$key]['tables'] && file_exists($appdir.'tables_baseline.inc.php')) + { + if ($DEBUG) + { + echo '
process->baseline(): Including baseline tables for ' . $appname . "\n"; + } + include ($appdir.'tables_baseline.inc.php'); + $this->oProc->m_aTables = $phpgw_baseline; + /* $this->oProc->GenerateScripts($phpgw_baseline, $DEBUG); */ + } + else + { + if ($DEBUG) + { + echo '
process->baseline(): No baseline tables for ' . $appname . "\n"; + } + /* This should be a break with a status setting, or not at all + break; + */ + } + if (file_exists($appdir . 'tables_update.inc.php') && !@$this->updateincluded[$appname]) + { + include ($appdir . 'tables_update.inc.php'); + $this->updateincluded[$appname] = True; + + /* $test array comes from update file. It is a list of available upgrade functions */ + @reset($test); + while (list($x,$value) = @each($test)) + { + $currentver = $setup_info[$key]['currentver']; + + /* build upgrade function name */ + $function = $appname . '_upgrade' . ereg_replace("\.", '_', $value); + + if ($DEBUG) + { + echo '
process->upgrade(): appname: ' . $appname; + echo '
process->upgrade(): currentver: ' . $currentver; + echo '
process->upgrade(): targetver: ' . $targetver; + echo '
process->upgrade(): status: ' . $setup_info[$key]['status']; + echo '
process->upgrade(): checking: ' . $value; + echo '
process->upgrade(): function: ' . $function; + } + + if ($value == $targetver) + { + $this->oProc->m_bDeltaOnly = False; + /* Done upgrading */ + if($DEBUG) + { + echo '
process->upgrade(): Upgrade of ' . $appname . ' to ' . $targetver . ' is completed.' . "\n"; + } + $appstatus = 'C'; + $setup_info[$key]['status'] = $appstatus; + $setup_info[$key]['currentver'] = $targetver; + if ($GLOBALS['phpgw_setup']->app_registered($appname)) + { + $GLOBALS['phpgw_setup']->update_app($appname); + $GLOBALS['phpgw_setup']->update_hooks($appname); + } + else + { + $GLOBALS['phpgw_setup']->register_app($appname); + $GLOBALS['phpgw_setup']->register_hooks($appname); + } + //break; + } + elseif (($value == $currentver) || !$currentver) + { + /* start upgrading db in addition to baseline */ + $this->oProc->m_bDeltaOnly = False; + if ($DEBUG) { echo '
process->upgrade(): running ' . $function; } + /* run upgrade function */ + $success = $function(); + if ($success != False) + { + $setup_info[$key]['currentver'] = $success; + if ($DEBUG) + { + echo '
process->upgrade(): Upgrade of ' . $appname + . ' from ' . $value + . ' to ' . $setup_info[$key]['currentver'] + . ' is completed.' . "\n"; + } + $appstatus = 'R'; + $setup_info[$key]['status'] = $appstatus; + if($GLOBALS['phpgw_setup']->app_registered($appname)) + { + if($DEBUG) + { + echo '
process->upgrade(): Updating registration of ' . $appname . ', new version: ' . $setup_info[$key]['currentver']; + } + $GLOBALS['phpgw_setup']->update_app($appname); + $GLOBALS['phpgw_setup']->update_hooks($appname); + } + else + { + if($DEBUG) + { + echo '
process->upgrade(): Registering ' . $appname . ', version: ' . $setup_info[$key]['currentver']; + } + $GLOBALS['phpgw_setup']->register_app($appname); + $GLOBALS['phpgw_setup']->register_hooks($appname); + } + } + else + { + if($DEBUG) + { + echo '
process->upgrade(): Upgrade of ' . $appname + . ' from ' . $currentver + . ' to ' . $value + . ' failed!!!' . "\n"; + } + $appstatus = 'F'; + break; + } + } + elseif ($GLOBALS['phpgw_setup']->alessthanb($value,$currentver)) + { + if ($DEBUG) { echo '
process->upgrade(): running baseline delta only: ' . $function . '...'; } + $this->oProc->m_bDeltaOnly = True; + $success = $function(); + } + else + { + break; + } + } + } + else + { + if ($setup_info[$appname]['tables']) + { + $appstatus = 'F'; + + if ($DEBUG) + { + echo '
process->upgrade(): No table upgrade available for ' . $appname . "\n"; + } + } + else + { + $setup_info[$key]['currentver'] == $targetver; + $appstatus = 'C'; + if ($GLOBALS['phpgw_setup']->app_registered($appname)) + { + $GLOBALS['phpgw_setup']->update_app($appname); + $GLOBALS['phpgw_setup']->update_hooks($appname); + } + else + { + $GLOBALS['phpgw_setup']->register_app($appname); + $GLOBALS['phpgw_setup']->register_hooks($appname); + } + + if ($DEBUG) + { + echo '
process->upgrade(): No table upgrade required for ' . $appname . "\n"; + } + } + } + } + else + { + $appstatus = 'C'; + if ($DEBUG) + { + echo '
process->upgrade(): No upgrade required for ' . $appname . "\n"; + } + } + + /* Done with this app, update status */ + $setup_info[$key]['status'] = $appstatus; + if ($DEBUG) + { + echo '
process->upgrade(): Outgoing : appname: '.$setup_info[$key]['name'] . ' status: ' . $setup_info[$key]['status']; + } + } + + /* Done, return current status */ + return ($setup_info); + } + + /*! + @function post_process + @abstract commit above processing to the db + */ + function post_process($tables,$DEBUG=False) + { + if (!$tables) + { + return False; + } + + $ret = $this->oProc->GenerateScripts($tables,$DEBUG); + if ($ret) + { + $oret = $this->oProc->ExecuteScripts($tables,$DEBUG); + if ($oret) + { + return True; + } + else + { + return False; + } + } + else + { + return False; + } + } + + /*! + @function sql_to_array + @abstract send this a table name, returns printable column spec and keys for the table from schema_proc + @param $tablename table whose array you want to see + */ + function sql_to_array($tablename='') + { + if (!$tablename) + { + return False; + } + + if (!$this->oProc) + { + $this->init_process(); + } + + $this->oProc->m_oTranslator->_GetColumns($this->oProc, $tablename, $sColumns, $sColumnName); + + while (list($key,$tbldata) = each ($this->oProc->m_oTranslator->sCol)) + { + $arr .= $tbldata; + } + $pk = $this->oProc->m_oTranslator->pk; + $fk = $this->oProc->m_oTranslator->fk; + $ix = $this->oProc->m_oTranslator->ix; + $uc = $this->oProc->m_oTranslator->uc; + + return array($arr,$pk,$fk,$ix,$uc); + } + } +?> diff --git a/phpgwapi/inc/class.setup_translation.inc.php b/phpgwapi/inc/class.setup_translation.inc.php new file mode 100644 index 0000000000..238fadbe14 --- /dev/null +++ b/phpgwapi/inc/class.setup_translation.inc.php @@ -0,0 +1,234 @@ + * + * and Dan Kuykendall * + * Handles multi-language support using flat files * + * -------------------------------------------------------------------------* + * This library is part of the phpGroupWare API * + * http://www.phpgroupware.org/api * + * ------------------------------------------------------------------------ * + * This library is free software; you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as published by * + * the Free Software Foundation; either version 2.1 of the License, * + * or any later version. * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU Lesser General Public License for more details. * + * You should have received a copy of the GNU Lesser General Public License * + * along with this library; if not, write to the Free Software Foundation, * + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + \**************************************************************************/ + + /* $Id$ */ + + class setup_translation + { + var $langarray; + var $langtbl = 'phpgw_lang'; + + /*! + @function setup_lang + @abstract constructor for the class, loads all phrases into langarray + @param $lang user lang variable (defaults to en) + */ + function setup_translation() + { + $ConfigLang = @$GLOBALS['HTTP_COOKIE_VARS']['ConfigLang'] ? @$GLOBALS['HTTP_COOKIE_VARS']['ConfigLang'] : @$GLOBALS['HTTP_POST_VARS']['ConfigLang']; + + /* TODO */ + /* + if(@$GLOBALS['phpgw_setup']->alessthanb(@$GLOBALS['setup_info']['phpgwapi']['currentver'], '0.9.15.002')) + { + $this->langtbl = 'lang'; + } + */ + + if(!$ConfigLang) + { + $lang = 'en'; + } + else + { + $lang = $ConfigLang; + } + + $fn = '.' . SEP . 'lang' . SEP . 'phpgw_' . $lang . '.lang'; + if (!file_exists($fn)) + { + $fn = '.' . SEP . 'lang' . SEP . 'phpgw_en.lang'; + } + + if (file_exists($fn)) + { + $fp = fopen($fn,'r'); + while ($data = fgets($fp,8000)) + { + list($message_id,$app_name,$null,$content) = explode("\t",$data); + if ($app_name == 'setup' || $app_name == 'common' || $app_name == 'all') + { + $this->langarray[] = array( + 'message_id' => $message_id, + 'content' => trim($content) + ); + } + } + fclose($fp); + } + } + + /*! + @function translate + @abstract Translate phrase to user selected lang + @param $key phrase to translate + @param $vars vars sent to lang function, passed to us + */ + function translate($key, $vars=False) + { + if (!$vars) + { + $vars = array(); + } + + $ret = $key; + + @reset($this->langarray); + while(list($null,$data) = @each($this->langarray)) + { + $lang[strtolower($data['message_id'])] = $data['content']; + } + + if (isset($lang[strtolower ($key)]) && $lang[strtolower ($key)]) + { + $ret = $lang[strtolower ($key)]; + } + else + { + $ret = $key.'*'; + } + $ndx = 1; + while( list($key,$val) = each( $vars ) ) + { + $ret = preg_replace( "/%$ndx/", $val, $ret ); + ++$ndx; + } + return $ret; + } + + /* Following functions are called for app (un)install */ + + /*! + @function get_langs + @abstract return array of installed languages, e.g. array('de','en') + */ + function get_langs($DEBUG=False) + { + if($DEBUG) + { + echo '
get_langs(): checking db...' . "\n"; + } + $GLOBALS['phpgw_setup']->db->query("SELECT DISTINCT(lang) FROM $this->langtbl",__LINE__,__FILE__); + $langs = array(); + + while($GLOBALS['phpgw_setup']->db->next_record()) + { + if($DEBUG) + { + echo '
get_langs(): found ' . $GLOBALS['phpgw_setup']->db->f(0); + } + $langs[] = $GLOBALS['phpgw_setup']->db->f(0); + } + return $langs; + } + + /*! + @function drop_langs + @abstract delete all lang entries for an application, return True if langs were found + @param $appname app_name whose translations you want to delete + */ + function drop_langs($appname,$DEBUG=False) + { + if($DEBUG) + { + echo '
drop_langs(): Working on: ' . $appname; + } + $GLOBALS['phpgw_setup']->db->query("SELECT COUNT(message_id) FROM $this->langtbl WHERE app_name='$appname'",__LINE__,__FILE__); + $GLOBALS['phpgw_setup']->db->next_record(); + if($GLOBALS['phpgw_setup']->db->f(0)) + { + $GLOBALS['phpgw_setup']->db->query("DELETE FROM $this->langtbl WHERE app_name='$appname'",__LINE__,__FILE__); + return True; + } + return False; + } + + /*! + @function add_langs + @abstract process an application's lang files, calling get_langs() to see what langs the admin installed already + @param $appname app_name of application to process + */ + function add_langs($appname,$DEBUG=False,$force_en=False) + { + $langs = $this->get_langs($DEBUG); + if($force_en && !isinarray('en',$langs)) + { + $langs[] = 'en'; + } + + if($DEBUG) + { + echo '
add_langs(): chose these langs: '; + _debug_array($langs); + } + + $GLOBALS['phpgw_setup']->db->transaction_begin(); + + while (list($null,$lang) = each($langs)) + { + if($DEBUG) + { + echo '
add_langs(): Working on: ' . $lang . ' for ' . $appname; + } + $appfile = PHPGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP . 'phpgw_' . strtolower($lang) . '.lang'; + if(file_exists($appfile)) + { + if($DEBUG) + { + echo '
add_langs(): Including: ' . $appfile; + } + $raw_file = file($appfile); + + while (list($null,$line) = @each($raw_file)) + { + list($message_id,$app_name,$GLOBALS['phpgw_setup']->db_lang,$content) = explode("\t",$line); + $message_id = $GLOBALS['phpgw_setup']->db->db_addslashes(chop($message_id)); + /* echo '
APPNAME:' . $app_name . ' PHRASE:' . $message_id; */ + $app_name = $GLOBALS['phpgw_setup']->db->db_addslashes(chop($app_name)); + $GLOBALS['phpgw_setup']->db_lang = $GLOBALS['phpgw_setup']->db->db_addslashes(chop($GLOBALS['phpgw_setup']->db_lang)); + $content = $GLOBALS['phpgw_setup']->db->db_addslashes(chop($content)); + + $GLOBALS['phpgw_setup']->db->query("SELECT COUNT(*) FROM $this->langtbl WHERE message_id='$message_id' and lang='" + . $GLOBALS['phpgw_setup']->db_lang . "'",__LINE__,__FILE__); + $GLOBALS['phpgw_setup']->db->next_record(); + + if ($GLOBALS['phpgw_setup']->db->f(0) == 0) + { + if($message_id && $content) + { + if($DEBUG) + { + echo "
add_langs(): adding - INSERT INTO $this->langtbl VALUES ('$message_id','$app_name','" + . $GLOBALS['phpgw_setup']->db_lang . "','$content')"; + } + $GLOBALS['phpgw_setup']->db->query("INSERT INTO $this->langtbl VALUES ('$message_id','$app_name','" + . $GLOBALS['phpgw_setup']->db_lang . "','$content')",__LINE__,__FILE__); + } + } + } + } + } + $GLOBALS['phpgw_setup']->db->transaction_commit(); + } + } +?>