From f36203b87aa5385ce85ac15599ebbea1d5f0f2f1 Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Sat, 20 Dec 2025 12:06:23 +0100 Subject: [PATCH 1/8] [DBTools] Some fixes --- application/views/logbookadvanced/dbtoolsdialog.php | 2 +- .../views/logbookadvanced/showMissingDxccQsos.php | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/application/views/logbookadvanced/dbtoolsdialog.php b/application/views/logbookadvanced/dbtoolsdialog.php index 543052a43..fedec1139 100644 --- a/application/views/logbookadvanced/dbtoolsdialog.php +++ b/application/views/logbookadvanced/dbtoolsdialog.php @@ -90,7 +90,7 @@ - config->item('callbook_batch_lookup')): ?> + config->item('callbook_batch_lookup') ?? true): ?>
diff --git a/application/views/logbookadvanced/showMissingDxccQsos.php b/application/views/logbookadvanced/showMissingDxccQsos.php index f98c3049a..8a6f3e7f7 100644 --- a/application/views/logbookadvanced/showMissingDxccQsos.php +++ b/application/views/logbookadvanced/showMissingDxccQsos.php @@ -1,3 +1,12 @@ +session->userdata('user_date_format')) { + // If Logged in and session exists + $custom_date_format = $this->session->userdata('user_date_format'); +} else { + // Get Default date format from /config/wavelog.php + $custom_date_format = $this->config->item('qso_date_format'); +} +?>
0): ?>
@@ -21,7 +30,7 @@ col_primary_key . ')">' . htmlspecialchars($qso->col_call) . ''; ?> - col_time_on)); ?> + col_time_on)); ?> col_mode; ?> col_band; ?> col_state; ?> From 5537f6ed43fb178fc488a6803cc88e8dcdd07cb0 Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Sat, 20 Dec 2025 12:53:31 +0100 Subject: [PATCH 2/8] Changed header in table --- application/models/Logbookadvanced_model.php | 120 +++++++++++++++++- .../logbookadvanced/showMissingDxccQsos.php | 2 +- 2 files changed, 120 insertions(+), 2 deletions(-) diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php index f5a7522d7..6161260dd 100644 --- a/application/models/Logbookadvanced_model.php +++ b/application/models/Logbookadvanced_model.php @@ -1609,7 +1609,7 @@ class Logbookadvanced_model extends CI_Model { $count = 0; foreach ($query->result() as $qso) { - $result = $this->fixStateSingle($qso->COL_PRIMARY_KEY); + $result = $this->fixStateDxcc($qso->COL_PRIMARY_KEY); if ($result['success']) { $count++; } else { @@ -1625,6 +1625,124 @@ class Logbookadvanced_model extends CI_Model { return $results; } + /** + * Fix state for a batch of QSOs, based on the DXCC + * + * @param int $qso_id QSO primary key + * @return array Result array with success, dxcc_name, dxcc_number, state_code, skipped + */ + function fixStateDxcc($qso_id) { + $this->load->library('Geojson'); + + // Get QSO data + $sql = "SELECT COL_PRIMARY_KEY, COL_CALL, COL_GRIDSQUARE, COL_DXCC, COL_STATE, d.name as dxcc_name + FROM " . $this->config->item('table_name') . " qsos + JOIN station_profile ON qsos.station_id = station_profile.station_id + LEFT JOIN dxcc_entities d ON qsos.COL_DXCC = d.adif + WHERE qsos.COL_PRIMARY_KEY = ? AND station_profile.user_id = ?"; + + $query = $this->db->query($sql, [$qso_id, $this->session->userdata('user_id')]); + + if ($query->num_rows() === 0) { + return [ + 'success' => false, + 'skipped' => true, + 'reason' => 'QSO not found' + ]; + } + + $qso = $query->row(); + $callsign = $qso->COL_CALL ?? 'Unknown'; + $dxcc = (int)$qso->COL_DXCC; + $gridsquare = $qso->COL_GRIDSQUARE; + $state = $qso->COL_STATE ?? ''; + $dxcc_name = $qso->dxcc_name ?? 'Unknown'; + + // Skip if state is already populated + if (!empty($state)) { + return [ + 'success' => false, + 'skipped' => true, + 'callsign' => $callsign, + 'dxcc_number' => $dxcc, + 'dxcc_name' => $dxcc_name, + 'reason' => 'State already set' + ]; + } + + // Check if gridsquare exists + if (empty($gridsquare)) { + return [ + 'success' => false, + 'skipped' => true, + 'callsign' => $callsign, + 'dxcc_number' => $dxcc, + 'dxcc_name' => $dxcc_name, + 'reason' => 'No gridsquare' + ]; + } + + // Check if gridsquare is precise enough (at least 6 characters) + if (strlen($gridsquare) < 6) { + return [ + 'success' => false, + 'skipped' => true, + 'callsign' => $callsign, + 'dxcc_number' => $dxcc, + 'dxcc_name' => $dxcc_name, + 'reason' => 'Gridsquare not precise enough' + ]; + } + + // Check if state is supported for this DXCC + if (!$this->geojson->isStateSupported($dxcc)) { + return [ + 'success' => false, + 'skipped' => true, + 'callsign' => $callsign, + 'dxcc_number' => $dxcc, + 'dxcc_name' => $dxcc_name, + 'reason' => 'DXCC not supported' + ]; + } + + // Find state from gridsquare + $state = $this->geojson->findStateFromGridsquare($gridsquare, $dxcc); + + if ($state === null || !isset($state['code'])) { + // Get coordinates for debugging + $coords = $this->geojson->gridsquareToLatLng($gridsquare); + return [ + 'success' => false, + 'skipped' => false, + 'callsign' => $callsign, + 'dxcc_number' => $dxcc, + 'dxcc_name' => $dxcc_name, + 'gridsquare' => $gridsquare, + 'lat' => $coords['lat'] ?? null, + 'lng' => $coords['lng'] ?? null, + 'reason' => 'State not found in GeoJSON' + ]; + } + + // Update the state + $update_sql = "UPDATE " . $this->config->item('table_name') . " + SET COL_STATE = ? + WHERE COL_PRIMARY_KEY = ?"; + + $this->db->query($update_sql, [$state['code'], $qso_id]); + + return [ + 'success' => true, + 'skipped' => false, + 'callsign' => $callsign, + 'dxcc_number' => $dxcc, + 'dxcc_name' => $dxcc_name, + 'state_code' => $state['code'], + 'state_name' => $state['name'] ?? null + ]; + } + function getStateListQsos($dxcc) { $sql = "SELECT col_primary_key, col_call, col_time_on, col_mode, col_submode, col_band, col_state, col_gridsquare, d.name as dxcc_name, station_profile.station_profile_name FROM " . $this->config->item('table_name') . " qsos JOIN station_profile ON qsos.station_id = station_profile.station_id diff --git a/application/views/logbookadvanced/showMissingDxccQsos.php b/application/views/logbookadvanced/showMissingDxccQsos.php index 8a6f3e7f7..4f6b58f7f 100644 --- a/application/views/logbookadvanced/showMissingDxccQsos.php +++ b/application/views/logbookadvanced/showMissingDxccQsos.php @@ -23,7 +23,7 @@ if($this->session->userdata('user_date_format')) { - + From 5375f03fb8e89606823b625f791c0fe332ac5e07 Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Sat, 20 Dec 2025 15:53:05 +0100 Subject: [PATCH 3/8] Load geojson file in constructor --- application/libraries/Geojson.php | 18 +++++++++++++----- application/models/Logbookadvanced_model.php | 4 +--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/application/libraries/Geojson.php b/application/libraries/Geojson.php index 8d3890dc2..db4b87772 100644 --- a/application/libraries/Geojson.php +++ b/application/libraries/Geojson.php @@ -66,11 +66,17 @@ class Geojson { ]; private $qra; + private $geojsonFile = null; + private $geojsonData = null; - public function __construct() { + public function __construct($dxcc = null) { $CI =& get_instance(); $CI->load->library('qra'); $this->qra = $CI->qra; + if ($dxcc !== null) { + $this->geojsonFile = "assets/json/geojson/states_{$dxcc}.geojson"; + $this->geojsonData = $this->loadGeoJsonFile($geojsonFile); + } } // ============================================================================ @@ -114,14 +120,16 @@ class Geojson { return null; } - $geojsonFile = "assets/json/geojson/states_{$dxcc}.geojson"; - $geojsonData = $this->loadGeoJsonFile($geojsonFile); + if ($this->geojsonFile === null) { + $this->geojsonFile = "assets/json/geojson/states_{$dxcc}.geojson"; + $this->geojsonData = $this->loadGeoJsonFile($this->geojsonFile); + } - if ($geojsonData === null) { + if ($this->geojsonData === null) { return null; } - return $this->findFeatureContainingPoint($lat, $lng, $geojsonData); + return $this->findFeatureContainingPoint($lat, $lng, $this->geojsonData); } /** diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php index 6161260dd..5052e6e50 100644 --- a/application/models/Logbookadvanced_model.php +++ b/application/models/Logbookadvanced_model.php @@ -1583,7 +1583,7 @@ class Logbookadvanced_model extends CI_Model { * @return array Result array with success, dxcc_name, dxcc_number, state_code, skipped */ function fixStateBatch($dxcc) { - $this->load->library('Geojson'); + $this->load->library('Geojson', $dxcc); // Get QSO data $sql = "SELECT COL_PRIMARY_KEY, COL_CALL, COL_GRIDSQUARE, COL_DXCC, COL_STATE, d.name as dxcc_name, station_profile.station_profile_name @@ -1632,8 +1632,6 @@ class Logbookadvanced_model extends CI_Model { * @return array Result array with success, dxcc_name, dxcc_number, state_code, skipped */ function fixStateDxcc($qso_id) { - $this->load->library('Geojson'); - // Get QSO data $sql = "SELECT COL_PRIMARY_KEY, COL_CALL, COL_GRIDSQUARE, COL_DXCC, COL_STATE, d.name as dxcc_name FROM " . $this->config->item('table_name') . " qsos From 136f2213dccf6e077ace326d3e549b5abcb96bae Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Sat, 20 Dec 2025 16:05:28 +0100 Subject: [PATCH 4/8] Optimize state setting --- application/models/Logbookadvanced_model.php | 72 +------------------- 1 file changed, 3 insertions(+), 69 deletions(-) diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php index 5052e6e50..beba8c37a 100644 --- a/application/models/Logbookadvanced_model.php +++ b/application/models/Logbookadvanced_model.php @@ -1609,7 +1609,7 @@ class Logbookadvanced_model extends CI_Model { $count = 0; foreach ($query->result() as $qso) { - $result = $this->fixStateDxcc($qso->COL_PRIMARY_KEY); + $result = $this->fixStateDxcc($qso); if ($result['success']) { $count++; } else { @@ -1631,79 +1631,13 @@ class Logbookadvanced_model extends CI_Model { * @param int $qso_id QSO primary key * @return array Result array with success, dxcc_name, dxcc_number, state_code, skipped */ - function fixStateDxcc($qso_id) { - // Get QSO data - $sql = "SELECT COL_PRIMARY_KEY, COL_CALL, COL_GRIDSQUARE, COL_DXCC, COL_STATE, d.name as dxcc_name - FROM " . $this->config->item('table_name') . " qsos - JOIN station_profile ON qsos.station_id = station_profile.station_id - LEFT JOIN dxcc_entities d ON qsos.COL_DXCC = d.adif - WHERE qsos.COL_PRIMARY_KEY = ? AND station_profile.user_id = ?"; - - $query = $this->db->query($sql, [$qso_id, $this->session->userdata('user_id')]); - - if ($query->num_rows() === 0) { - return [ - 'success' => false, - 'skipped' => true, - 'reason' => 'QSO not found' - ]; - } - - $qso = $query->row(); + function fixStateDxcc($qso) { $callsign = $qso->COL_CALL ?? 'Unknown'; $dxcc = (int)$qso->COL_DXCC; $gridsquare = $qso->COL_GRIDSQUARE; $state = $qso->COL_STATE ?? ''; $dxcc_name = $qso->dxcc_name ?? 'Unknown'; - // Skip if state is already populated - if (!empty($state)) { - return [ - 'success' => false, - 'skipped' => true, - 'callsign' => $callsign, - 'dxcc_number' => $dxcc, - 'dxcc_name' => $dxcc_name, - 'reason' => 'State already set' - ]; - } - - // Check if gridsquare exists - if (empty($gridsquare)) { - return [ - 'success' => false, - 'skipped' => true, - 'callsign' => $callsign, - 'dxcc_number' => $dxcc, - 'dxcc_name' => $dxcc_name, - 'reason' => 'No gridsquare' - ]; - } - - // Check if gridsquare is precise enough (at least 6 characters) - if (strlen($gridsquare) < 6) { - return [ - 'success' => false, - 'skipped' => true, - 'callsign' => $callsign, - 'dxcc_number' => $dxcc, - 'dxcc_name' => $dxcc_name, - 'reason' => 'Gridsquare not precise enough' - ]; - } - - // Check if state is supported for this DXCC - if (!$this->geojson->isStateSupported($dxcc)) { - return [ - 'success' => false, - 'skipped' => true, - 'callsign' => $callsign, - 'dxcc_number' => $dxcc, - 'dxcc_name' => $dxcc_name, - 'reason' => 'DXCC not supported' - ]; - } - // Find state from gridsquare $state = $this->geojson->findStateFromGridsquare($gridsquare, $dxcc); @@ -1728,7 +1662,7 @@ class Logbookadvanced_model extends CI_Model { SET COL_STATE = ? WHERE COL_PRIMARY_KEY = ?"; - $this->db->query($update_sql, [$state['code'], $qso_id]); + $this->db->query($update_sql, [$state['code'], $qso->COL_PRIMARY_KEY]); return [ 'success' => true, From 3b1f7f71b0dbc3641a352098be2a0abf80d28169 Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Sun, 21 Dec 2025 08:11:22 +0100 Subject: [PATCH 5/8] We don't need coordinates --- application/models/Logbookadvanced_model.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php index beba8c37a..6e8ff6cd1 100644 --- a/application/models/Logbookadvanced_model.php +++ b/application/models/Logbookadvanced_model.php @@ -1642,8 +1642,6 @@ class Logbookadvanced_model extends CI_Model { $state = $this->geojson->findStateFromGridsquare($gridsquare, $dxcc); if ($state === null || !isset($state['code'])) { - // Get coordinates for debugging - $coords = $this->geojson->gridsquareToLatLng($gridsquare); return [ 'success' => false, 'skipped' => false, @@ -1651,8 +1649,6 @@ class Logbookadvanced_model extends CI_Model { 'dxcc_number' => $dxcc, 'dxcc_name' => $dxcc_name, 'gridsquare' => $gridsquare, - 'lat' => $coords['lat'] ?? null, - 'lng' => $coords['lng'] ?? null, 'reason' => 'State not found in GeoJSON' ]; } From 97868db3c86be350c54e4b95fef849f60204d623 Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Sun, 21 Dec 2025 08:20:40 +0100 Subject: [PATCH 6/8] Batch update --- application/models/Logbookadvanced_model.php | 28 ++++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php index 6e8ff6cd1..ed4d2011d 100644 --- a/application/models/Logbookadvanced_model.php +++ b/application/models/Logbookadvanced_model.php @@ -1605,13 +1605,17 @@ class Logbookadvanced_model extends CI_Model { } $results = []; - - $count = 0; + $batch_updates = []; foreach ($query->result() as $qso) { $result = $this->fixStateDxcc($qso); + if ($result['success']) { - $count++; + // Prepare data for batch update + $batch_updates[] = [ + 'COL_PRIMARY_KEY' => $qso->COL_PRIMARY_KEY, + 'COL_STATE' => $result['state_code'] + ]; } else { $result['station_profile_name'] = $qso->station_profile_name; $result['id'] = $qso->COL_PRIMARY_KEY; @@ -1620,6 +1624,13 @@ class Logbookadvanced_model extends CI_Model { } } + // Perform batch update if there are any updates + $count = 0; + if (!empty($batch_updates)) { + $this->db->update_batch($this->config->item('table_name'), $batch_updates, 'COL_PRIMARY_KEY'); + $count = count($batch_updates); + } + $results['count'] = $count; return $results; @@ -1627,8 +1638,9 @@ class Logbookadvanced_model extends CI_Model { /** * Fix state for a batch of QSOs, based on the DXCC + * Note: This now only validates and prepares data * - * @param int $qso_id QSO primary key + * @param object $qso QSO object * @return array Result array with success, dxcc_name, dxcc_number, state_code, skipped */ function fixStateDxcc($qso) { @@ -1653,13 +1665,7 @@ class Logbookadvanced_model extends CI_Model { ]; } - // Update the state - $update_sql = "UPDATE " . $this->config->item('table_name') . " - SET COL_STATE = ? - WHERE COL_PRIMARY_KEY = ?"; - - $this->db->query($update_sql, [$state['code'], $qso->COL_PRIMARY_KEY]); - + // Return success with state info return [ 'success' => true, 'skipped' => false, From 09bbaf18989898b23b6626f71c895067b7ca2067 Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Sun, 21 Dec 2025 08:28:52 +0100 Subject: [PATCH 7/8] Remove commented out text --- application/views/logbookadvanced/index.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/application/views/logbookadvanced/index.php b/application/views/logbookadvanced/index.php index 3e8a453c8..1b773023b 100644 --- a/application/views/logbookadvanced/index.php +++ b/application/views/logbookadvanced/index.php @@ -773,14 +773,6 @@ $options = json_decode($options);
-
From bf8b8b71008b49d4ad41c37ec168f5b4656ca42a Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Sun, 21 Dec 2025 08:41:48 +0100 Subject: [PATCH 8/8] Limit callbook grid fixer to 150 per run, and add batch update --- application/models/Logbookadvanced_model.php | 30 +++++++++++++------ .../views/logbookadvanced/dbtoolsdialog.php | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php index ed4d2011d..c7f0bce01 100644 --- a/application/models/Logbookadvanced_model.php +++ b/application/models/Logbookadvanced_model.php @@ -1776,29 +1776,41 @@ class Logbookadvanced_model extends CI_Model { $result = $this->getMissingGridQsos(); $count = 0; + $batch_updates = []; + $this->db->trans_start(); + if (count($result) > 0) { + if (!$this->load->is_loaded('callbook')) { + $this->load->library('callbook'); + } + foreach ($result as $row) { $callsign = $row->col_call; - if (!$this->load->is_loaded('callbook')) { - $this->load->library('callbook'); - } - $callbook = $this->callbook->getCallbookData($callsign); if (isset($callbook)) { if (isset($callbook['error'])) { log_message('error', "Error: " . $callbook['error']); } else { - if ($callbook['gridsquare'] != '') { - $sql = "update " . $this->config->item('table_name') . " set COL_GRIDSQUARE = ? where COL_PRIMARY_KEY = ?"; - $this->db->query($sql, array($callbook['gridsquare'], $row->col_primary_key)); - $count++; + if (isset($callbook['gridsquare']) && $callbook['gridsquare'] != '') { + // Prepare data for batch update + $batch_updates[] = [ + 'COL_PRIMARY_KEY' => $row->col_primary_key, + 'COL_GRIDSQUARE' => $callbook['gridsquare'] + ]; } } } } + + // Perform batch update if there are any updates + if (!empty($batch_updates)) { + $this->db->update_batch($this->config->item('table_name'), $batch_updates, 'COL_PRIMARY_KEY'); + $count = count($batch_updates); + } } + $this->db->trans_complete(); return $count; @@ -1810,7 +1822,7 @@ class Logbookadvanced_model extends CI_Model { WHERE station_profile.user_id = ? AND (qsos.COL_GRIDSQUARE IS NULL OR qsos.COL_GRIDSQUARE = '') AND (qsos.COL_VUCC_GRIDS IS NULL OR qsos.COL_VUCC_GRIDS = '') - ORDER BY COL_TIME_ON DESC limit 250"; + ORDER BY COL_TIME_ON DESC limit 150"; $query = $this->db->query($sql, [$this->session->userdata('user_id')]); diff --git a/application/views/logbookadvanced/dbtoolsdialog.php b/application/views/logbookadvanced/dbtoolsdialog.php index fedec1139..c9a14318c 100644 --- a/application/views/logbookadvanced/dbtoolsdialog.php +++ b/application/views/logbookadvanced/dbtoolsdialog.php @@ -95,7 +95,7 @@

-

+