From d1bb6ff3eafb3363003d6a36dbcf9fc4d8b54b1d Mon Sep 17 00:00:00 2001 From: Peter Goodhall Date: Mon, 11 Aug 2025 16:08:06 +0100 Subject: [PATCH] Add DXCC satellite contact tracking and display Introduces 'workedViaSatellite' status to DXCC tracking in both controller and model, including batch queries for satellite contacts. Updates the DXCC list view to show a badge when a country has been worked via satellite, improving visibility of satellite achievements. --- application/controllers/Workabledxcc.php | 19 +++- application/models/Workabledxcc_model.php | 93 ++++++++++++++++++- .../workabledxcc/components/dxcclist.php | 5 + 3 files changed, 111 insertions(+), 6 deletions(-) diff --git a/application/controllers/Workabledxcc.php b/application/controllers/Workabledxcc.php index 8f580221..76964818 100644 --- a/application/controllers/Workabledxcc.php +++ b/application/controllers/Workabledxcc.php @@ -69,7 +69,11 @@ class Workabledxcc extends CI_Controller // Get DXCC status for this callsign $entity = $dxccEntities[$index] ?? null; - $worked = $entity && isset($dxccStatus[$entity]) ? $dxccStatus[$entity] : ['workedBefore' => false, 'confirmed' => false]; + $worked = $entity && isset($dxccStatus[$entity]) ? $dxccStatus[$entity] : [ + 'workedBefore' => false, + 'confirmed' => false, + 'workedViaSatellite' => false + ]; $requiredData[] = array( 'clean_date' => $item['0'], @@ -80,6 +84,7 @@ class Workabledxcc extends CI_Controller 'callsign' => $item['callsign'], 'workedBefore' => $worked['workedBefore'], 'confirmed' => $worked['confirmed'], + 'workedViaSatellite' => $worked['workedViaSatellite'], ); } @@ -93,6 +98,7 @@ class Workabledxcc extends CI_Controller $return = [ "workedBefore" => false, "confirmed" => false, + "workedViaSatellite" => false, ]; $user_default_confirmation = $this->session->userdata('user_default_confirmation'); @@ -101,6 +107,7 @@ class Workabledxcc extends CI_Controller $this->load->model('logbook_model'); if (!empty($logbooks_locations_array)) { + // Check terrestrial contacts $this->db->where('COL_PROP_MODE !=', 'SAT'); $this->db->where_in('station_id', $logbooks_locations_array); @@ -112,6 +119,16 @@ class Workabledxcc extends CI_Controller $return['workedBefore'] = true; } + // Check satellite contacts + $this->db->where('COL_PROP_MODE', 'SAT'); + $this->db->where_in('station_id', $logbooks_locations_array); + $this->db->where('UPPER(COL_COUNTRY) = UPPER(?)', urldecode($country)); + + $query = $this->db->get($this->config->item('table_name'), 1, 0); + foreach ($query->result() as $satelliteRow) { + $return['workedViaSatellite'] = true; + } + $extrawhere = ''; if (isset($user_default_confirmation) && strpos($user_default_confirmation, 'Q') !== false) { $extrawhere = "COL_QSL_RCVD='Y'"; diff --git a/application/models/Workabledxcc_model.php b/application/models/Workabledxcc_model.php index dd2601a5..55f765e5 100644 --- a/application/models/Workabledxcc_model.php +++ b/application/models/Workabledxcc_model.php @@ -47,7 +47,11 @@ class Workabledxcc_model extends CI_Model $logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook')); if (empty($logbooks_locations_array)) { - return array_fill_keys($entities, ['workedBefore' => false, 'confirmed' => false]); + return array_fill_keys($entities, [ + 'workedBefore' => false, + 'confirmed' => false, + 'workedViaSatellite' => false + ]); } $results = array(); @@ -55,23 +59,80 @@ class Workabledxcc_model extends CI_Model // Build confirmation criteria once $confirmationCriteria = $this->buildConfirmationCriteria($user_default_confirmation); - // Batch query for worked status + // Debug: Log entities being checked + log_message('debug', 'Workable DXCC: Checking entities: ' . implode(', ', $entities)); + + // Batch query for worked status (terrestrial) $workedResults = $this->batchWorkedQuery($entities, $logbooks_locations_array); - // Batch query for confirmed status + // Batch query for confirmed status (terrestrial) $confirmedResults = $this->batchConfirmedQuery($entities, $logbooks_locations_array, $confirmationCriteria); + // Batch query for satellite contacts + $satelliteResults = $this->batchSatelliteQuery($entities, $logbooks_locations_array); + + // Debug: Log results + log_message('debug', 'Workable DXCC: Worked results: ' . json_encode($workedResults)); + log_message('debug', 'Workable DXCC: Confirmed results: ' . json_encode($confirmedResults)); + log_message('debug', 'Workable DXCC: Satellite results: ' . json_encode($satelliteResults)); + // Combine results foreach ($entities as $entity) { $results[$entity] = [ 'workedBefore' => isset($workedResults[$entity]), - 'confirmed' => isset($confirmedResults[$entity]) + 'confirmed' => isset($confirmedResults[$entity]), + 'workedViaSatellite' => isset($satelliteResults[$entity]) ]; } return $results; } + /** + * Batch query to check which entities have been worked via satellite + */ + private function batchSatelliteQuery($entities, $logbooks_locations_array) + { + // Create case-insensitive matching for DXCC entities + $whereConditions = array(); + foreach ($entities as $entity) { + $whereConditions[] = "UPPER(COL_COUNTRY) = UPPER('" . $this->db->escape_str($entity) . "')"; + } + + if (empty($whereConditions)) { + return array(); + } + + $whereClause = '(' . implode(' OR ', $whereConditions) . ')'; + + $this->db->select('COL_COUNTRY') + ->distinct() + ->from($this->config->item('table_name')) + ->where('COL_PROP_MODE', 'SAT') // Only satellite contacts + ->where_in('station_id', $logbooks_locations_array) + ->where($whereClause); + + $query = $this->db->get(); + + // Debug: Log the SQL query + log_message('debug', 'Workable DXCC satellite query: ' . $this->db->last_query()); + + $results = array(); + + foreach ($query->result() as $row) { + // Store with the original entity case for lookup + foreach ($entities as $entity) { + if (strtoupper($row->COL_COUNTRY) === strtoupper($entity)) { + $results[$entity] = true; + log_message('debug', 'Workable DXCC: Found satellite match: ' . $entity . ' matches ' . $row->COL_COUNTRY); + break; + } + } + } + + return $results; + } + /** * Build confirmation criteria SQL based on user preferences */ @@ -120,6 +181,10 @@ class Workabledxcc_model extends CI_Model ->where($whereClause); $query = $this->db->get(); + + // Debug: Log the SQL query + log_message('debug', 'Workable DXCC worked query: ' . $this->db->last_query()); + $results = array(); foreach ($query->result() as $row) { @@ -127,6 +192,7 @@ class Workabledxcc_model extends CI_Model foreach ($entities as $entity) { if (strtoupper($row->COL_COUNTRY) === strtoupper($entity)) { $results[$entity] = true; + log_message('debug', 'Workable DXCC: Found worked match: ' . $entity . ' matches ' . $row->COL_COUNTRY); break; } } @@ -243,10 +309,15 @@ class Workabledxcc_model extends CI_Model // Get DXCC status for this callsign $entity = $dxccEntities[$index] ?? null; - $worked = $entity && isset($dxccStatus[$entity]) ? $dxccStatus[$entity] : ['workedBefore' => false, 'confirmed' => false]; + $worked = $entity && isset($dxccStatus[$entity]) ? $dxccStatus[$entity] : [ + 'workedBefore' => false, + 'confirmed' => false, + 'workedViaSatellite' => false + ]; $record['workedBefore'] = $worked['workedBefore']; $record['confirmed'] = $worked['confirmed']; + $record['workedViaSatellite'] = $worked['workedViaSatellite']; $thisWeekRecords[] = $record; } @@ -260,6 +331,7 @@ class Workabledxcc_model extends CI_Model $return = [ "workedBefore" => false, "confirmed" => false, + "workedViaSatellite" => false, ]; $user_default_confirmation = $this->session->userdata('user_default_confirmation'); @@ -268,6 +340,7 @@ class Workabledxcc_model extends CI_Model $this->load->model('logbook_model'); if (!empty($logbooks_locations_array)) { + // Check for terrestrial contacts $this->db->where('COL_PROP_MODE !=', 'SAT'); $this->db->where_in('station_id', $logbooks_locations_array); @@ -279,6 +352,16 @@ class Workabledxcc_model extends CI_Model $return['workedBefore'] = true; } + // Check for satellite contacts + $this->db->where('COL_PROP_MODE', 'SAT'); + $this->db->where_in('station_id', $logbooks_locations_array); + $this->db->where('UPPER(COL_COUNTRY) = UPPER(?)', urldecode($country)); + + $query = $this->db->get($this->config->item('table_name'), 1, 0); + foreach ($query->result() as $satelliteRow) { + $return['workedViaSatellite'] = true; + } + $extrawhere = ''; if (isset($user_default_confirmation) && strpos($user_default_confirmation, 'Q') !== false) { $extrawhere = "COL_QSL_RCVD='Y'"; diff --git a/application/views/workabledxcc/components/dxcclist.php b/application/views/workabledxcc/components/dxcclist.php index ce891bac..83e0a4d1 100644 --- a/application/views/workabledxcc/components/dxcclist.php +++ b/application/views/workabledxcc/components/dxcclist.php @@ -49,6 +49,11 @@ foreach ($grouped as $month => $dxccs) { echo 'Confirmed'; } + // Add satellite badge if worked via satellite + if (isset($dxcc['workedViaSatellite']) && $dxcc['workedViaSatellite']) { + echo 'Worked via Satellite'; + } + echo ' ' . $dxcc['notes'] . ' ';