Added system upgrade page for site admins.
authorJanusz Dobrowolski <janusz@frontaccounting.eu>
Tue, 18 Nov 2008 21:40:50 +0000 (21:40 +0000)
committerJanusz Dobrowolski <janusz@frontaccounting.eu>
Tue, 18 Nov 2008 21:40:50 +0000 (21:40 +0000)
admin/db/company_db.inc
admin/db/maintenance_db.inc
admin/inst_upgrade.php [new file with mode: 0644]
applications/setup.php
sql/alter2.1.php [new file with mode: 0644]

index 8a832211bee06d4369d8dcd736227dca87c67eb4..fde84cfe29b2a69ccd04a8807659f9faa0e8c9cd 100644 (file)
@@ -80,9 +80,10 @@ function update_company_setup($coy_name, $coy_no, $gst_no, $tax_prd, $tax_last,
        db_query($sql, "The company setup could not be updated ");
 }
 
-function get_company_prefs()
+function get_company_prefs($tbpref = TB_PREF)
 {
-       $sql = "SELECT * FROM ".TB_PREF."company WHERE coy_code=1";
+       $sql = "SELECT * FROM ".$tbpref."company WHERE coy_code=1";
+       
        $result = db_query($sql, "The company preferences could not be retrieved");
 
        if (db_num_rows($result) == 0)
@@ -91,9 +92,9 @@ function get_company_prefs()
        return db_fetch($result);
 }
 
-function get_company_pref($pref_name)
+function get_company_pref($pref_name, $tbpref = TB_PREF)
 {
-       $prefs = get_company_prefs();
+       $prefs = get_company_prefs($tbpref);
        return $prefs[$pref_name];
 }
 
index 1a08ce62539a5785e6c258bf0351dbc04493d2af..97eea2a8670811bcebedc209c975e935e909859d 100644 (file)
@@ -105,7 +105,7 @@ function db_drop_db($connection)
        }
 }
 
