From ffe381f42946574401de4999cf834449e362be17 Mon Sep 17 00:00:00 2001 From: HB9HIL Date: Fri, 16 Feb 2024 23:25:07 +0100 Subject: [PATCH] [AWARDS] Added swiss H26 --- application/controllers/Awards.php | 117 +++++++ application/models/H26.php | 315 ++++++++++++++++++ application/models/Logbook_model.php | 4 + application/models/User_model.php | 2 +- application/views/awards/h26/index.php | 245 ++++++++++++++ application/views/interface_assets/footer.php | 45 ++- application/views/interface_assets/header.php | 2 + assets/js/sections/h26map.js | 230 +++++++++++++ assets/js/sections/h26map_geojson.js | 15 + 9 files changed, 973 insertions(+), 2 deletions(-) create mode 100644 application/models/H26.php create mode 100644 application/views/awards/h26/index.php create mode 100644 assets/js/sections/h26map.js create mode 100644 assets/js/sections/h26map_geojson.js diff --git a/application/controllers/Awards.php b/application/controllers/Awards.php index 904a9e671..31580016b 100644 --- a/application/controllers/Awards.php +++ b/application/controllers/Awards.php @@ -581,6 +581,68 @@ class Awards extends CI_Controller { $this->load->view('interface_assets/footer', $footerData); } + public function h26() { + $footerData = []; + $footerData['scripts'] = [ + 'assets/js/sections/h26map_geojson.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/h26map_geojson.js")), + 'assets/js/sections/h26map.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/h26map.js")), + 'assets/js/leaflet/L.Maidenhead.js', + ]; + + $this->load->model('h26'); + $this->load->model('modes'); + $this->load->model('bands'); + + $data['worked_bands'] = $this->bands->get_worked_bands('h26'); + $data['modes'] = $this->modes->active(); // Used in the view for mode select + + if ($this->input->post('band') != NULL) { // Band is not set when page first loads. + if ($this->input->post('band') == 'All') { // Did the user specify a band? If not, use all bands + $bands = $data['worked_bands']; + } + else { + $bands[] = $this->security->xss_clean($this->input->post('band')); + } + } + else { + $bands = $data['worked_bands']; + } + + $data['bands'] = $bands; // Used for displaying selected band(s) in the table in the view + + if($this->input->method() === 'post') { + $postdata['qsl'] = $this->security->xss_clean($this->input->post('qsl')); + $postdata['lotw'] = $this->security->xss_clean($this->input->post('lotw')); + $postdata['eqsl'] = $this->security->xss_clean($this->input->post('eqsl')); + $postdata['qrz'] = $this->security->xss_clean($this->input->post('qrz')); + $postdata['worked'] = $this->security->xss_clean($this->input->post('worked')); + $postdata['confirmed'] = $this->security->xss_clean($this->input->post('confirmed')); + $postdata['notworked'] = $this->security->xss_clean($this->input->post('notworked')); + $postdata['band'] = $this->security->xss_clean($this->input->post('band')); + $postdata['mode'] = $this->security->xss_clean($this->input->post('mode')); + } + else { // Setting default values at first load of page + $postdata['qsl'] = 1; + $postdata['lotw'] = 1; + $postdata['eqsl'] = 0; + $postdata['qrz'] = 0; + $postdata['worked'] = 1; + $postdata['confirmed'] = 1; + $postdata['notworked'] = 1; + $postdata['band'] = 'All'; + $postdata['mode'] = 'All'; + } + + $data['h26_array'] = $this->h26->get_h26_array($bands, $postdata); + $data['h26_summary'] = $this->h26->get_h26_summary($bands, $postdata); + + // Render Page + $data['page_title'] = "Awards - H26"; + $this->load->view('interface_assets/header', $data); + $this->load->view('awards/h26/index'); + $this->load->view('interface_assets/footer', $footerData); + } + public function iota () { $this->load->model('iota'); $this->load->model('modes'); @@ -1066,6 +1128,61 @@ class Awards extends CI_Controller { echo json_encode($states); } + /* + function H26_map + + This displays the H26 map and requires the $band_type and $mode_type + */ + public function h26_map() { + $stateString = 'AB,BC,MB,NB,NL,NT,NS,NU,ON,PE,QC,SK,YT'; + $h26Array = explode(',', $stateString); + + $this->load->model('h26'); + + $bands[] = $this->security->xss_clean($this->input->post('band')); + + $postdata['qsl'] = $this->input->post('qsl') == 0 ? NULL: 1; + $postdata['lotw'] = $this->input->post('lotw') == 0 ? NULL: 1; + $postdata['eqsl'] = $this->input->post('eqsl') == 0 ? NULL: 1; + $postdata['qrz'] = $this->input->post('qrz') == 0 ? NULL: 1; + $postdata['worked'] = $this->input->post('worked') == 0 ? NULL: 1; + $postdata['confirmed'] = $this->input->post('confirmed') == 0 ? NULL: 1; + $postdata['notworked'] = $this->input->post('notworked') == 0 ? NULL: 1; + $postdata['band'] = $this->security->xss_clean($this->input->post('band')); + $postdata['mode'] = $this->security->xss_clean($this->input->post('mode')); + + $h26_array = $this->h26->get_h26_array($bands, $postdata); + + $states = array(); + + foreach ($h26Array as $state) { // Generating array for use in the table + $states[$state] = '-'; // Inits each state's count + } + + + foreach ($h26_array as $was => $value) { + foreach ($value as $key) { + if($key != "") { + if (strpos($key, '>W<') !== false) { + $states[$was] = 'W'; + break; + } + if (strpos($key, '>C<') !== false) { + $states[$was] = 'C'; + break; + } + if (strpos($key, '-') !== false) { + $states[$was] = '-'; + break; + } + } + } + } + + header('Content-Type: application/json'); + echo json_encode($states); + } + /* function cq_map This displays the CQ Zone map and requires the $band_type and $mode_type diff --git a/application/models/H26.php b/application/models/H26.php new file mode 100644 index 000000000..ebc950dfb --- /dev/null +++ b/application/models/H26.php @@ -0,0 +1,315 @@ +load->model('logbooks_model'); + $logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook')); + + if (!$logbooks_locations_array) { + return null; + } + + $location_list = "'".implode("','",$logbooks_locations_array)."'"; + + $stateArray = explode(',', $this->stateString); + + $states = array(); // Used for keeping th26k of which states that are not worked + + $qsl = ""; + if ($postdata['confirmed'] != NULL) { + if ($postdata['qsl'] != NULL ) { + $qsl .= "Q"; + } + if ($postdata['lotw'] != NULL ) { + $qsl .= "L"; + } + if ($postdata['eqsl'] != NULL ) { + $qsl .= "E"; + } + if ($postdata['qrz'] != NULL ) { + $qsl .= "Z"; + } + } + + foreach ($stateArray as $state) { // Generating array for use in the table + $states[$state]['count'] = 0; // Inits each state's count + } + + + foreach ($bands as $band) { + foreach ($stateArray as $state) { // Generating array for use in the table + $bandh26[$state][$band] = '-'; // Sets all to dash to indicate no result + } + + if ($postdata['worked'] != NULL) { + $h26Band = $this->geth26Worked($location_list, $band, $postdata); + foreach ($h26Band as $line) { + $bandh26[$line->col_state][$band] = '
col_state . '","' . $band . '","'. $postdata['mode'] . '","h26", "")\'>W
'; + $states[$line->col_state]['count']++; + } + } + if ($postdata['confirmed'] != NULL) { + $h26Band = $this->geth26Confirmed($location_list, $band, $postdata); + foreach ($h26Band as $line) { + $bandh26[$line->col_state][$band] = '
col_state . '","' . $band . '","'. $postdata['mode'] . '","h26", "'.$qsl.'")\'>C
'; + $states[$line->col_state]['count']++; + } + } + } + + // We want to remove the worked states in the list, since we do not want to display them + if ($postdata['worked'] == NULL) { + $h26Band = $this->geth26Worked($location_list, $postdata['band'], $postdata); + foreach ($h26Band as $line) { + unset($bandh26[$line->col_state]); + } + } + + // We want to remove the confirmed states in the list, since we do not want to display them + if ($postdata['confirmed'] == NULL) { + $h26Band = $this->geth26Confirmed($location_list, $postdata['band'], $postdata); + foreach ($h26Band as $line) { + unset($bandh26[$line->col_state]); + } + } + + if ($postdata['notworked'] == NULL) { + foreach ($stateArray as $state) { + if ($states[$state]['count'] == 0) { + unset($bandh26[$state]); + }; + } + } + + if (isset($bandh26)) { + return $bandh26; + } + else { + return 0; + } + } + + /* + * Function gets worked and confirmed summary on each band on the active stationprofile + */ + function get_h26_summary($bands, $postdata) + { + $CI =& get_instance(); + $CI->load->model('logbooks_model'); + $logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook')); + + if (!$logbooks_locations_array) { + return null; + } + + $location_list = "'".implode("','",$logbooks_locations_array)."'"; + + foreach ($bands as $band) { + $worked = $this->getSummaryByBand($band, $postdata, $location_list); + $confirmed = $this->getSummaryByBandConfirmed($band, $postdata, $location_list); + $h26Summary['worked'][$band] = $worked[0]->count; + $h26Summary['confirmed'][$band] = $confirmed[0]->count; + } + + $workedTotal = $this->getSummaryByBand($postdata['band'], $postdata, $location_list); + $confirmedTotal = $this->getSummaryByBandConfirmed($postdata['band'], $postdata, $location_list); + + $h26Summary['worked']['Total'] = $workedTotal[0]->count; + $h26Summary['confirmed']['Total'] = $confirmedTotal[0]->count; + + return $h26Summary; + } + + function getSummaryByBand($band, $postdata, $location_list) + { + $sql = "SELECT count(distinct thcv.col_state) as count FROM " . $this->config->item('table_name') . " thcv"; + + $sql .= " where station_id in (" . $location_list . ")"; + + if ($band == 'SAT') { + $sql .= " and thcv.col_prop_mode ='" . $band . "'"; + } else if ($band == 'All') { + $this->load->model('bands'); + + $bandslots = $this->bands->get_worked_bands('h26'); + + $bandslots_list = "'".implode("','",$bandslots)."'"; + + $sql .= " and thcv.col_band in (" . $bandslots_list . ")" . + " and thcv.col_prop_mode !='SAT'"; + } else { + $sql .= " and thcv.col_prop_mode !='SAT'"; + $sql .= " and thcv.col_band ='" . $band . "'"; + } + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = '" . $postdata['mode'] . "' or col_submode = '" . $postdata['mode'] . "')"; + } + + $sql .= $this->addStateToQuery(); + + $query = $this->db->query($sql); + + return $query->result(); + } + + function getSummaryByBandConfirmed($band, $postdata, $location_list) + { + $sql = "SELECT count(distinct thcv.col_state) as count FROM " . $this->config->item('table_name') . " thcv"; + + $sql .= " where station_id in (" . $location_list . ")"; + + if ($band == 'SAT') { + $sql .= " and thcv.col_prop_mode ='" . $band . "'"; + } else if ($band == 'All') { + $this->load->model('bands'); + + $bandslots = $this->bands->get_worked_bands('h26'); + + $bandslots_list = "'".implode("','",$bandslots)."'"; + + $sql .= " and thcv.col_band in (" . $bandslots_list . ")" . + " and thcv.col_prop_mode !='SAT'"; + } else { + $sql .= " and thcv.col_prop_mode !='SAT'"; + $sql .= " and thcv.col_band ='" . $band . "'"; + } + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = '" . $postdata['mode'] . "' or col_submode = '" . $postdata['mode'] . "')"; + } + + $sql .= $this->addQslToQuery($postdata); + + $sql .= $this->addStateToQuery(); + + $query = $this->db->query($sql); + + return $query->result(); + } + + /* + * Function returns all worked, but not confirmed states + * $postdata contains data from the form, in this case Lotw or QSL are used + */ + function geth26Worked($location_list, $band, $postdata) { + $sql = "SELECT distinct col_state FROM " . $this->config->item('table_name') . " thcv + where station_id in (" . $location_list . ")"; + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = '" . $postdata['mode'] . "' or col_submode = '" . $postdata['mode'] . "')"; + } + + $sql .= $this->addStateToQuery(); + + $sql .= $this->addBandToQuery($band); + + $sql .= " and not exists (select 1 from ". $this->config->item('table_name') . + " where station_id in (". $location_list . ")" . + " and col_state = thcv.col_state"; + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = '" . $postdata['mode'] . "' or col_submode = '" . $postdata['mode'] . "')"; + } + + $sql .= $this->addBandToQuery($band); + + $sql .= $this->addQslToQuery($postdata); + + $sql .= $this->addStateToQuery(); + + $sql .= ")"; + + $query = $this->db->query($sql); + + return $query->result(); + } + + /* + * Function returns all confirmed states on given band and on LoTW or QSL + * $postdata contains data from the form, in this case Lotw or QSL are used + */ + function geth26Confirmed($location_list, $band, $postdata) { + $sql = "SELECT distinct col_state FROM " . $this->config->item('table_name') . " thcv + where station_id in (" . $location_list . ")"; + + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = '" . $postdata['mode'] . "' or col_submode = '" . $postdata['mode'] . "')"; + } + + $sql .= $this->addStateToQuery(); + + $sql .= $this->addBandToQuery($band); + + $sql .= $this->addQslToQuery($postdata); + + $query = $this->db->query($sql); + + return $query->result(); + } + + function addQslToQuery($postdata) { + $sql = ''; + $qsl = array(); + if ($postdata['qrz'] != NULL || $postdata['lotw'] != NULL || $postdata['qsl'] != NULL || $postdata['eqsl'] != NULL) { + $sql .= ' and ('; + if ($postdata['qsl'] != NULL) { + array_push($qsl, "col_qsl_rcvd = 'Y'"); + } + if ($postdata['lotw'] != NULL) { + array_push($qsl, "col_lotw_qsl_rcvd = 'Y'"); + } + if ($postdata['eqsl'] != NULL) { + array_push($qsl, "col_eqsl_qsl_rcvd = 'Y'"); + } + if ($postdata['qrz'] != NULL) { + array_push($qsl, "COL_QRZCOM_QSO_DOWNLOAD_STATUS = 'Y'"); + } + if (count($qsl) > 0) { + $sql .= implode(' or ', $qsl); + } else { + $sql .= '1=0'; + } + $sql .= ')'; + } else { + $sql.=' and 1=0'; + } + return $sql; + } + + + + function addBandToQuery($band) { + $sql = ''; + if ($band != 'All') { + if ($band == 'SAT') { + $sql .= " and col_prop_mode ='" . $band . "'"; + } else { + $sql .= " and col_prop_mode !='SAT'"; + $sql .= " and col_band ='" . $band . "'"; + } + } else { + $this->load->model('bands'); + + $bandslots = $this->bands->get_worked_bands('h26'); + + $bandslots_list = "'".implode("','",$bandslots)."'"; + + $sql .= " and col_band in (" . $bandslots_list . ")" . + " and col_prop_mode !='SAT'"; + } + return $sql; + } + + function addStateToQuery() { + $sql = ''; + $sql .= " and COL_DXCC = 287"; + $sql .= " and COL_STATE in ('AG','AI','AR','BE','BL','BS','FR','GE','GL','GR','JU','LU','NE','NW','OW','SG','SH','SO','SZ','TG','TI','UR','VD','VS','ZG','ZH')"; + return $sql; + } +} +?> diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index 2ca067999..a8da7ba92 100755 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -380,6 +380,10 @@ class Logbook_model extends CI_Model { $this->db->where('COL_STATE', $searchphrase); $this->db->where_in('COL_DXCC', ['1']); break; + case 'h26': + $this->db->where('COL_STATE', $searchphrase); + $this->db->where_in('COL_DXCC', ['287']); + break; case 'SOTA': $this->db->where('COL_SOTA_REF', $searchphrase); break; diff --git a/application/models/User_model.php b/application/models/User_model.php index b26681cba..836d39b5a 100644 --- a/application/models/User_model.php +++ b/application/models/User_model.php @@ -200,7 +200,7 @@ class User_Model extends CI_Model { // Add user and insert bandsettings for user $this->db->insert($this->config->item('auth_table'), $data); $insert_id = $this->db->insert_id(); - $this->db->query("insert into bandxuser (bandid, userid, active, cq, dok, dxcc, iota, pota, sig, sota, uscounties, was, wwff, vucc, waja, rac) select bands.id, " . $insert_id . ", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 from bands;"); + $this->db->query("insert into bandxuser (bandid, userid, active, cq, dok, dxcc, iota, pota, sig, sota, uscounties, was, wwff, vucc, waja, rac, h26) select bands.id, " . $insert_id . ", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 from bands;"); $this->db->query("insert into paper_types (user_id,paper_name,metric,width,orientation,height) SELECT ".$insert_id.", paper_name, metric, width, orientation,height FROM paper_types where user_id = -1;"); return OK; } else { diff --git a/application/views/awards/h26/index.php b/application/views/awards/h26/index.php new file mode 100644 index 000000000..b0fb0c3c5 --- /dev/null +++ b/application/views/awards/h26/index.php @@ -0,0 +1,245 @@ + + + + +
+ +
+
+ +

