2 /**********************************************************************
3 Copyright (C) FrontAccounting, LLC.
4 Released under the terms of the GNU General Public License, GPL,
5 as published by the Free Software Foundation, either version 3
6 of the License, or (at your option) any later version.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12 include_once($path_to_root."/includes/packages.inc");
14 // Utility class contains basic database upgrade routines.
17 var $previous; // previous database version
18 var $version; // version after upgrade
19 var $description; // short patch description
21 var $sql; // basic sql file
24 var $backup; // pre-upgrade backup filename
26 var $errors = array();
27 var $max_upgrade_time = 300;
33 include $path_to_root."/config_db.php";
35 $this->companies = $db_connections;
37 return $this->companies;
41 Collect/log messages generated during upgrade process.
43 function log_error($msg, $type='Error')
46 $this->errors[] = $msg;
47 error_log(sprintf('[%s] %s', $type, $msg));
52 Check and disable incompatible extensions.
54 function update_extensions()
58 $mods = get_company_extensions();
59 $exts = get_company_extensions($this->cur_company);
62 foreach($mods as $key => $ins) {
63 foreach($exts as $ext)
64 if ($ext['name'] == $ins['name'] && (!check_src_ext_version($ins['version']))) {
65 $mods[$key]['active'] = false;
66 $this->log_error(sprintf(_("Uncompatible extension '%s' disabled for company %d."), $ins['name'], $this->cur_company), 'Notice');
72 write_extensions($mods, $this->cur_company);
76 Pre-install maintenance: login to company, open upgrade log, make a backup
78 function pre_install($company)
82 $this->cur_company = $company;
83 $this->errors = array();
86 $this->save_log = ini_set('error_log', dirname(__FILE__).'/../../tmp/upgrade.'.$this->cur_company.'.log');
87 $this->log_error(sprintf(_("Upgrade started for company %s."), $this->cur_company), 'Info');
89 if (!set_global_connection($this->cur_company))
90 return $this->log_error(_("Cannot connect to company database."));
92 $cur_ver = get_company_pref('version_id', true);
93 if ($cur_ver != $this->previous)
94 return $this->log_error(sprintf(_("Cannot upgrade company %s: database version is incompatible ('%s' instead of '%s')."),
95 $this->cur_company, $cur_ver, $this->previous));
97 $this->update_extensions(); // disable uncompatible extensions
99 if (!$this->prepare()) // fetch params, perform additional checks (if any)
103 return true; // skip security backup if database content is not changed
105 $this->backup = db_backup($this->companies[$this->cur_company], 'no', 'Security backup before upgrade',
106 $SysPrefs->backup_dir($this->cur_company));
109 return $this->log_error(_("Security backup failed."));
111 $this->log_error(sprintf(_("Security backup in file %s done."), $this->backup), 'Info');
116 Basic install procedure using sql file.
118 function sql_install($company, $force=false)
120 global $path_to_root;
122 if ($this->sql != '') // perform basic upgrade operations defined in sql file
126 if ($result === true)
127 $result = db_import($path_to_root. '/sql/'.$this->sql, $this->companies[$company],
128 $force, true, false, true);
130 if ($result !== true)
132 if (is_array($result))
134 foreach($result as $err)
135 $this->log_error($err[1] . ':'. $err[0]);
138 $this->log_error($result);
139 unset($this->backup); // prevent restore (database was not touched due to other errors)
148 Post install procedures: update database version, or restore databse from backup file in case of errors
150 function post_install($result=true)
154 if ($result !== true)
158 if (!set_global_connection($this->cur_company)) // reset connection to clear encoding
159 return $this->log_error(_("Cannot connect to company database for database restore."));
161 set_time_limit($this->max_upgrade_time);
162 $result = db_import($this->backup, $this->companies[$this->cur_company], true, false);
164 $this->log_error(_("Upgrade failed. Original database content restored successfully."), 'Info');
166 $thi->log_error(sprintf(_("Database restore operation failed. Original database content is in %s file."), $this->backup));
167 $this->post_fail($this->cur_company);
170 update_company_prefs(array('version_id' => $this->version));
173 $this->log_error(sprintf(_("Upgrade for company %s finished."), $this->cur_company), 'Info');
175 set_global_connection();
176 ini_set('error_log', $this->save_log);
185 Main routine for single company upgrade.
187 function upgrade_company($comp, $force=false)
189 $result = $this->pre_install($comp) && $this->sql_install($comp, $force) && $this->install($comp, $force);
191 $this->post_install($result);
193 return count($this->errors) == 0;
197 Additional version specific php/sql upgrade procedures.
198 This procedure is performed after basic sql upgrade script is run.
200 function install($company, $force=false)
205 Optional cleanup procedure.
206 This procedure is run in case of upgrade failure, before the backup is restored.
208 function post_fail($company)
213 Present upgrade parameters to administrator
214 This function presents upgrade choices, after selection company to be upgraded.
216 function show_params($comp)
221 Fetch & check upgrade parameters, check additional upgrade pre-conditions.
222 This function is run after successfull switching to target database connection.
232 Return databases status info.
234 function get_site_status($connections)
240 foreach($connections as $i => $conn)
242 $info[$i]['status'] = set_global_connection($i) !== false;
244 $info[$i]['name'] = $conn['name'];
245 $info[$i]['table_set'] = $conn['host'].'/'.$conn['dbname'].':'.$conn['tbpref'].'*';
246 if ($info[$i]['status'])
248 $info[$i]['version'] = get_company_pref('version_id');
251 set_global_connection();
252 $SysPrefs->refresh();
258 Creates table of installer objects sorted by applicable db scheme version.
260 function get_installers()
262 global $path_to_root;
264 $patchdir = $path_to_root."/sql/";
266 $datadir = @opendir($patchdir);
270 while(false !== ($fname = readdir($datadir)))
271 { // check all php files but index.php
272 if (!is_dir($patchdir . $fname) && ($fname != 'index.php')
273 && stristr($fname, '.php') != false && $fname[0] != '.')
276 include_once($patchdir . $fname);
277 if (isset($install)) // add installer if found
278 $upgrades[$install->previous] = $install;
281 ksort($upgrades); // sort by file name