include_once($path_to_root . "/includes/ui.inc");
include_once($path_to_root . "/admin/db/maintenance_db.inc");
-define("BACKUP_PATH", $SysPrefs->comp_path.'/'.user_company()."/backup/");
-
if (get_post('view')) {
if (!get_post('backups')) {
display_error(_('Select backup file first.'));
} else {
- $filename = BACKUP_PATH . clean_file_name(get_post('backups'));
+ $filename = $SysPrefs->backup_dir().clean_file_name(get_post('backups'));
if (in_ajax())
$Ajax->popup( $filename );
else {
};
if (get_post('download')) {
if (get_post('backups')) {
- download_file(BACKUP_PATH . clean_file_name(get_post('backups')));
+ download_file($SysPrefs->backup_dir().clean_file_name(get_post('backups')));
exit;
} else
display_error(_("Select backup file first."));
function check_paths()
{
- if (!file_exists(BACKUP_PATH)) {
+ global $SysPrefs;
+
+ if (!file_exists($SysPrefs->backup_dir())) {
display_error (_("Backup paths have not been set correctly.")
._("Please contact System Administrator.")."<br>"
- . _("cannot find backup directory") . " - " . BACKUP_PATH . "<br>");
+ . _("cannot find backup directory") . " - " . $SysPrefs->backup_dir() . "<br>");
end_page();
exit;
}
function generate_backup($conn, $ext='no', $comm='')
{
- $filename = db_backup($conn, $ext, $comm, BACKUP_PATH);
+ global $SysPrefs;
+
+ $filename = db_backup($conn, $ext, $comm, $SysPrefs->backup_dir());
if ($filename)
display_notification(_("Backup successfully generated."). ' '
. _("Filename") . ": " . $filename);
function get_backup_file_combo()
{
- global $path_to_root, $Ajax;
+ global $path_to_root, $Ajax, $SysPrefs;
$ar_files = array();
default_focus('backups');
- $dh = opendir(BACKUP_PATH);
+ $dh = opendir($SysPrefs->backup_dir());
while (($file = readdir($dh)) !== false)
$ar_files[] = $file;
closedir($dh);
$conn = $db_connections[user_company()];
$backup_name = clean_file_name(get_post('backups'));
-$backup_path = BACKUP_PATH . $backup_name;
+$backup_path = $SysPrefs->backup_dir() . $backup_name;
if (get_post('creat')) {
generate_backup($conn, get_post('comp'), get_post('comments'));
if (!preg_match("/\.sql(\.zip|\.gz)?$/", $fname))
display_error(_("You can only upload *.sql backup files"));
elseif (is_uploaded_file($tmpname)) {
- rename($tmpname, BACKUP_PATH . $fname);
+ rename($tmpname, $SysPrefs->backup_dir() . $fname);
display_notification(_("File uploaded to backup directory"));
$Ajax->activate('backups');
} else
function refresh_sys_prefs()
{
- flush_dir(user_js_cache()); // clear cache
+// flush_dir(user_js_cache()); // clear cache
unset($_SESSION['SysPrefs']);
+ $_SESSION['SysPrefs'] = new sys_prefs();
get_company_prefs();
}
--- /dev/null
+<?php
+/**********************************************************************
+ Copyright (C) FrontAccounting, LLC.
+ Released under the terms of the GNU General Public License, GPL,
+ as published by the Free Software Foundation, either version 3
+ of the License, or (at your option) any later version.
+ This program 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 License here <http://www.gnu.org/licenses/gpl-3.0.html>.
+***********************************************************************/
+
+//
+// Utility class contains basic database upgrade routines.
+//
+class fa_patch {
+ var $previous; // previous database version
+ var $version; // version after upgrade
+ var $description; // short patch description
+
+ var $sql; // basic sql file
+
+ var $cur_company;
+ var $backup; // pre-upgrade backup filename
+
+ var $errors = array();
+ var $ma_upgrade_time = 300;
+
+ function fa_patch()
+ {
+ global $path_to_root;
+
+ include $path_to_root."/config_db.php";
+
+ $this->companies = $db_connections;
+
+ return $this->companies;
+ }
+
+ /*
+ Collect/log messages generated during upgrade process.
+ */
+ function log_error($msg, $type='Error')
+ {
+ if ($type == 'Error')
+ $this->errors[] = $msg;
+ error_log(sprintf('[%s] %s', $type, $msg));
+ return false;
+ }
+
+ /*
+ Pre-install maintenance: login to company, open upgrade log, make a backup
+ */
+ function pre_install($company)
+ {
+ global $SysPrefs;
+
+ $this->cur_company = $company;
+ $this->errors = array();
+ $this->backup = null;
+
+ $this->save_log = ini_set('error_log', dirname(__FILE__).'/../../tmp/upgrade.'.$this->cur_company.'.log');
+ $this->log_error(sprintf(_("Upgrade started for company %s."), $this->cur_company), 'Info');
+
+ if (!set_global_connection($this->cur_company))
+ return $this->log_error(_("Cannot connect to company database."));
+
+ $cur_ver = get_company_pref('version_id', true);
+ if ($cur_ver != $this->previous)
+ return $this->log_error(sprintf(_("Cannot upgrade company %s: database version is incompatible ('%s' instead of '%s')."),
+ $this->cur_company, $cur_ver, $this->previous));
+
+ if (!$this->prepare()) // fetch params, perform additional checks (if any)
+ return false;
+
+ if (!$this->sql)
+ return true; // skip security backup if database content is not changed
+
+ $this->backup = db_backup($this->companies[$this->cur_company], 'no', 'Security backup before upgrade',
+ $SysPrefs->backup_dir($this->cur_company));
+
+ if (!$this->backup)
+ return $this->log_error(_("Security backup failed."));
+
+ $this->log_error(sprintf(_("Security backup in file %s done."), $this->backup), 'Info');
+ return true;
+ }
+
+ /*
+ Basic install procedure using sql file.
+ */
+ function sql_install($company, $force=false)
+ {
+ global $path_to_root;
+
+ if ($this->sql != '') // perform basic upgrade operations defined in sql file
+ {
+ $result = true;
+
+ if ($result === true)
+ $result = db_import($path_to_root. '/sql/'.$this->sql, $this->companies[$company],
+ $force, true, false, true);
+
+ if ($result !== true)
+ {
+ if (is_array($result))
+ {
+ foreach($result as $err)
+ $this->log_error($err[1] . ':'. $err[0]);
+ } else
+ {
+ $this->log_error($result);
+ unset($this->backup); // prevent restore (database was not touched due to other errors)
+ }
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ Post install procedures: update database version, or restore databse from backup file in case of errors
+ */
+ function post_install($result=true)
+ {
+ global $db_version;
+
+ if ($result !== true)
+ {
+ if ($this->backup)
+ {
+ if (!set_global_connection($this->cur_company)) // reset connection to clear encoding
+ return $this->log_error(_("Cannot connect to company database for database restore."));
+
+ set_time_limit($this->max_upgrade_time);
+ $result = db_import($this->backup, $this->companies[$this->cur_company], true, false);
+ if ($result)
+ $this->log_error(_("Upgrade failed. Original database content restored successfully."), 'Info');
+ else
+ $thi->log_error(sprintf(_("Database restore operation failed. Original database content is in %s file."), $this->backup));
+ $this->post_fail($this->cur_company);
+ }
+ } else {
+ update_company_prefs(array('version_id' => $this->version));
+ }
+
+ $this->log_error(sprintf(_("Upgrade for company %s finished."), $this->cur_company), 'Info');
+
+ set_global_connection();
+ ini_set('error_log', $this->save_log);
+
+ if (db_fixed())
+ db_set_encoding();
+
+ return $result;
+ }
+
+ /*
+ Main routine for single company upgrade.
+ */
+ function upgrade_company($comp, $force=false)
+ {
+ $result = $this->pre_install($comp) && $this->sql_install($comp, $force) && $this->install($comp, $force);
+
+ $this->post_install($result);
+
+ return count($this->errors) == 0;
+ }
+
+ /*
+ Additional version specific php/sql upgrade procedures.
+ This procedure is performed after basic sql upgrade script is run.
+ */
+ function install($company, $force=false)
+ {
+ return true;
+ }
+ /*
+ Optional cleanup procedure.
+ This procedure is run in case of upgrade failure, before the backup is restored.
+ */
+ function post_fail($company)
+ {
+ }
+
+ /*
+ Present upgrade parameters to administrator
+ This function presents upgrade choices, after selection company to be upgraded.
+ */
+ function show_params($comp)
+ {
+ }
+
+ /*
+ Fetch & check upgrade parameters, check additional upgrade pre-conditions.
+ This function is run after successfull switching to target database connection.
+ */
+ function prepare()
+ {
+ return true;
+ }
+
+}
+
+/*
+ Return databases status info.
+*/
+function get_site_status($connections)
+{
+ $info = array();
+
+ foreach($connections as $i => $conn)
+ {
+ $info[$i]['status'] = set_global_connection($i) !== false;
+
+ $info[$i]['name'] = $conn['name'];
+ $info[$i]['table_set'] = $conn['host'].'/'.$conn['dbname'].':'.$conn['tbpref'].'*';
+ if ($info[$i]['status'])
+ {
+ $info[$i]['version'] = get_company_pref('version_id');
+ }
+ }
+ set_global_connection();
+ refresh_sys_prefs();
+
+ return $info;
+}
+
+/*
+ Creates table of installer objects sorted by applicable db scheme version.
+*/
+function get_installers()
+{
+ global $path_to_root;
+
+ $patchdir = $path_to_root."/sql/";
+ $upgrades = array();
+ $datadir = @opendir($patchdir);
+
+ if ($datadir)
+ {
+ while(false !== ($fname = readdir($datadir)))
+ { // check all php files but index.php
+ if (!is_dir($patchdir . $fname) && ($fname != 'index.php')
+ && stristr($fname, '.php') != false && $fname[0] != '.')
+ {
+ unset($install);
+ include_once($patchdir . $fname);
+ if (isset($install)) // add installer if found
+ $upgrades[$install->previous] = $install;
+ }
+ }
+ ksort($upgrades); // sort by file name
+ }
+ return $upgrades;
+}
--- /dev/null
+<?php
+header("Location: ../index.php");
if ($SysPrefs->use_popup_windows) {
$js = get_js_open_window(900, 500);
}
-page(_($help_context = "Install/Activate extensions"));
+page(_($help_context = "Install/Activate extensions"), false, false, "", $js);
include_once($path_to_root . "/includes/date_functions.inc");
include_once($path_to_root . "/admin/db/company_db.inc");
$path_to_root="..";
include_once($path_to_root . "/includes/session.inc");
-page(_($help_context = "Software Upgrade"));
+if ($SysPrefs->use_popup_windows) {
+ $js = get_js_open_window(900, 500);
+}
+page(_($help_context = "Software Upgrade"), false, false, "", $js);
include_once($path_to_root . "/includes/date_functions.inc");
include_once($path_to_root . "/admin/db/company_db.inc");
include_once($path_to_root . "/admin/db/maintenance_db.inc");
include_once($path_to_root . "/includes/ui.inc");
+include_once($path_to_root . "/admin/includes/fa_patch.class.inc");
+
+$site_status = get_site_status($db_connections);
+$installers = get_installers();
-//
-// Creates table of installer objects sorted by version.
-//
-function get_installers()
+if (get_post('Upgrade'))
{
- global $path_to_root;
+ $comp = get_post('select_comp');
- $patchdir = $path_to_root."/sql/";
- $upgrades = array();
- $datadir = @opendir($patchdir);
+ if ($comp === '')
+ display_error(_('Select company to be upgraded.'));
+ else {
+ $patch = @$installers[$site_status[$comp]['version']];
+ if ($patch)
+ {
+ if (!$patch->upgrade_company($comp, check_value('force')))
+ display_error(implode('<hr>', $patch->errors));
+ else
+ display_notification(_("Company upgraded successfully."));
- if ($datadir)
- {
- while(false !== ($fname = readdir($datadir)))
- { // check all php files but index.php
- if (!is_dir($patchdir . $fname) && ($fname != 'index.php')
- && stristr($fname, '.php') != false && $fname[0] != '.')
- {
- unset($install);
- include_once($patchdir . $fname);
- if (isset($install)) // add installer if found
- $upgrades[$install->version] = $install;
- }
+ $site_status = get_site_status($db_connections); // update info
+ $Ajax->activate('_page_body');
}
- ksort($upgrades); // sort by file name
- $upgrades = array_values($upgrades);
}
- return $upgrades;
}
-//
-// Apply one differential data set.
-//
-function upgrade_step($inst, $company, $conn, $force)
+$i = find_submit('Clear');
+if ($i != -1)
{
- global $path_to_root;
-
- $pref = $conn['tbpref'];
- $ret = true;
+ unlink($path_to_root.'/tmp/upgrade.'.$i.'.log');
+ $Ajax->activate('_page_body');
+}
+if (get_post('_select_comp_update'))
+{
+ $Ajax->activate('_page_body');
+}
- $state = $inst->installed($pref);
- if (!$state || $force)
- {
- if (!$inst->pre_check($pref, $force)) return false;
- $sql = $inst->sql;
+start_form();
- error_log(sprintf(_("Database upgrade for company '%s' (%s:%s*) started..."),
- $conn['name'], $conn['dbname'], $conn['tbpref']));
+$th = array(_("Company"), _("Table set"), _("Current version"), _("Last log"), _('Upgrade'));
+start_table(TABLESTYLE);
+table_header($th);
- if ($sql != '')
- $ret &= db_import($path_to_root.'/sql/'.$sql, $conn, $force, true);
+$uptodate = true;
+foreach($site_status as $i => $comp)
+{
+ $status = $comp['version']==$db_version;
- $ret &= $inst->install($company, $force);
+ alt_table_row_color($k);
- if (!$ret && is_callable(array($inst, 'post_fail')))
- $inst->post_fail($pref);
+ label_cell($comp['name']);
+ label_cell($comp['table_set']);
- error_log(_("Database upgrade finished."));
- } else
- if ($state!==true) {
- display_error(_("Upgrade cannot be done because database has been already partially upgraded. Please downgrade database to clean previous version or try forced upgrade."));
- $ret = false;
- }
- return $ret;
-}
+ label_cell($comp['version'], 'align=center' .($status ? '':' class=redfg')/*, 'class='.( $status ? 'ok' : 'error')*/);
-$installers = get_installers();
+ $log = $path_to_root.'/tmp/upgrade.'.$i.'.log';
+ if (file_exists($log))
+ {
+ label_cell(viewer_link(_('View log'), "admin/view/view_upgrade_log.php?id=$i", null, $i, 'log.png')
+ .button('Clear'.$i, _('Clear'), _('Clear log'), ICON_DELETE), 'align=center');
+ submit_js_confirm('Clear'.$i, _("Do you really want to clear this upgrade log?"));
+ } else
+ label_cell('-', 'align=center');
-if (get_post('Upgrade'))
-{
- $ret = true;
- foreach ($db_connections as $comp => $conn)
+ if (!$status)
{
- // connect to database
- if (!(set_global_connection($comp)))
- {
- display_error(_("Cannot connect to database for company")
- ." '".$conn['name']."'");
- continue;
- }
- // create security backup
- db_backup($conn, 'no', 'Security backup before upgrade');
- // apply all upgrade data
- foreach ($installers as $i => $inst)
- {
-
- $force = get_post('force_'.$i);
- if ($force || get_post('install_'.$i))
- $ret = upgrade_step($installers[$i], $comp, $conn, $force);
-
- if (!$ret)
- {
- display_error(
- sprintf(_("Database upgrade to version %s failed for company '%s'."),
- $inst->version, $conn['name'])
- .'<br>'
- ._('You should restore company database from latest backup file'));
- }
- }
-// db_close($conn); ?
- if (!$ret) break;
- }
- set_global_connection();
- if($ret)
- { // re-read the prefs
- global $path_to_root;
- include_once($path_to_root . "/admin/db/users_db.inc");
- $user = get_user_by_login($_SESSION["wa_current_user"]->username);
- $_SESSION["wa_current_user"]->prefs = new user_prefs($user);
- display_notification(_('All companies data has been successfully updated'));
- }
- refresh_sys_prefs(); // re-read system setup
- $Ajax->activate('_page_body');
+ label_cell(radio(null, 'select_comp', $i, null, true), 'align=center');
+ $uptodate = false;
+ } else
+ label_cell(_('Up to date'));
+ end_row();
}
-start_form();
-start_table(TABLESTYLE);
-$th = array(_("Version"), _("Description"), _("Sql file"), _("Install"),
- _("Force upgrade"));
-table_header($th);
+end_table();
+br();
-$k = 0; //row colour counter
-$partial = 0;
-foreach($installers as $i => $inst)
+div_start('upgrade_args');
+if (get_post('select_comp') !== '')
{
- alt_table_row_color($k);
- start_row();
- label_cell($inst->version);
- label_cell($inst->description);
- label_cell($inst->sql ? $inst->sql : '<i>'._('None').'</i>', 'align=center');
-// this is checked only for first (site admin) company,
-// but in fact we should always upgrade all data sets after
-// source upgrade.
- $check = $inst->installed(TB_PREF);
- if ($check === true)
- label_cell(_("Installed"));
- else
- if (!$check)
- check_cells(null,'install_'.$i, 0);
- else {
- label_cell("<span class=redfg>"
- . sprintf(_("Partially installed (%s)"), $check) . "</span>");
- $partial++;
- }
-
- check_cells(null,'force_'.$i, 0);
- end_row();
+ $patch = @$installers[$site_status[get_post('select_comp')]['version']];
+ if ($patch)
+ $patch->show_params(get_post('select_comp'));
}
-end_table(1);
-if ($partial!=0) {
- display_note(_("Database upgrades marked as partially installed cannot be installed automatically.
-You have to clean database manually to enable them, or try to perform forced upgrade."));
- br();
+div_end();
+
+if ($uptodate)
+ display_note(_('All company database schemes are up to date.'));
+else {
+ if (get_post('select_comp') === '')
+ display_note(_("Select company for incremental upgrade."), 0, 1, "class='stockmankofg'");
+ submit_center('Upgrade', _('Upgrade'), true, _('Save database and perform upgrade'), 'process');
}
-submit_center('Upgrade', _('Upgrade system'), true, _('Save database and perform upgrade'), 'process');
end_form();
end_page();
--- /dev/null
+<?php
+/**********************************************************************
+ Copyright (C) FrontAccounting, LLC.
+ Released under the terms of the GNU General Public License, GPL,
+ as published by the Free Software Foundation, either version 3
+ of the License, or (at your option) any later version.
+ This program 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 License here <http://www.gnu.org/licenses/gpl-3.0.html>.
+***********************************************************************/
+$page_security = 'SA_SOFTWAREUPGRADE';
+$path_to_root = "../..";
+include_once($path_to_root . "/includes/session.inc");
+include_once($path_to_root . "/includes/packages.inc");
+
+page(_($help_context = "Log View"), true);
+
+include_once($path_to_root . "/includes/ui.inc");
+
+if (!isset($_GET['id']))
+{
+ /*Script was not passed the correct parameters */
+ display_note(_("The script must be called with a valid company number."));
+ end_page();
+}
+
+display_heading(sprintf(_("Upgrade log for company '%s'"), $_GET['id']));
+br();
+ start_table();
+ start_row();
+
+ $log = strtr(file_get_contents($path_to_root.'/tmp/upgrade.'.$_GET['id'].'.log'),
+ array('Fatal error' => 'Fatal error')); // prevent misinterpretation in output_handler
+ label_cells(null, nl2br(html_specials_encode($log)));
+ end_row();
+ end_table(1);
+end_page(true);
$help_base_url = null;
/* per user data/cache directory */
- $comp_path = $path_to_root.'/company';
+ $comp_path = dirname(__FILE__).'/company';
/* Date systems. 0 = traditional, 1 = Jalali used by Iran, nabour countries, Afghanistan and some other Central Asian nations,
2 = Islamic used by other arabic nations. 3 = traditional, but where non-workday is Friday and start of week is Saturday */
*/
$clear_trial_balance_opening = false;
+/*
+ Optional backup path. Use %s in place of company number.
+ If not defined $comp_path/%s/backup/ is used.
+*/
+// $backup_path = dirname(__FILE__).'/company/%s/backup/';
'it' => 'roman',
);
- return 'utf8_'.(isset($db_collation[$lang]) ? $db_collation[$lang] : 'general').'_ci';
+ return 'utf8_'.(isset($db_collation[$lang]) ? $db_collation[$lang] : 'unicode').'_ci';
}
/*
///// We are, however, investigating the existing code to be compatible in the future.
db_query("SET sql_mode = '".SQL_MODE."'");
/////
+ refresh_sys_prefs();
return $db;
}
{
return $this->prefs['suppress_tax_rates'];
}
+
+ function backup_dir($comp=null)
+ {
+ if (!isset($comp))
+ $comp = user_company();
+
+ if (isset($this->backup_path))
+ return sprintf($this->backup_path, $comp);
+ else
+ return $this->comp_path.'/'.$comp."/backup/";
+ }
}
function radio($label, $name, $value, $selected=null, $submit_on_change=false)
{
if (!isset($selected))
- $selected = get_post($name) == $value;
+ $selected = get_post($name) === (string)$value;
if ($submit_on_change === true)
$submit_on_change =
if ($value == '')
continue;
start_row();
- label_cells($field, nl2br(htmlentities(is_array($value) ? implode("\n", $value) :$value)),
+ label_cells($field, nl2br(html_specials_encode(is_array($value) ? implode("\n", $value) :$value)),
"class='tableheader2'");
end_row();
}
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
***********************************************************************/
-class fa2_1 {
+class fa2_1 extends fa_patch {
+ var $previous = ''; // applicable database version
var $version = '2.1'; // version installed
var $description;
var $sql = 'alter2.1.sql';
// Install procedure. All additional changes
// not included in sql file should go here.
//
- function install($company, $force)
+ function install($company, $force=false)
{
global $db;
return true;
}
+
//
// Checking before install
//
- function pre_check($pref)
+ function prepare()
{
// We cannot perform successfull upgrade on system where the
- // trans tax details tables was deleted during previous try.
+ // trans tax details tables was deleted during previous try.
+ $pref = $this->companies[$company]['tbpref'];
+
if (check_table($pref, 'debtor_trans_tax_details')
|| check_table($pref, 'supp_invoice_tax_items')) {
display_error(_("Seems that system upgrade to version 2.1 has
database restore from last backup file first."));
return false;
- }
+ }
return true; // true when ok, fail otherwise
}
- //
- // Test if patch was applied before.
- //
- function installed($pref) {
- $n = 4; // number of features to be installed
- if (!check_table($pref, 'item_codes')) $n--;
-// if (!check_table($pref, 'company', 'foreign_codes')) $n--;
- if (!check_table($pref, 'suppliers', 'credit_limit')) $n--;
- if (!check_table($pref, 'bank_trans', 'reconciled',
- array('Type'=>'date'))) $n--;
- if (!check_table($pref, 'trans_tax_details')) $n--;
- return $n == 0 ? true : 5 - $n;
- }
};
$install = new fa2_1;
See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
***********************************************************************/
-class fa2_2 {
- var $version = '2.2'; // version installed
+class fa2_2 extends fa_patch {
+ var $previous = '2.1'; // applicable database version
+ var $version = '2.2rc'; // version installed
var $description;
var $sql = 'alter2.2.sql';
var $preconf = true;
- var $beta = false; // upgrade from 2.1 or 2.2beta; set in pre_check
+ var $beta = false; // upgrade from 2.1 or 2.2beta; set in prepare()
function fa2_2() {
global $security_groups;
// Install procedure. All additional changes
// not included in sql file should go here.
//
- function install($company, $force)
+ function install($company, $force=false)
{
global $db, $systypes_array, $db_connections;
-
+
if (!$this->preconf)
return false;
//
// Checking before install
//
- function pre_check($pref, $force)
- {
+ function prepare()
+ {
global $security_groups;
-
- if ($this->beta && !$force)
+
+ if ($this->beta)
$this->sql = 'alter2.2rc.sql';
// return ok when security groups still defined (upgrade from 2.1)
// or usersonline not defined (upgrade from 2.2 beta)
- return isset($security_groups) || (check_table($pref, 'usersonline')!=0);
- }
- //
- // Test if patch was applied before.
- //
- function installed($pref) {
- $n = 1; // number of patches to be installed
- $patchcnt = 0;
- if (!$this->beta) {
- $n = 16;
- if (check_table($pref, 'company')) // skip in 2.3
- $n -= 3;
- else {
- if (check_table($pref, 'company', 'custom1_name')) $patchcnt++;
- if (!check_table($pref, 'company', 'profit_loss_year_act')) $patchcnt++;
- if (!check_table($pref, 'company', 'login_tout')) $patchcnt++;
- }
- if (!check_table($pref, 'stock_category', 'dflt_no_sale')) $patchcnt++;
- if (!check_table($pref, 'users', 'sticky_doc_date')) $patchcnt++;
- if (!check_table($pref, 'users', 'startup_tab')) $patchcnt++;
- if (!check_table($pref, 'cust_branch', 'inactive')) $patchcnt++;
- if (!check_table($pref, 'chart_class', 'ctype')) $patchcnt++;
- if (!check_table($pref, 'audit_trail')) $patchcnt++;
- if (!check_table($pref, 'currencies', 'auto_update')) $patchcnt++;
- if (!check_table($pref, 'stock_master','no_sale')) $patchcnt++;
- if (!check_table($pref, 'suppliers', 'supp_ref')) $patchcnt++;
- if (!check_table($pref, 'users', 'role_id')) $patchcnt++;
- if (!check_table($pref, 'sales_orders', 'reference')) $patchcnt++;
- if (!check_table($pref, 'tags')) $patchcnt++;
- }
- if (!check_table($pref, 'useronline')) $patchcnt++;
+ $pref = $this->companies[$company]['tbpref'];
- $n -= $patchcnt;
- return $n == 0 ? true : $patchcnt;
+ return isset($security_groups) || (check_table($pref, 'usersonline')!=0);
}
};
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
***********************************************************************/
-class fa2_3 {
- var $version = '2.3'; // version installed
+class fa2_3 extends fa_patch {
+ var $previous = '2.2rc'; // applicable database version
+ var $version = '2.3rc'; // version installed
var $description;
var $sql = 'alter2.3.sql';
var $preconf = true;
// Install procedure. All additional changes
// not included in sql file should go here.
//
- function install($company, $force)
+ function install($company, $force=false)
{
global $db_version, $dflt_lang;
//
// Checking before install
//
- function pre_check($pref, $force)
+ function prepare()
{
- if ($this->beta && !$force)
+ if ($this->beta)
$this->sql = 'alter2.3rc.sql';
return true;
}
- //
- // Test if patch was applied before.
- //
- function installed($pref) {
- $this->beta = !check_table($pref, 'suppliers', 'tax_included');
-
- $n = 1; // number of patches to be installed
- $patchcnt = 0;
- if (!$this->beta) {
- $n += 3;
- if (!check_table($pref, 'comments', 'type', array('Key'=>'MUL'))) $patchcnt++;
- if (!check_table($pref, 'sys_prefs')) $patchcnt++;
- if (!check_table($pref, 'sales_orders', 'payment_terms')) $patchcnt++;
- }
- if (!check_table($pref, 'purch_orders', 'tax_included')) $patchcnt++;
- return $n == $patchcnt ? true : ($patchcnt ? ($patchcnt.'/'. $n) : 0);
- }
//=========================================================================================
// 2.3 specific update functions
//
-
+
/*
Update order totals
*/
}
return true;
}
-
+
function fix_extensions()
{
global $path_to_root, $next_extension_id, $installed_languages;
-
+
$lang_chd = false;
foreach($installed_languages as $i => $lang) {
if (!isset($lang['path'])) {
if ($lang_chd)
write_lang();
-
$installed_extensions= get_company_extensions();
if (!isset($next_extension_id))
$next_extension_id = 1;
$new_exts = array();
-
+
/* Old extension modules are uninstalled - they need manual porting after
heavy changes in extension system in FA2.3
-
+
foreach($installed_extensions as $i => $ext)
{
if (isset($ext['title'])) // old type entry
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
***********************************************************************/
-class fa2_4 {
+function collations_list_row($label, $name, $selected_id=null)
+{
+
+$mysql_collations = array(
+ 'xx' => 'Unicode (multilanguage)',
+ 'is' => 'Icelandic',
+ 'lv' => 'Latvian',
+ 'ro' => 'Romanian',
+ 'sl' => 'Slovenian',
+ 'pl' => 'Polish',
+ 'et' => 'Estonian',
+ 'es' => 'Spanish', // or 'spanish2',
+ 'sw' => 'Swedish',
+ 'tr' => 'Turkish',
+ 'cs' => 'Czech',
+ 'da' => 'Danish',
+ 'lt' => 'Lithuanian',
+ 'sk' => 'Slovak',
+ 'sp' => 'Spanish (alternative)',
+ 'fa' => 'Persian',
+ 'hu' => 'Hungarian',
+ 'fr' => 'French',
+ 'it' => 'Italian',
+);
+
+ echo "<tr>";
+ if ($label != null)
+ echo "<td class='label'>$label</td>\n";
+ echo "<td>";
+
+ echo array_selector($name, $selected_id, $mysql_collations,
+ array('select_submit'=> false) );
+ echo "</td></tr>\n";
+}
+
+class fa2_4 extends fa_patch {
+ var $previous = '2.3rc'; // applicable database version
var $version = '2.4.0'; // version installed
var $description;
var $sql = 'alter2.4.sql';
var $preconf = true;
function fa2_4() {
+ parent::fa_patch();
$this->description = _('Upgrade from version 2.3 to 2.4');
}
+ /*
+ Shows parameters to be selected before upgrade (if any)
+ */
+ function show_params($comp)
+ {
+ display_note(_('Set optimal parameters and start upgrade:'));
+ start_table(TABLESTYLE);
+ start_row();
+ collations_list_row(_('Text collation optimization:'), 'collation', substr($_SESSION['language']->code, 0, 2));
+ end_row();
+ end_table();
+ br();
+ }
+
+ /*
+ Fetches selected upgrade parameters.
+ */
+ function prepare()
+ {
+ $this->collation = get_mysql_collation(get_post('collation'));
+ return true;
+ }
+
//
// Install procedure. All additional changes
// not included in sql file should go here.
//
- function install($company, $force=false)
+ function install($company, $force=false)
{
global $db_version, $db_connections;
if ($result)
$result = $this->do_cleanup();
- //remove obsolete and temporary columns.
- // this have to be done here as db_import rearranges alter query order
- $dropcol = array(
- 'cust_branch' => array('contact_name', 'disable_trans'),
- );
-
- foreach($dropcol as $table => $columns)
- foreach($columns as $col) {
- if (db_query("ALTER TABLE `".TB_PREF."{$table}` DROP `$col`")==false) {
- display_error("Cannot drop {$table}.{$col} column:<br>".db_error_msg($db));
- return false;
- }
- }
-
- return update_company_prefs(array('version_id'=>$db_version));
- }
- //
- // Checking before install
- //
- function pre_check($pref, $force)
- {
- return true;
+ return $result;
}
//
// optional procedure done after upgrade fail, before backup is restored
//
- function post_fail($pref)
+ function post_fail($company)
{
+ $pref = $this->companies[$company]['tbpref'];
db_query("DROP TABLE IF EXISTS " . $pref . 'wo_costing');
}
- //
- // Test if patch was applied before.
- //
- function installed($pref)
- {
- $n = 2; // number of patches to be installed
- $patchcnt = 0;
-
- if (!check_table($pref, 'suppliers', 'tax_algorithm')) $patchcnt++;
- if (!check_table($pref, 'wo_costing')) $patchcnt++;
- return $n == $patchcnt ? true : ($patchcnt ? ($patchcnt.'/'. $n) : 0);
- }
function update_workorders()
{
." AND person_type_id=1";
$res = db_query($sql);
if (!$res)
- {
- display_error("Cannot update work orders costs"
- .':<br>'. db_error_msg($db));
- return false;
- }
+ return $this->log_error(sprintf(_("Cannot update work orders costs:\n%s"), db_error_msg($db)));
+
while ($row = db_fetch($res))
{
$journal_id = get_next_trans_no(ST_JOURNAL);
WHERE `type`=".ST_WORKORDER." AND type_no={$row['type_no']} AND tran_date='{$row['tran_date']}'
AND person_id='{$row['person_id']}'";
if (!db_query($sql1)) return false;
-
+
$sql2 = "INSERT INTO ".TB_PREF."wo_costing (workorder_id, cost_type, trans_no)
VALUES ({$row['type_no']}, {$row['person_id']}, {$journal_id})";
if (!db_query($sql2)) return false;
. for all text/char column:
- suppress autorecoding by change of the type to related binary/blob type
- change column to utf8 encodding and selected collation.
- . change default table encoding to utf8
+ . change default table encoding to utf8 and selected collation
*/
- function switch_database_to_utf($pref, $test = false) {
+ function switch_database_to_utf($pref, $dbg = false) {
global $installed_languages, $dflt_lang;
$lang = array_search_value($dflt_lang, $installed_languages, 'code');
$new_encoding = get_mysql_encoding_name(strtoupper($lang['encoding']));
- if ($test)
- error_log('Switching database to utf8 encoding from '.$old_encoding);
- $collation = get_mysql_collation();
+ $this->log_error(sprintf('Switching database to utf8 encoding from %s', $old_encoding), 'Info');
+ $collation = $this->collation;
$tsql = "SHOW TABLES LIKE '".($pref=='' ? '' : substr($pref, 0, -1).'\\_')."%'";
$tresult = db_query($tsql, "Cannot select all tables with prefix '$pref'");
while($tbl = db_fetch($tresult)) {
if ($bintype != $col['Type'])
{ // this is char/text column, so change encoding to proper encoding
- if ($test)
- error_log($table.'.'.$col['Field']);
+ if ($dbg)
+ $this->log_error(sprintf('%s switched to uft8.', $table.'.'.$col['Field']), 'Debug');
$null = $col['Null'] === 'YES' ? ' NULL ' : ' NOT NULL ';
$default = $col['Null'] !== 'YES' && isset($col['Default']) ? ' DEFAULT '.db_escape($col['Default']) : '';
db_query("ALTER TABLE `$table` COLLATE $collation");
}
db_query("ALTER DATABASE COLLATE $collation");
- if ($test)
- error_log('Convertion to utf8 done.');
+ $this->log_error(_('Convertion to utf8 done.'), 'Info');
return true;
}
function do_cleanup()
{
+ global $db;
+
+ //remove obsolete and temporary columns.
+ // this have to be done here as db_import rearranges alter query order
$dropcol = array(
'tax_group_items' => array('rate'),
'budget_trans' => array('type', 'type_no', 'person_id', 'person_type_id', 'memo_'),
+ 'cust_branch' => array('contact_name', 'disable_trans'),
);
foreach($dropcol as $table => $columns)
foreach($columns as $col) {
if (db_query("ALTER TABLE `".TB_PREF."{$table}` DROP `$col`") == false) {
- display_error("Cannot drop {$table}.{$col} column:<br>".db_error_msg($db));
- return false;
+ return $this->log_error(sprintf(_("Cannot drop column in %s table: %s"), $table, db_error_msg($db)));
}
}
- }
+ return true;
+ }
}
$install = new fa2_4;