-function db_import($filename, $connection)
+function db_import($filename, $connection, $force=true)
 {
        global $db;
        $allowed_commands = array(
@@ -172,7 +172,7 @@ function db_import($filename, $connection)
        }
 */
        // execute drop tables if exists queries
-       if (is_array($drop_queries))
+       if ($force && is_array($drop_queries))
        {
                foreach($drop_queries as $drop_query)
                {
@@ -277,13 +277,12 @@ function db_unzip($mode, $path)
 
 // generates a dump of $db database
 // $drop and $zip tell if to include the drop table statement or dry to pack
-function db_export($conn, $filename, $zip='no', $comment='')
+function db_export($conn, $filename, $zip='no', $comment='', $tbpref = TB_PREF)
 {
 
        global $app_title, $version, $power_url, $path_to_root;
 
     $error = false;
-
     // set max string size before writing to file
     $max_size = 1048576 * 2; // 2 MB
     // changes max size if value can be retrieved
@@ -297,7 +296,8 @@ function db_export($conn, $filename, $zip='no', $comment='')
        $backupfile = $filename . ".zip";
     else
        $backupfile = $filename;
-    $company = get_company_pref('coy_name');
+    $company = get_company_pref('coy_name', $tbpref);
+
     //create comment
     $out="# MySQL dump of database '".$conn["dbname"]."' on host '".$conn["host"]."'\n";
     $out.="# Backup Date and Time: ".date("Y-m-d H:i")."\n";
diff --git a/admin/inst_upgrade.php b/admin/inst_upgrade.php
new file mode 100644 (file)
index 0000000..793e050
--- /dev/null
@@ -0,0 +1,184 @@
+<?php
+
+$page_security = 20;
+$path_to_root="..";
+include_once($path_to_root . "/includes/session.inc");
+
+page(_("Software Upgrade"));
+
+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");
+
+//
+//     Checks $field existence in $table with given field $properties
+//     $table - table name without prefix
+//  $field -  optional field name
+//  $properties - optional properties of field defined by MySQL:
+//             'Type', 'Null', 'Key', 'Default', 'Extra'
+//
+function check_table($pref, $table, $field=null, $properties=null)
+{
+       $fields = db_query("SHOW COLUMNS FROM ".$pref.$table);
+       if (!$fields)
+               return 1;               // no such table or error
+
+       if (!isset($field)) 
+               return 0;               // table exists
+
+       while( $row = db_fetch_assoc($fields)) 
+       {
+               if ($row['Field'] == $field) 
+               {
+                       if (!isset($properties)) 
+                               return 0;
+                       foreach($properties as $property => $value) 
+                       {
+                               if ($row[$property] != $value) 
+                                       return 3;       // failed type/length check
+                       }
+                       return 0; // property check ok.
+               }
+       }
+       return 2; // field not found
+}
+//
+//     Creates table of installer objects sorted by 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)
+                       {
+                               unset($install);
+                               include_once($patchdir . $fname);
+                               if (isset($install)) // add installer if found
+                                       $upgrades[$install->version] =  $install;
+                       }
+               }
+               ksort($upgrades); // sort by file name
+               $upgrades = array_values($upgrades);
+       }
+       return $upgrades;
+}
+//
+//     Apply one differential data set.
+//
+function upgrade_step($index, $conn) 
+{
+       global $path_to_root, $installers;
+
+       $inst = $installers[$index];
+       $sql = $inst->sql;
+       $pref = $conn['tbpref'];
+       $ret = true;
+
+       $force = get_post('force_'.$index);
+       if ($force || get_post('install_'.$index)) 
+       {
+               if (!$inst->installed($pref) || $force) 
+               {
+       //              if(!$inst->pre_check($pref)) return false;
+
+                       if ($sql != '')
+                               $ret &= db_import($path_to_root.'/sql/'.$sql, $conn, $force);
+
+                       $ret &= $inst->install($pref, $force);
+               }
+       }
+       return $ret;
+}
+
+function db_open($conn)
+{
+       $db = mysql_connect($conn["host"] ,$conn["dbuser"], $conn["dbpassword"]);
+       if (!$db)
+               return false;
+       if (!mysql_select_db($conn["dbname"], $db))
+               return false;
+       return $db;
+}
+
+$installers = get_installers();
+
+if (get_post('Upgrade')) 
+{
+
+       $ret = true;
+       foreach ($db_connections as $conn) 
+       {
+       // connect to database
+               if (!($db = db_open($conn))) 
+               {
+                       display_error(_("Cannot connect to database for company")
+                               ." '".$conn['name']."'");
+                       continue;
+               }
+       // create security backup               
+               if ($conn['tbpref'] != "")
+                       $filename = $conn['dbname'] . "_" . $conn['tbpref'] . date("Ymd_Hi") . ".sql";
+               else
+                       $filename = $conn['dbname'] . "_" . date("Ymd_Hi") . ".sql";
+
+               db_export($conn, $filename, 'no', 'Security backup before upgrade', $conn['tbpref']);
+       // apply all upgrade data
+               foreach ($installers as $i => $inst) 
+               {
+                       $ret = upgrade_step($i, $conn);
+                       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;
+       }
+       if($ret)
+               display_notification(_('All companies data has been successfully updated'));
+       $Ajax->activate('_page_body');
+}
+
+start_form();
+start_table($table_style);
+$th = array(_("Version"), _("Description"), _("Sql file"), _("Install"),
+       _("Force upgrade"));
+table_header($th);
+
+$k = 0; //row colour counter
+foreach($installers as $i => $inst)
+{
+       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.
+       if ($inst->installed(TB_PREF))
+               label_cell(_("Installed"));
+       else
+               check_cells(null,'install_'.$i, 0);
+       check_cells(null,'force_'.$i, 0);
+       end_row();
+}
+end_table(1);
+submit_center('Upgrade', _('Upgrade system'), true, _('Save database and perform upgrade'), 'process');
+end_form();
+
+end_page();
+
+?>
\ No newline at end of file
index de752454324d9c8c5288453307c74ddac5797811..31e4a34751723f072977395dd9aaff232bde020e 100644 (file)
@@ -35,6 +35,7 @@
                        $this->add_rapp_function(2, _("Create/Update &Companies"),"admin/create_coy.php?", 14);
                        $this->add_rapp_function(2, _("Install/Update &Languages"),"admin/inst_lang.php?", 14);
                        $this->add_rapp_function(2, _("Install/Update &Modules"),"admin/inst_module.php?", 15);
+                       $this->add_rapp_function(2, _("Software &Upgrade"),"admin/inst_upgrade.php?", 15);
                        if (count($installed_modules) > 0)
                        {
                                foreach ($installed_modules as $mod)
diff --git a/sql/alter2.1.php b/sql/alter2.1.php
new file mode 100644 (file)
index 0000000..8e3a0d5
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+class fa2_1 {
+       var $version = '2.1';   // version installed
+       var $description = 'Version 2.1';
+       var $sql = 'alter2.1.sql';
+       //
+       //      Install procedure. All additional changes 
+       //      not included in sql file should go here.
+       //
+       function install($pref, $force) 
+       {
+               global $db;
+       /*
+       Statement below is allowed only for MySQL >=4.0.4:
+       UPDATE `0_bank_trans`, `0_bank_accounts` 
+               SET 0_bank_trans.bank_act=0_bank_accounts.id 
+               WHERE 0_bank_trans.bank_act=0_bank_accounts.account_code;
+       */
+               $sql = "SELECT id, account_code FROM ".$pref."bank_accounts";
+               if(!($res = db_query($sql))) {
+                       display_error(_("Cannot retrieve bank accounts codes")
+                               .':<br>'. db_error_msg($db));
+                       return false;
+               }
+               while ($acc = db_fetch($res)) {
+                       $sql = "UPDATE ".$pref."bank_trans SET bank_act='"
+                               .$acc['id']."' WHERE bank_act=".$acc['account_code'];
+                       if (db_query($sql)==false) {
+                       display_error(_("Cannot update bank transactions")
+                               .':<br>'. db_error_msg($db));
+                               return false;
+                       }
+               }
+               return true;
+       }
+       //
+       //      Checking before install
+       //
+       function pre_check($pref) 
+       {
+               return true; // true when ok, fail otherwise
+       }
+       //
+       //      Test if patch was applied before.
+       //
+       function installed($pref) {
+               return !check_table($pref, 'item_codes');
+       }
+};
+
+$install = new fa2_1;
+?>
\ No newline at end of file