diff --git a/application/models/Vucc.php b/application/models/Vucc.php
index 4163de860..e31c3b532 100644
--- a/application/models/Vucc.php
+++ b/application/models/Vucc.php
@@ -27,69 +27,141 @@ class VUCC extends CI_Model
* Builds the array to display worked/confirmed vucc on award page
*/
function fetchVucc($data) {
- $totalGridConfirmed = array();
- $totalGridWorked = array();
+ // Use associative arrays for O(1) lookups instead of O(n) in_array()
+ $totalGridWorked = [];
+ $totalGridConfirmed = [];
+ $workedGrids = [];
+ $confirmedGrids = [];
- foreach($data['worked_bands'] as $band) {
+ // Create a lookup array for valid bands
+ $validBands = array_flip($data['worked_bands']);
- // Getting all the worked grids
- $col_gridsquare_worked = $this->get_vucc_summary($band, 'none');
+ // Get combined data (2 queries instead of 4 per band)
+ $combinedData = $this->get_vucc_combined_data_all_bands();
+ $combinedData2 = $this->get_vucc_combined_data_sat();
- $workedGridArray = array();
- foreach ($col_gridsquare_worked as $workedgrid) {
- array_push($workedGridArray, $workedgrid['gridsquare']);
- if(!in_array($workedgrid['gridsquare'], $totalGridWorked)){
- array_push($totalGridWorked, $workedgrid['gridsquare']);
+ // Process col_gridsquare data
+ if (!empty($combinedData['gridsquare'])) {
+ foreach ($combinedData['gridsquare'] as $row) {
+ $grid = $row['gridsquare'];
+ $band = $row['col_band'];
+
+ // Skip if this band is not in our requested bands list
+ if (!isset($validBands[$band])) {
+ continue;
}
- }
- $col_vucc_grids_worked = $this->get_vucc_summary_col_vucc($band, 'none');
+ // Always add to worked
+ $totalGridWorked[$grid] = true;
+ if (!isset($workedGrids[$band][$grid])) {
+ $workedGrids[$band][$grid] = true;
+ }
- foreach ($col_vucc_grids_worked as $gridSplit) {
- $grids = explode(",", $gridSplit['col_vucc_grids']);
- foreach($grids as $key) {
- $grid_four = strtoupper(substr(trim($key),0,4));
-
- if(!in_array($grid_four, $workedGridArray)){
- array_push($workedGridArray, $grid_four);
- }
-
- if(!in_array($grid_four, $totalGridWorked)){
- array_push($totalGridWorked, $grid_four);
+ // Add to confirmed if flagged
+ if ($row['confirmed']) {
+ $totalGridConfirmed[$grid] = true;
+ if (!isset($confirmedGrids[$band][$grid])) {
+ $confirmedGrids[$band][$grid] = true;
}
}
}
+ }
- // Getting all the confirmed grids
- $col_gridsquare_confirmed = $this->get_vucc_summary($band, 'both');
+ // Process col_vucc_grids data
+ if (!empty($combinedData['vucc_grids'])) {
+ foreach ($combinedData['vucc_grids'] as $row) {
+ $grids = explode(",", $row['col_vucc_grids']);
+ $band = $row['col_band'];
- $confirmedGridArray = array();
- foreach ($col_gridsquare_confirmed as $confirmedgrid) {
- array_push($confirmedGridArray, $confirmedgrid['gridsquare']);
- if(!in_array($confirmedgrid['gridsquare'], $totalGridConfirmed)){
- array_push($totalGridConfirmed, $confirmedgrid['gridsquare']);
+ // Skip if this band is not in our requested bands list
+ if (!isset($validBands[$band])) {
+ continue;
}
- }
- $col_vucc_grids_confirmed = $this->get_vucc_summary_col_vucc($band, 'both');
+ foreach ($grids as $key) {
+ $grid_four = strtoupper(substr(trim($key), 0, 4));
- foreach ($col_vucc_grids_confirmed as $gridSplit) {
- $grids = explode(",", $gridSplit['col_vucc_grids']);
- foreach($grids as $key) {
- $grid_four = strtoupper(substr(trim($key),0,4));
-
- if(!in_array($grid_four, $confirmedGridArray)){
- array_push($confirmedGridArray, $grid_four);
+ // Always add to worked
+ $totalGridWorked[$grid_four] = true;
+ if (!isset($workedGrids[$band][$grid_four])) {
+ $workedGrids[$band][$grid_four] = true;
}
- if(!in_array($grid_four, $totalGridConfirmed)){
- array_push($totalGridConfirmed, $grid_four);
+ // Add to confirmed if flagged
+ if ($row['confirmed']) {
+ $totalGridConfirmed[$grid_four] = true;
+ if (!isset($confirmedGrids[$band][$grid_four])) {
+ $confirmedGrids[$band][$grid_four] = true;
+ }
}
}
}
+ }
- $vuccArray[$band]['worked'] = count($workedGridArray);
- $vuccArray[$band]['confirmed'] = count($confirmedGridArray);
+ // Process col_gridsquare data
+ if (!empty($combinedData2['gridsquare'])) {
+ foreach ($combinedData2['gridsquare'] as $row) {
+ $grid = $row['gridsquare'];
+ $band = $row['col_band'];
+
+ // Skip if this band is not in our requested bands list
+ if (!isset($validBands[$band])) {
+ continue;
+ }
+
+ // Always add to worked
+ $totalGridWorked[$grid] = true;
+ if (!isset($workedGrids[$band][$grid])) {
+ $workedGrids[$band][$grid] = true;
+ }
+
+ // Add to confirmed if flagged
+ if ($row['confirmed']) {
+ $totalGridConfirmed[$grid] = true;
+ if (!isset($confirmedGrids[$band][$grid])) {
+ $confirmedGrids[$band][$grid] = true;
+ }
+ }
+ }
+ }
+
+ // Process col_vucc_grids data
+ if (!empty($combinedData2['vucc_grids'])) {
+ foreach ($combinedData2['vucc_grids'] as $row) {
+ $grids = explode(",", $row['col_vucc_grids']);
+ $band = $row['col_band'];
+
+ // Skip if this band is not in our requested bands list
+ if (!isset($validBands[$band])) {
+ continue;
+ }
+
+ foreach ($grids as $key) {
+ $grid_four = strtoupper(substr(trim($key), 0, 4));
+
+ // Always add to worked
+ $totalGridWorked[$grid_four] = true;
+ if (!isset($workedGrids[$band][$grid_four])) {
+ $workedGrids[$band][$grid_four] = true;
+ }
+
+ // Add to confirmed if flagged
+ if ($row['confirmed']) {
+ $totalGridConfirmed[$grid_four] = true;
+ if (!isset($confirmedGrids[$band][$grid_four])) {
+ $confirmedGrids[$band][$grid_four] = true;
+ }
+ }
+ }
+ }
+ }
+
+
+ // Build the result array with counts per band
+ $vuccArray = [];
+ foreach ($data['worked_bands'] as $band) {
+ $vuccArray[$band]['worked'] = isset($workedGrids[$band]) ? count($workedGrids[$band]) : 0;
+ $vuccArray[$band]['confirmed'] = isset($confirmedGrids[$band]) ? count($confirmedGrids[$band]) : 0;
}
$vuccArray['All']['worked'] = count($totalGridWorked);
@@ -102,106 +174,86 @@ class VUCC extends CI_Model
return $vuccArray;
}
- /*
- * Gets the grid from col_vucc_grids
- * $band = the band chosen
- * $confirmationMethod - qsl, lotw or both, use anything else to skip confirmed
+ /*
+ * Makes a list of all gridsquares on chosen band with info about lotw and qsl
+ * Optimized to fetch all callsigns in a single query instead of one per grid
*/
- function get_vucc_summary_col_vucc($band, $confirmationMethod) {
+ function vucc_details($band, $type) {
+ // Get combined data for the specific band
+ $bandData = $this->get_vucc_band_data($band);
- if (!$this->logbooks_locations_array) {
- return null;
+ if (empty($bandData['gridsquare']) && empty($bandData['vucc_grids'])) {
+ return 0;
}
- $location_list = "'".implode("','",$this->logbooks_locations_array)."'";
+ $vuccBand = [];
- $sql = "select distinct col_vucc_grids
- from " . $this->config->item('table_name') .
- " where station_id in (" . $location_list . ")" .
- " and col_vucc_grids <> '' ";
+ // Process col_gridsquare data
+ foreach ($bandData['gridsquare'] as $row) {
+ $grid = $row['gridsquare'];
+ $qsl = $row['qsl_confirmed'] ? 'Y' : '';
+ $lotw = $row['lotw_confirmed'] ? 'Y' : '';
+ $confirmed = $row['confirmed'];
- if ($confirmationMethod == 'both') {
- $sql .= " and (col_qsl_rcvd='Y' or col_lotw_qsl_rcvd='Y')";
- }
- else if ($confirmationMethod == 'qsl') {
- $sql .= " and col_qsl_rcvd='Y'";
- }
- else if ($confirmationMethod == 'lotw') {
- $sql .= " and col_lotw_qsl_rcvd='Y'";
- }
+ // Filter based on type
+ if ($type == 'worked' && $confirmed) {
+ continue; // Skip confirmed grids when showing only worked
+ }
+ if ($type == 'confirmed' && !$confirmed) {
+ continue; // Skip worked grids when showing only confirmed
+ }
- if ($band != 'All') {
- if ($band == 'SAT') {
- $sql .= " and col_prop_mode ='" . $band . "'";
+ if (!isset($vuccBand[$grid])) {
+ $vuccBand[$grid]['qsl'] = $qsl;
+ $vuccBand[$grid]['lotw'] = $lotw;
} else {
- $sql .= " and col_prop_mode !='SAT'";
- $sql .= " and col_band ='" . $band . "'";
+ // Update confirmation status if already exists
+ if ($qsl) $vuccBand[$grid]['qsl'] = $qsl;
+ if ($lotw) $vuccBand[$grid]['lotw'] = $lotw;
}
}
- $query = $this->db->query($sql);
- return $query->result_array();
- }
+ // Process col_vucc_grids data
+ foreach ($bandData['vucc_grids'] as $row) {
+ $grids = explode(",", $row['col_vucc_grids']);
+ $qsl = $row['qsl_confirmed'] ? 'Y' : '';
+ $lotw = $row['lotw_confirmed'] ? 'Y' : '';
+ $confirmed = $row['confirmed'];
- /*
- * Gets the grid from col_gridsquare
- * $band = the band chosen
- * $confirmationMethod - qsl, lotw or both, use anything else to skip confirmed
- */
- function get_vucc_summary($band, $confirmationMethod) {
- if (!$this->logbooks_locations_array) {
- return null;
- }
+ foreach ($grids as $key) {
+ $grid_four = strtoupper(substr(trim($key), 0, 4));
- $location_list = "'".implode("','",$this->logbooks_locations_array)."'";
+ // Filter based on type
+ if ($type == 'worked' && $confirmed) {
+ continue; // Skip confirmed grids when showing only worked
+ }
+ if ($type == 'confirmed' && !$confirmed) {
+ continue; // Skip worked grids when showing only confirmed
+ }
- $sql = "select distinct upper(substring(log.col_gridsquare, 1, 4)) gridsquare
- from " . $this->config->item('table_name') . " log".
- " inner join bands b on (b.band = log.col_band) ".
- " where log.station_id in (" . $location_list . ")" .
- " and log.col_gridsquare <> ''";
+ if (!isset($vuccBand[$grid_four])) {
+ $vuccBand[$grid_four]['qsl'] = $qsl;
+ $vuccBand[$grid_four]['lotw'] = $lotw;
+ } else {
+ // Update confirmation status if already exists
+ if ($qsl) $vuccBand[$grid_four]['qsl'] = $qsl;
+ if ($lotw) $vuccBand[$grid_four]['lotw'] = $lotw;
+ }
+ }
+ }
- if (($band == 'SAT') || ($band == 'All')) {
- $sql.=" and b.bandgroup in ('vhf','uhf','shf','sat')";
- }
+ // Get all callsigns for all grids in a SINGLE query
+ $gridCallsigns = $this->get_grid_callsigns_batch(array_keys($vuccBand), $band);
- if ($confirmationMethod == 'both') {
- $sql .= " and (log.col_qsl_rcvd='Y' or log.col_lotw_qsl_rcvd='Y')";
- } else if ($confirmationMethod == 'qsl') {
- $sql .= " and log.col_qsl_rcvd='Y'";
- } else if ($confirmationMethod == 'lotw') {
- $sql .= " and log.col_lotw_qsl_rcvd='Y'";
- }
-
- if ($band != 'All') {
- if ($band == 'SAT') {
- $sql .= " and log.col_prop_mode ='" . $band . "'";
- } else {
- $sql .= " and log.col_prop_mode !='SAT'";
- $sql .= " and log.col_band ='" . $band . "'";
- }
- } else {
- $sql .= " and log.col_prop_mode !='SAT'";
- }
- $query = $this->db->query($sql);
-
- return $query->result_array();
- }
-
- /*
- * Makes a list of all gridsquares on chosen band with info about lotw and qsl
- */
- function vucc_details($band, $type) {
-
- if ($type == 'worked') {
- $workedGridArray = $this->getWorkedGridsList($band, 'none');
- $vuccBand = $this->removeConfirmedGrids($band, $workedGridArray);
- } else if ($type == 'confirmed') {
- $workedGridArray = $this->getWorkedGridsList($band, 'both');
- $vuccBand = $this->markConfirmedGrids($band, $workedGridArray);
- } else {
- $workedGridArray = $this->getWorkedGridsList($band, 'none');
- $vuccBand = $this->markConfirmedGrids($band, $workedGridArray);
+ // Add callsign details for each grid from the batched result
+ foreach ($vuccBand as $grid => $data) {
+ $callsignlist = '';
+ if (isset($gridCallsigns[$grid])) {
+ foreach ($gridCallsigns[$grid] as $call) {
+ $callsignlist .= $call . '
';
+ }
+ }
+ $vuccBand[$grid]['call'] = $callsignlist;
}
if (!isset($vuccBand)) {
@@ -212,60 +264,141 @@ class VUCC extends CI_Model
}
}
- function removeConfirmedGrids($band, $workedGridArray) {
- $vuccDataQsl = $this->get_vucc_summary($band, 'qsl');
-
- foreach ($vuccDataQsl as $grid) {
- if (($key = array_search($grid['gridsquare'], $workedGridArray)) !== false) {
- unset($workedGridArray[$key]);
- }
+ /*
+ * Fetches callsigns for multiple grids in a single query
+ * Returns array indexed by 4-character grid with list of callsigns
+ */
+ private function get_grid_callsigns_batch($grids, $band) {
+ if (empty($grids) || !$this->logbooks_locations_array) {
+ return [];
}
- $vuccDataLotw = $this->get_vucc_summary($band, 'lotw');
+ $location_list = "'" . implode("','", $this->logbooks_locations_array) . "'";
+ $bindings = array();
- foreach ($vuccDataLotw as $grid) {
- if (($key = array_search($grid['gridsquare'], $workedGridArray)) !== false) {
- unset($workedGridArray[$key]);
- }
- }
-
- $col_vucc_grids_confirmed_qsl = $this->get_vucc_summary_col_vucc($band, 'lotw');
-
- foreach ($col_vucc_grids_confirmed_qsl as $gridSplit) {
- $grids = explode(",", $gridSplit['col_vucc_grids']);
- foreach($grids as $key) {
- $grid_four = strtoupper(substr(trim($key),0,4));
- if (($key = array_search($grid_four, $workedGridArray)) !== false) {
- unset($workedGridArray[$key]);
- }
- }
- }
-
- $col_vucc_grids_confirmed_lotw = $this->get_vucc_summary_col_vucc($band, 'qsl');
-
- foreach ($col_vucc_grids_confirmed_lotw as $gridSplit) {
- $grids = explode(",", $gridSplit['col_vucc_grids']);
- foreach($grids as $key) {
- $grid_four = strtoupper(substr(trim($key),0,4));
- if (($key = array_search($grid_four, $workedGridArray)) !== false) {
- unset($workedGridArray[$key]);
- }
- }
- }
- foreach ($workedGridArray as $grid) {
- $result = $this->grid_detail($grid, $band);
- $callsignlist = '';
- foreach($result->result() as $call) {
- $callsignlist .= $call->COL_CALL . '
';
- }
- $vuccBand[$grid]['call'] = $callsignlist;
- }
-
- if (isset($vuccBand)) {
- return $vuccBand;
+ // Build band condition
+ if ($band == 'SAT') {
+ $bandCondition = " and col_prop_mode = 'SAT'";
} else {
- return null;
+ $bandCondition = " and col_prop_mode != 'SAT' and col_band = ?";
+ $bindings[] = $band;
}
+
+ // Fetch all QSOs for this band - we'll filter by grids in PHP
+ // This is much more efficient than one query per grid
+ $sql = "SELECT COL_CALL, col_gridsquare, col_vucc_grids
+ FROM " . $this->config->item('table_name') . "
+ WHERE station_id IN (" . $location_list . ")
+ AND (col_gridsquare <> '' OR col_vucc_grids <> '')"
+ . $bandCondition;
+
+ $query = $this->db->query($sql, $bindings);
+ $result = $query->result_array();
+
+ // Group callsigns by grid in PHP
+ $gridCallsigns = [];
+ $gridsLookup = array_flip($grids); // For O(1) lookups
+
+ foreach ($result as $row) {
+ // Process col_gridsquare
+ if (!empty($row['col_gridsquare'])) {
+ $grid_four = strtoupper(substr($row['col_gridsquare'], 0, 4));
+ if (isset($gridsLookup[$grid_four])) {
+ if (!isset($gridCallsigns[$grid_four])) {
+ $gridCallsigns[$grid_four] = [];
+ }
+ // Avoid duplicate callsigns for the same grid
+ if (!in_array($row['COL_CALL'], $gridCallsigns[$grid_four])) {
+ $gridCallsigns[$grid_four][] = $row['COL_CALL'];
+ }
+ }
+ }
+
+ // Process col_vucc_grids (comma-separated list)
+ if (!empty($row['col_vucc_grids'])) {
+ $vuccGrids = explode(",", $row['col_vucc_grids']);
+ foreach ($vuccGrids as $vuccGrid) {
+ $grid_four = strtoupper(substr(trim($vuccGrid), 0, 4));
+ if (isset($gridsLookup[$grid_four])) {
+ if (!isset($gridCallsigns[$grid_four])) {
+ $gridCallsigns[$grid_four] = [];
+ }
+ // Avoid duplicate callsigns for the same grid
+ if (!in_array($row['COL_CALL'], $gridCallsigns[$grid_four])) {
+ $gridCallsigns[$grid_four][] = $row['COL_CALL'];
+ }
+ }
+ }
+ }
+ }
+
+ return $gridCallsigns;
+ }
+
+ /*
+ * Fetches VUCC data for a specific band with QSL/LoTW confirmation details
+ * Returns data in a single query per band
+ */
+ private function get_vucc_band_data($band) {
+ if (!$this->logbooks_locations_array) {
+ return ['gridsquare' => [], 'vucc_grids' => []];
+ }
+
+ $results = ['gridsquare' => [], 'vucc_grids' => []];
+
+ $location_list = "'" . implode("','", $this->logbooks_locations_array) . "'";
+
+ $bindings1 = array();
+
+ if ($band == 'SAT') {
+ $bandCondition1 = " and log.col_prop_mode = 'SAT'";
+ } else {
+ $bandCondition1 = " and log.col_prop_mode != 'SAT' and log.col_band = ?";
+ $bindings1[] = $band;
+ }
+
+ $sql1 = "SELECT
+ DISTINCT UPPER(SUBSTRING(col_gridsquare, 1, 4)) as gridsquare,
+ MAX(CASE WHEN col_qsl_rcvd='Y' THEN 1 ELSE 0 END) as qsl_confirmed,
+ MAX(CASE WHEN col_lotw_qsl_rcvd='Y' THEN 1 ELSE 0 END) as lotw_confirmed,
+ MAX(CASE WHEN (col_qsl_rcvd='Y' OR col_lotw_qsl_rcvd='Y') THEN 1 ELSE 0 END) as confirmed
+ FROM " . $this->config->item('table_name') . " log
+ WHERE log.station_id IN (" . $location_list . ")
+ AND log.col_gridsquare <> ''"
+ . $bandCondition1 . "
+ GROUP BY UPPER(SUBSTRING(col_gridsquare, 1, 4))";
+
+ $query1 = $this->db->query($sql1, $bindings1);
+ if ($query1->num_rows() > 0) {
+ $results['gridsquare'] = $query1->result_array();
+ }
+
+ if ($band == 'SAT') {
+ $bandCondition2 = " and col_prop_mode = ?";
+ $bindings2[] = $band;
+ } else {
+ $bandCondition2 = " and col_prop_mode != ? and col_band = ?";
+ $bindings2[] = 'SAT';
+ $bindings2[] = $band;
+ }
+
+ $sql2 = "SELECT
+ DISTINCT col_vucc_grids,
+ MAX(CASE WHEN col_qsl_rcvd='Y' THEN 1 ELSE 0 END) as qsl_confirmed,
+ MAX(CASE WHEN col_lotw_qsl_rcvd='Y' THEN 1 ELSE 0 END) as lotw_confirmed,
+ MAX(CASE WHEN (col_qsl_rcvd='Y' OR col_lotw_qsl_rcvd='Y') THEN 1 ELSE 0 END) as confirmed
+ FROM " . $this->config->item('table_name') . "
+ WHERE station_id IN (" . $location_list . ")
+ AND col_vucc_grids <> ''"
+ . $bandCondition2 . "
+ GROUP BY col_vucc_grids";
+
+ $query2 = $this->db->query($sql2, $bindings2);
+ if ($query2->num_rows() > 0) {
+ $results['vucc_grids'] = $query2->result_array();
+ }
+
+ return $results;
}
function grid_detail($gridsquare, $band) {
@@ -287,142 +420,50 @@ class VUCC extends CI_Model
return $this->db->query($sql);
}
- function markConfirmedGrids($band, $workedGridArray) {
- foreach ($workedGridArray as $grid) {
- $vuccBand[$grid]['qsl'] = '';
- $vuccBand[$grid]['lotw'] = '';
- }
-
- $vuccDataQsl = $this->get_vucc_summary($band, 'qsl');
-
- foreach ($vuccDataQsl as $grid) {
- $vuccBand[$grid['gridsquare']]['qsl'] = 'Y';
- }
-
- $vuccDataLotw = $this->get_vucc_summary($band, 'lotw');
-
- foreach ($vuccDataLotw as $grid) {
- $vuccBand[$grid['gridsquare']]['lotw'] = 'Y';
- }
-
- $col_vucc_grids_confirmed_qsl = $this->get_vucc_summary_col_vucc($band, 'lotw');
-
- foreach ($col_vucc_grids_confirmed_qsl as $gridSplit) {
- $grids = explode(",", $gridSplit['col_vucc_grids']);
- foreach($grids as $key) {
- $grid_four = strtoupper(substr(trim($key),0,4));
- $vuccBand[$grid_four]['lotw'] = 'Y';
- }
- }
-
- $col_vucc_grids_confirmed_lotw = $this->get_vucc_summary_col_vucc($band, 'qsl');
-
- foreach ($col_vucc_grids_confirmed_lotw as $gridSplit) {
- $grids = explode(",", $gridSplit['col_vucc_grids']);
- foreach($grids as $key) {
- $grid_four = strtoupper(substr(trim($key),0,4));
- $vuccBand[$grid_four]['qsl'] = 'Y';
- }
- }
-
- return $vuccBand;
- }
-
- function getWorkedGridsList($band, $confirmationMethod) {
-
- $col_gridsquare_worked = $this->get_vucc_summary($band, $confirmationMethod);
-
- $workedGridArray = array();
- foreach ($col_gridsquare_worked as $workedgrid) {
- array_push($workedGridArray, $workedgrid['gridsquare']);
- }
-
- $col_vucc_grids_worked = $this->get_vucc_summary_col_vucc($band, $confirmationMethod);
-
- foreach ($col_vucc_grids_worked as $gridSplit) {
- $grids = explode(",", $gridSplit['col_vucc_grids']);
- foreach($grids as $key) {
- $grid_four = strtoupper(substr(trim($key),0,4));
-
- if(!in_array($grid_four, $workedGridArray)){
- array_push($workedGridArray, $grid_four);
- }
- }
- }
-
- return $workedGridArray;
- }
-
- private function get_vucc_combined_data($band = 'All') {
+ /*
+ * Fetches VUCC data for ALL bands in 2 queries (optimized)
+ * Similar approach to CQ model's getCqZoneData()
+ * Returns data with band information included for processing
+ */
+ private function get_vucc_combined_data_all_bands() {
if (!$this->logbooks_locations_array) {
return ['gridsquare' => [], 'vucc_grids' => []];
}
$results = ['gridsquare' => [], 'vucc_grids' => []];
- $inPlaceholders = str_repeat('?,', count($this->logbooks_locations_array) - 1) . '?';
-
- // Query 1: Get col_gridsquare data with worked/confirmed status
- $bindings1 = array_merge($this->logbooks_locations_array);
- $bandCondition1 = '';
-
- if ($band != 'All') {
- if ($band == 'SAT') {
- $bandCondition1 = " and log.col_prop_mode = ?";
- $bindings1[] = $band;
- } else {
- $bandCondition1 = " and log.col_prop_mode != ? and log.col_band = ?";
- $bindings1[] = 'SAT';
- $bindings1[] = $band;
- }
- } else {
- $bandCondition1 = " and log.col_prop_mode != ?";
- $bindings1[] = 'SAT';
- }
+ // Query 1: Get col_gridsquare data for ALL bands with worked/confirmed status
+ // GROUP BY both gridsquare and band to get per-band statistics
+ $location_list = "'" . implode("','", $this->logbooks_locations_array) . "'";
$sql1 = "SELECT
DISTINCT UPPER(SUBSTRING(col_gridsquare, 1, 4)) as gridsquare,
+ col_band,
MAX(CASE WHEN (col_qsl_rcvd='Y' OR col_lotw_qsl_rcvd='Y') THEN 1 ELSE 0 END) as confirmed
FROM " . $this->config->item('table_name') . " log
- INNER JOIN bands b ON (b.band = log.col_band)
- WHERE log.station_id IN (" . $inPlaceholders . ")
+ WHERE log.station_id IN (" . $location_list . ")
AND log.col_gridsquare <> ''
- AND b.bandgroup IN ('vhf','uhf','shf','sat')"
- . $bandCondition1 . "
- GROUP BY UPPER(SUBSTRING(col_gridsquare, 1, 4))";
+ AND log.col_prop_mode != 'SAT'
+ GROUP BY UPPER(SUBSTRING(col_gridsquare, 1, 4)), col_band";
- $query1 = $this->db->query($sql1, $bindings1);
+ $query1 = $this->db->query($sql1);
if ($query1->num_rows() > 0) {
$results['gridsquare'] = $query1->result_array();
}
- // Query 2: Get col_vucc_grids data with worked/confirmed status
- // Note: col_vucc_grids has NO band filter when band='All' (includes SAT)
- $bindings2 = array_merge($this->logbooks_locations_array);
- $bandCondition2 = '';
-
- if ($band != 'All') {
- if ($band == 'SAT') {
- $bandCondition2 = " and col_prop_mode = ?";
- $bindings2[] = $band;
- } else {
- $bandCondition2 = " and col_prop_mode != ? and col_band = ?";
- $bindings2[] = 'SAT';
- $bindings2[] = $band;
- }
- }
- // When band='All', NO band filter is added (includes all prop_mode including SAT)
+ // Query 2: Get col_vucc_grids data for ALL bands with worked/confirmed status
$sql2 = "SELECT
DISTINCT col_vucc_grids,
+ col_band,
MAX(CASE WHEN (col_qsl_rcvd='Y' OR col_lotw_qsl_rcvd='Y') THEN 1 ELSE 0 END) as confirmed
FROM " . $this->config->item('table_name') . "
- WHERE station_id IN (" . $inPlaceholders . ")
- AND col_vucc_grids <> ''"
- . $bandCondition2 . "
- GROUP BY col_vucc_grids";
+ WHERE station_id IN (" . $location_list . ")
+ AND col_vucc_grids <> ''
+ AND col_prop_mode != 'SAT'
+ GROUP BY col_vucc_grids, col_band";
- $query2 = $this->db->query($sql2, $bindings2);
+ $query2 = $this->db->query($sql2);
if ($query2->num_rows() > 0) {
$results['vucc_grids'] = $query2->result_array();
}
@@ -430,7 +471,58 @@ class VUCC extends CI_Model
return $results;
}
- /*
+ /*
+ * Fetches VUCC data for ALL bands in 2 queries (optimized)
+ * Similar approach to CQ model's getCqZoneData()
+ * Returns data with band information included for processing
+ */
+ private function get_vucc_combined_data_sat() {
+ if (!$this->logbooks_locations_array) {
+ return ['gridsquare' => [], 'vucc_grids' => []];
+ }
+
+ $results = ['gridsquare' => [], 'vucc_grids' => []];
+
+ // Query 1: Get col_gridsquare data for ALL bands with worked/confirmed status
+ // GROUP BY both gridsquare and band to get per-band statistics
+ $location_list = "'" . implode("','", $this->logbooks_locations_array) . "'";
+
+ $sql1 = "SELECT
+ DISTINCT UPPER(SUBSTRING(col_gridsquare, 1, 4)) as gridsquare,
+ col_prop_mode as col_band,
+ MAX(CASE WHEN (col_qsl_rcvd='Y' OR col_lotw_qsl_rcvd='Y') THEN 1 ELSE 0 END) as confirmed
+ FROM " . $this->config->item('table_name') . " log
+ WHERE log.station_id IN (" . $location_list . ")
+ AND log.col_gridsquare <> ''
+ AND log.col_prop_mode = 'SAT'
+ GROUP BY UPPER(SUBSTRING(col_gridsquare, 1, 4)), col_prop_mode";
+
+ $query1 = $this->db->query($sql1);
+ if ($query1->num_rows() > 0) {
+ $results['gridsquare'] = $query1->result_array();
+ }
+
+ // Query 2: Get col_vucc_grids data for ALL bands with worked/confirmed status
+
+ $sql2 = "SELECT
+ DISTINCT col_vucc_grids,
+ col_prop_mode as col_band,
+ MAX(CASE WHEN (col_qsl_rcvd='Y' OR col_lotw_qsl_rcvd='Y') THEN 1 ELSE 0 END) as confirmed
+ FROM " . $this->config->item('table_name') . "
+ WHERE station_id IN (" . $location_list . ")
+ AND col_vucc_grids <> ''
+ AND col_prop_mode = 'SAT'
+ GROUP BY col_vucc_grids, col_prop_mode";
+
+ $query2 = $this->db->query($sql2);
+ if ($query2->num_rows() > 0) {
+ $results['vucc_grids'] = $query2->result_array();
+ }
+
+ return $results;
+ }
+
+ /*
* Builds the array to display worked/confirmed vucc on dashboard page
*/
function fetchVuccSummary($band = 'All') {
@@ -475,5 +567,79 @@ class VUCC extends CI_Model
return $vuccArray;
}
+
+ private function get_vucc_combined_data($band = 'All') {
+ if (!$this->logbooks_locations_array) {
+ return ['gridsquare' => [], 'vucc_grids' => []];
+ }
+
+ $results = ['gridsquare' => [], 'vucc_grids' => []];
+
+ $location_list = "'" . implode("','", $this->logbooks_locations_array) . "'";
+
+ // Query 1: Get col_gridsquare data with worked/confirmed status
+ $bandCondition1 = '';
+ $bindings1 = array();
+
+ if ($band != 'All') {
+ if ($band == 'SAT') {
+ $bandCondition1 = " and log.col_prop_mode = 'SAT'";
+ } else {
+ $bandCondition1 = " and log.col_prop_mode != 'SAT' and log.col_band = ?";
+ $bindings1[] = $band;
+ }
+ } else {
+ $bandCondition1 = " and log.col_prop_mode != 'SAT'";
+ }
+
+ $sql1 = "SELECT
+ DISTINCT UPPER(SUBSTRING(col_gridsquare, 1, 4)) as gridsquare,
+ MAX(CASE WHEN (col_qsl_rcvd='Y' OR col_lotw_qsl_rcvd='Y') THEN 1 ELSE 0 END) as confirmed
+ FROM " . $this->config->item('table_name') . " log
+ INNER JOIN bands b ON (b.band = log.col_band)
+ WHERE log.station_id IN (" . $location_list . ")
+ AND log.col_gridsquare <> ''
+ AND b.bandgroup IN ('vhf','uhf','shf','sat')"
+ . $bandCondition1 . "
+ GROUP BY UPPER(SUBSTRING(col_gridsquare, 1, 4))";
+
+ $query1 = $this->db->query($sql1, $bindings1);
+ if ($query1->num_rows() > 0) {
+ $results['gridsquare'] = $query1->result_array();
+ }
+
+ // Query 2: Get col_vucc_grids data with worked/confirmed status
+ // Note: col_vucc_grids has NO band filter when band='All' (includes SAT)
+ $bandCondition2 = '';
+
+ $bindings2 = array();
+
+ if ($band != 'All') {
+ if ($band == 'SAT') {
+ $bandCondition2 = " and col_prop_mode = 'SAT'";
+ } else {
+ $bandCondition2 = " and col_prop_mode != 'SAT' and col_band = ?";
+ $bindings2[] = $band;
+ }
+ }
+ // When band='All', NO band filter is added (includes all prop_mode including SAT)
+
+ $sql2 = "SELECT
+ DISTINCT col_vucc_grids,
+ MAX(CASE WHEN (col_qsl_rcvd='Y' OR col_lotw_qsl_rcvd='Y') THEN 1 ELSE 0 END) as confirmed
+ FROM " . $this->config->item('table_name') . "
+ WHERE station_id IN (" . $location_list . ")
+ AND col_vucc_grids <> ''"
+ . $bandCondition2 . "
+ GROUP BY col_vucc_grids";
+
+ $query2 = $this->db->query($sql2, $bindings2);
+ if ($query2->num_rows() > 0) {
+ $results['vucc_grids'] = $query2->result_array();
+ }
+
+ return $results;
+ }
+
}
?>