+ +
+ +
+
+ +
+
Worked / Confirmed
+
+
+ input->post('worked') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> > + +
+
+ input->post('confirmed') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> > + +
+
+ input->post('notworked') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> > + +
+
+
+ +
+
QSL Type
+
+
+ input->post('qsl') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> > + +
+
+ input->post('lotw') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> > + +
+
+ input->post('eqsl')) echo ' checked="checked"'; ?> > + +
+
+ input->post('qrz')) echo ' checked="checked"'; ?> > + +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + + + +
+
+ +
+
+ + +
+ +
+
+
+ +
+ +
+ +
+ + + + + + # + Canton'; + foreach($bands as $band) { + echo '' . $band . ''; + } + echo ' + + '; + + foreach ($h26_array as $h26 => $value) { // Fills the table with the data + echo ' + ' . $i++ . ' + '. $h26 .''; + foreach ($value as $key) { + echo '' . $key . ''; + } + echo ''; + } + echo ' + +

Summary

+ + + + '; + + foreach($bands as $band) { + echo ''; + } + echo ' + + + + '; + + foreach ($h26_summary['worked'] as $h26) { // Fills the table with the data + echo ''; + } + + echo ' + '; + foreach ($h26_summary['confirmed'] as $h26) { // Fills the table with the data + echo ''; + } + + echo ' +
' . $band . 'Total
Total worked' . $h26 . '
Total confirmed' . $h26 . '
+
'; + } + else { + echo ''; + } + ?> +
+
+ diff --git a/application/views/interface_assets/footer.php b/application/views/interface_assets/footer.php index 188ecb113..b78f78324 100644 --- a/application/views/interface_assets/footer.php +++ b/application/views/interface_assets/footer.php @@ -1930,7 +1930,50 @@ $(document).ready(function(){ $(".buttons-csv").css("color", "white"); } - + + +uri->segment(2) == "h26") { ?> + + uri->segment(2) == "vucc_band") { ?>