diff --git a/application/controllers/Update.php b/application/controllers/Update.php
index 5c6937735..b3b3ef253 100644
--- a/application/controllers/Update.php
+++ b/application/controllers/Update.php
@@ -211,7 +211,7 @@ class Update extends CI_Controller {
$gz = gzopen($url, 'r');
if ($gz === FALSE) {
$this->update_status("FAILED: Could not download from clublog.org");
- log_message('error', 'FAILED: Could not download exceptions from clublog.org');
+ log_message('error', 'FAILED: Could not download data from clublog.org');
exit();
}
@@ -223,6 +223,7 @@ class Update extends CI_Controller {
if (file_put_contents($this->paths->make_update_path("cty.xml"), $data) === FALSE) {
$this->update_status("FAILED: Could not write to cty.xml file");
+ log_message('error', 'DXCC UPDATE FAILED: Could not write to cty.xml file');
exit();
}
diff --git a/install/includes/core/core_class.php b/install/includes/core/core_class.php
index a62ecce27..a9c80a215 100644
--- a/install/includes/core/core_class.php
+++ b/install/includes/core/core_class.php
@@ -8,22 +8,34 @@ class Core
{
// Counter variable
$counter = 0;
+ $errors = [];
// Validate the hostname
if (isset($data['db_hostname']) and !empty($data['db_hostname'])) {
$counter++;
+ } else {
+ $errors[] = "DB Hostname is missing.";
}
+
// Validate the username
if (isset($data['db_username']) and !empty($data['db_username'])) {
$counter++;
+ } else {
+ $errors[] = "DB Username is missing.";
}
+
// Validate the password
if (isset($data['db_password']) and !empty($data['db_password'])) {
- // pass
+ $counter++;
+ } else {
+ $errors[] = "DB Password is missing.";
}
+
// Validate the database
if (isset($data['db_name']) and !empty($data['db_name'])) {
$counter++;
+ } else {
+ $errors[] = "DB Name is missing.";
}
if ($data['directory'] ?? '' != "") {
@@ -31,36 +43,46 @@ class Core
//pass folders real
$counter++;
} else {
- echo "Directory " . $data['directory'] . " cannot be found";
- exit;
+ $errors[] = "Directory " . $data['directory'] . " does not exist.";
}
} else {
+ // directory is not set so nothing to check here
$counter++;
}
// Validate First Name
if (isset($data['firstname']) && !empty($data['firstname'])) {
$counter++;
+ } else {
+ $errors[] = "First Name is missing.";
}
// Validate Last Name
if (isset($data['lastname']) && !empty($data['lastname'])) {
$counter++;
+ } else {
+ $errors[] = "Last Name is missing.";
}
// Validate Username
if (isset($data['username']) && !empty($data['username'])) {
$counter++;
+ } else {
+ $errors[] = "Username is missing.";
}
// Validate Callsign
if (isset($data['callsign']) && !empty($data['callsign'])) {
$counter++;
+ } else {
+ $errors[] = "Callsign is missing.";
}
// Validate Password
if (isset($data['password']) && !empty($data['password'])) {
$counter++;
+ } else {
+ $errors[] = "User Password is missing.";
}
// Validate Locator
@@ -72,12 +94,14 @@ class Core
$errors[] = "Invalid Maidenhead Locator format.";
}
} else {
- $errors[] = "Locator is required.";
+ $errors[] = "Locator is missing.";
}
// Validate Confirm Password
if (isset($data['cnfm_password']) && !empty($data['cnfm_password'])) {
$counter++;
+ } else {
+ $errors[] = "Confirm Password is missing.";
}
// Validate Email Address
@@ -90,58 +114,81 @@ class Core
// Validate Timezone
if (isset($data['timezone']) && is_numeric($data['timezone'])) {
$counter++;
+ } else {
+ $errors[] = "Invalid Timezone.";
}
// Check if all the required fields have been entered
- if ($counter == '13') {
+ if ($counter == '14') {
+ log_message('info', 'Data validation passed.');
return true;
} else {
- log_message('error', 'Failed to validate POST data');
+ log_message('error', 'Data validation failed.');
+ foreach ($errors as $error) {
+ log_message('error', $error);
+ }
return false;
}
}
- // Function to write the config file
+ // Function to write the database config file
function write_config($data) {
$template_path = 'config/database.php';
$output_path = $_SERVER['DOCUMENT_ROOT'] . '/' . $data['directory'] . '/application/config/database.php';
if (isset($_ENV['CI_ENV'])) {
$output_path = $_SERVER['DOCUMENT_ROOT'] . '/' . $data['directory'] . '/application/config/'.$_ENV['CI_ENV'].'/database.php';
+ log_message('info', 'CI_ENV is set to ' . $_ENV['CI_ENV'] . '. Using ' . $_ENV['CI_ENV'] . ' database.php config path.');
+ } else {
+ log_message('info', 'CI_ENV is not set. Using default database.php config path.');
+ }
+
+ if (!file_exists($template_path)) {
+ log_message('error', 'database.php template file not found.');
+ return false;
}
// Open the file
$database_file = file_get_contents($template_path);
+ if ($database_file === false) {
+ log_message('error', 'Failed to read database.php template file.');
+ return false;
+ }
+ log_message('info', 'database.php template file read successfully.');
// Sanitize DB Password from single quotes
- $sanitized_db_pwd = preg_replace("/\\\\/i",'\\\\\\\\',$data['db_password']); // Escape the Escape char ( '\' becomes '\\' )
- $sanitized_db_pwd = preg_replace("/\'/i",'\\\\\'',$sanitized_db_pwd); // Escape the ' ( ' becomes \' )
+ $sanitized_db_pwd = preg_replace("/\\\\/i",'\\\\\\\\',$data['db_password']); // Escape the Escape char ( '\' becomes '\\' )
+ $sanitized_db_pwd = preg_replace("/\'/i",'\\\\\'',$sanitized_db_pwd); // Escape the ' ( ' becomes \' )
$new = str_replace("%HOSTNAME%", $data['db_hostname'], $database_file);
$new = str_replace("%USERNAME%", $data['db_username'], $new);
$new = str_replace("%PASSWORD%", $sanitized_db_pwd, $new);
$new = str_replace("%DATABASE%", $data['db_name'], $new);
+ log_message('info', 'Database config file prepared successfully. Writing to file...');
// Write the new database.php file
$handle = fopen($output_path, 'w+');
-
- // Chmod the file, in case the user forgot
- @chmod($output_path, 0777);
+ if ($handle === false) {
+ log_message('error', 'Failed to open target path for writing the database.php file.');
+ return false;
+ }
// Verify file permissions
if (is_writable($output_path)) {
-
// Write the file
if (fwrite($handle, $new)) {
if(file_exists($output_path)) {
+ log_message('info', 'database.php file written successfully.');
return true;
} else {
+ log_message('error', 'database.php file not found after writing.');
return false;
}
} else {
return false;
}
} else {
+ log_message('error', 'database.php path is not writable.');
return false;
}
}
@@ -153,15 +200,23 @@ class Core
$output_path = '../application/config/config.php';
if (isset($_ENV['CI_ENV'])) {
$output_path = '../application/config/'.$_ENV['CI_ENV'].'/config.php';
+ log_message('info', 'CI_ENV is set to ' . $_ENV['CI_ENV'] . '. Using ' . $_ENV['CI_ENV'] . ' config.php config path.');
+ } else {
+ log_message('info', 'CI_ENV is not set. Using default config.php config path.');
}
// Open the file
- $database_file = file_get_contents($template_path);
+ $config_file = file_get_contents($template_path);
+ if ($config_file === false) {
+ log_message('error', 'Failed to read config.php template file.');
+ return false;
+ }
+ log_message('info', 'config.php template file read successfully.');
// creating a unique encryption key
$encryptionkey = uniqid(bin2hex(random_bytes(8)), false);
- $new = str_replace("%baselocator%", strtoupper($data['userlocator']), $database_file);
+ $new = str_replace("%baselocator%", strtoupper($data['userlocator']), $config_file);
$new = str_replace("%websiteurl%", $data['websiteurl'], $new);
$new = str_replace("%directory%", $data['directory'], $new);
$new = str_replace("%callbook%", $data['global_call_lookup'], $new);
@@ -190,24 +245,31 @@ class Core
$new = str_replace("%encryptionkey%", $encryptionkey, $new);
$new = str_replace("'%log_threshold%'", $data['log_threshold'], $new);
+ log_message('info', 'Config.php file prepared successfully. Writing to file...');
// Write the new config.php file
$handle = fopen($output_path, 'w+');
+ if ($handle === false) {
+ log_message('error', 'Failed to open target path for writing the config.php file.');
+ return false;
+ }
// Verify file permissions
if (is_writable($output_path)) {
-
// Write the file
if (fwrite($handle, $new)) {
if(file_exists($output_path)) {
+ log_message('info', 'config.php file written successfully.');
return true;
} else {
+ log_message('error', 'config.php file not found after writing.');
return false;
}
} else {
return false;
}
} else {
+ log_message('error', 'config.php path is not writable.');
return false;
}
}
diff --git a/install/includes/core/database_class.php b/install/includes/core/database_class.php
index fe37dd9f2..5795b19cc 100644
--- a/install/includes/core/database_class.php
+++ b/install/includes/core/database_class.php
@@ -8,11 +8,16 @@ class Database {
$mysqli = new mysqli($data['db_hostname'], $data['db_username'], $data['db_password'], $data['db_name']);
// Check for errors
- if (mysqli_connect_errno())
+ if (mysqli_connect_errno()) {
+ log_message('error', 'Database connection error: ' . mysqli_connect_error());
return false;
+ }
// Open the default SQL file
- $query = file_get_contents('assets/install.sql');
+ if (!$query = file_get_contents('assets/install.sql')) {
+ log_message('error', 'Failed to read install.sql file.');
+ return false;
+ }
$newpw = password_hash($data['password'], PASSWORD_DEFAULT);
$newquery = str_replace("%%FIRSTUSER_NAME%%", str_replace("'", "\\'", $data['username']), $query);
@@ -26,24 +31,37 @@ class Database {
$newquery = str_replace("%%FIRSTUSER_DXCC%%", $data['dxcc'], $newquery);
$newquery = str_replace("%%FIRSTUSER_CITY%%", str_replace("'", "\\'", $data['city']), $newquery);
$newquery = str_replace("%%FIRSTUSER_USERLANGUAGE%%", $data['userlanguage'], $newquery);
+ log_message('info', 'SQL queries prepared successfully. Writing to database...');
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
- // Execute a multi query
- $mysqli->multi_query($newquery);
+ try {
+ // Execute a multi query
+ $mysqli->multi_query($newquery);
- // MultiQuery is NON-Blocking,so wait until everything is done
- do {
- null;
- } while ($mysqli->next_result());
+ // MultiQuery is NON-Blocking,so wait until everything is done
+ do {
+ null;
+ } while ($mysqli->next_result());
- $result = $mysqli->store_result();
+ $mysqli->store_result();
- // Close the connection
- $mysqli->close();
+ // Close the connection
+ $mysqli->close();
- return true;
+ log_message('info', 'Database tables created successfully.');
+ return true;
+
+ } catch (mysqli_sql_exception $e) {
+ log_message('error', 'Database Error: ' . $e->getMessage());
+
+ if ($mysqli->ping()) {
+ $mysqli->close();
+ }
+
+ return false;
+ }
}
function database_check($data) {
@@ -63,7 +81,6 @@ class Database {
throw new Exception(__("Unable to create database: ") . $link->error);
}
- // Wählen Sie die Datenbank aus
if (!$link->select_db($data['db_name'])) {
throw new Exception(__("Unable to select database: ") . $link->error);
}
@@ -74,12 +91,30 @@ class Database {
throw new Exception(__("Database is not empty."));
}
- $mysql_version = $link->server_info;
-
+ $version_query = $link->query("SELECT VERSION() as version")->fetch_assoc(); // $link->server_info sometimes returns wrong version or additional (in this case unnecessary) information, e.g. 5.5.5-10.3.29-MariaDB-0+deb10u1
+ if (!$version_query) {
+ throw new Exception(__("Unable to get Database version: ") . $link->error);
+ }
+ if (!isset($version_query['version'])) {
+ throw new Exception(__("Database version could not be retrieved."));
+ }
+ $mysql_version = $version_query['version'];
+
+ // in case of a previous failed installation it can happen that still the migration lockfile is existent
+ // this would prevent the migration from running or at least would cause a unnecessary delay
+ // so we delete it here
+ $lockfile = sys_get_temp_dir() . '/.migration_running';
+ if (file_exists($lockfile)) {
+ log_message('info', 'Removing migration lockfile. Not expected to be present at this point.');
+ unlink($lockfile);
+ }
+
$link->close();
return $mysql_version;
+
} catch (Exception $e) {
+ log_message('error', 'Database Check Error: ' . $e->getMessage());
return 'Error: ' . $e->getMessage();
}
}
diff --git a/install/index.php b/install/index.php
index 52384055f..ae4b6917f 100644
--- a/install/index.php
+++ b/install/index.php
@@ -1557,7 +1557,7 @@ if (!file_exists('.lock')) {
} else {
db_connection_results.addClass('alert-warning');
$('#db_connection_test_button').html(originalButtonText).prop('disabled', false);
- db_connection_results.html("= __('Connection was successful but your database seems too old for Wavelog. You can try to continue but you could run into issues.'); ?> " + "= sprintf(__("The min. version for MySQL is %s, for MariaDB it's %s."), '' . $mysql_version . '', '' . $mariadb_version . ''); ?>");
+ db_connection_results.html("= __("Connection was successful but your database seems too old for Wavelog. You can try to continue but you could run into issues."); ?> " + "= sprintf(__("The min. version for MySQL is %s, for MariaDB it's %s."), '' . $mysql_version . '', '' . $mariadb_version . ''); ?>");
}
resolve(true);
}
@@ -1857,7 +1857,7 @@ if (!file_exists('.lock')) {
if ((checklistPrechecks.hasClass('fa-check-circle') || checklistPrechecks.hasClass('fa-exclamation-triangle')) &&
checklistConfiguration.hasClass('fa-check-circle') &&
- checklistDatabase.hasClass('fa-check-circle') &&
+ (checklistDatabase.hasClass('fa-check-circle') || checklistDatabase.hasClass('fa-exclamation-triangle')) &&
(checklistFirstUser.hasClass('fa-check-circle') || checklistFirstUser.hasClass('fa-exclamation-triangle'))) {
install_possible = true;
}
diff --git a/install/run.php b/install/run.php
index 339e08ec8..6cb1879d3 100644
--- a/install/run.php
+++ b/install/run.php
@@ -148,7 +148,7 @@
}
},
error: async function(error) {
- await log_message('error', "Install Lock Check went wrong...");
+ await log_message('error', "Install Lock Check went wrong... Ajax failed. Error: " + error.status);
reject(error);
window.location.href = "" + "index.php/user/login";
}
@@ -183,7 +183,7 @@
}
},
error: async function(error) {
- await log_message('error', 'File: Could not write file. Ajax failed.');
+ await log_message('error', 'File: Could not write file. Ajax failed. Status: ' + error.status + ' Status Text: ' + error.statusText);
running(field, false, true);
reject(error);
}
@@ -218,7 +218,7 @@
}
},
error: async function(error) {
- await log_message('error', 'File: Could not write file. Ajax failed.');
+ await log_message('error', 'File: Could not write file. Ajax failed. Status: ' + error.status + ' Status Text: ' + error.statusText);
running(field, false, true);
reject(error);
}
@@ -253,7 +253,7 @@
},
error: async function(error) {
running(field, false, true);
- await log_message('error', 'Creating database tables failed. Ajax crashed.');
+ await log_message('error', 'Creating database tables failed. Ajax crashed. Status: ' + error.status + ' Status Text: ' + error.statusText);
reject(error);
}
});
@@ -283,7 +283,7 @@
},
error: async function(error) {
running(field, false, true);
- await log_message('error', 'Could not migrate database. Ajax crashed.');
+ await log_message('error', 'Could not migrate database. Ajax crashed. Status: ' + error.status + ' Status Text: ' + error.statusText);
reject(error);
}
});
@@ -305,13 +305,13 @@
resolve();
} else {
running(field, false, true);
- await log_message('error', 'Could not update DXCC data.');
+ await log_message('error', 'Could not update DXCC data. Check application/logs for any error messages.');
reject("= __("Could not update DXCC data"); ?>");
}
},
error: async function(error) {
running(field, false, true);
- await log_message('error', 'Could not update DXCC data. Ajax crashed.');
+ await log_message('error', 'Could not update DXCC data. Ajax crashed. Status: ' + error.status + ' Status Text: ' + error.statusText);
reject(error);
}
});
@@ -343,7 +343,7 @@
},
error: async function(error) {
running(field, false, true);
- await log_message('error', 'Could not create .lock file. Ajax crashed');
+ await log_message('error', 'Could not create .lock file. Ajax crashed. Status: ' + error.status + ' Status Text: ' + error.statusText);
reject(error);
}
});
diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php
index 256748747..e27ade116 100644
--- a/system/libraries/Migration.php
+++ b/system/libraries/Migration.php
@@ -348,8 +348,10 @@ class CI_Migration {
log_message('debug', 'Finished migrating to '.$current_version);
// After the migrations we can remove the lockfile
- unlink($this->_migration_lockfile);
- log_message('debug', 'Deleted migration lockfile');
+ if (file_exists($this->_migration_lockfile)) {
+ unlink($this->_migration_lockfile);
+ log_message('debug', 'Deleted migration lockfile');
+ }
} else {
log_message('error', 'Failed to create Migration Lockfile. Check directory permissions.');