diff --git a/.htaccess.sample b/.htaccess.sample index 435eea60..f766ea9f 100644 --- a/.htaccess.sample +++ b/.htaccess.sample @@ -10,3 +10,5 @@ RewriteRule ^(.*)$ /index.php?/$1 "[L,QSA,B= ?,BNP]" RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /index.php?/$1 "[L,QSA,B= ?,BNP]" + +RedirectMatch 404 ^/\.git diff --git a/README.md b/README.md index 31d76758..88f87b65 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,6 @@ Thanks to Andy (VE7CXZ), Gavin (M1BXF), Graham (W5ISP), Robert (M0VFC), Corby (K Cloudlog is supported by Patreon and donations via PayPal, thanks to the following people: -Paul (M0TZO), Tim (G4VXE), Paul (N8HM), Michelle (W5NYV), Mitchell (AD0HJ), Dan (M0TCB), Martin (DK3ML), Juan Carlos (EA5WA), Iain (M0PCB), Charlie (GM1TGY), Ondrej (OK1CDJ), Trystan (G0KAY), Oliver (DL6KBG), Volkmar Schirmer, Jordan (M0PIR), Thomas Ziegler, Mathis (DB9MAT), Ken (VE3HLS), Tyler (WL7T), Jeremy Taylor, Ben Kuhn, Eric Thresher, Michael Cullen, Juuso (OH1JW), Anthony Castiglia, Fernando Ramirez-Ferrer, Robert Dixon, Mark Percival, Julia (KV1V), Timo Tomasini, Ant (NU1U), Christopher Williams, Danny Barnes, Vic, Tom (M0LTE), smurphboy, Lars (SM0TGU), Theo (PD9DP), Stefan (SM0RGM). Peter (G0ABI), Lou (KI5FTY), Michael (DG3NAB). +Paul (M0TZO), Tim (G4VXE), Paul (N8HM), Michelle (W5NYV), Mitchell (AD0HJ), Dan (M0TCB), Martin (DK3ML), Juan Carlos (EA5WA), Iain (M0PCB), Charlie (GM1TGY), Ondrej (OK1CDJ), Trystan (G0KAY), Oliver (DL6KBG), Volkmar Schirmer, Jordan (M0PIR), Thomas Ziegler, Mathis (DB9MAT), Ken (VE3HLS), Tyler (WL7T), Jeremy Taylor, Ben Kuhn, Eric Thresher, Michael Cullen, Juuso (OH1JW), Anthony Castiglia, Fernando Ramirez-Ferrer, Robert Dixon, Mark Percival, Julia (KV1V), Timo Tomasini, Ant (NU1U), Christopher Williams, Danny Barnes, Vic, Tom (M0LTE), smurphboy, Lars (SM0TGU), Theo (PD9DP), Stefan (SM0RGM). Peter (G0ABI), Lou (KI5FTY), Michael (DG3NAB), Dragan (4O4A), minorsecond, Emily (W7AYQ), Steve (M0SKM), Rob (M0VFC). If you'd like to donate to Cloudlog to help allow @magicbug spend less time doing commercial work and more time coding Cloudlog then you can donate via [PayPal](https://paypal.me/PGoodhall), [Github Sponsor](https://github.com/sponsors/magicbug) or become a [Patreon](https://www.patreon.com/2m0sql) diff --git a/application/config/config.sample.php b/application/config/config.sample.php index adc2d85a..081a62e8 100644 --- a/application/config/config.sample.php +++ b/application/config/config.sample.php @@ -14,7 +14,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); */ $config['app_name'] = "Cloudlog"; -$config['app_version'] = "2.4.3"; +$config['app_version'] = "2.4.5"; $config['directory'] = "logbook"; $config['callbook'] = "hamqth"; // Options are hamqth or qrz $config['datadir'] = null; // default to install directory diff --git a/application/config/migration.php b/application/config/migration.php index 55613c99..b4c75212 100644 --- a/application/config/migration.php +++ b/application/config/migration.php @@ -21,7 +21,7 @@ $config['migration_enabled'] = TRUE; | be upgraded / downgraded to. | */ -$config['migration_version'] = 124; +$config['migration_version'] = 130; /* |-------------------------------------------------------------------------- diff --git a/application/controllers/Adif.php b/application/controllers/Adif.php index 5ebe2826..960b48bc 100644 --- a/application/controllers/Adif.php +++ b/application/controllers/Adif.php @@ -206,7 +206,7 @@ class adif extends CI_Controller { $custom_errors .= $this->logbook_model->import($record, $this->input->post('station_profile'), - $this->input->post('skipDuplicate'), $this->input->post('markLotw'), $this->input->post('dxccAdif'), $this->input->post('markQrz'), true, $this->input->post('operatorName')); + $this->input->post('skipDuplicate'), $this->input->post('markLotw'), $this->input->post('dxccAdif'), $this->input->post('markQrz'), $this->input->post('markHrd'), true, $this->input->post('operatorName'))."
"; }; diff --git a/application/controllers/Api.php b/application/controllers/Api.php index 2eaf99a7..ceaa192a 100644 --- a/application/controllers/Api.php +++ b/application/controllers/Api.php @@ -5,38 +5,7 @@ class API extends CI_Controller { // Do absolutely nothing function index() { - } - - /* - TODOs - - Search Callsign (Return Json) - - Add QSO return json - */ - - - function search_callsign($callsign) { - $this->db->select('COL_PRIMARY_KEY, COL_CALL, COL_MODE, COL_SUBMODE, COL_BAND, COL_COUNTRY, COL_FREQ, COL_GRIDSQUARE, COL_RST_RCVD, COL_RST_SENT, COL_SAT_MODE, COL_SAT_NAME'); - //$this->db->select("DATE_FORMAT(COL_TIME_ON, '%H:%i') AS time_on", FALSE ); - //$this->db->select("DATE_FORMAT(COL_TIME_ON, '%d/%c/%Y') AS date_on", FALSE ); - $this->db->like('COL_CALL', $callsign); - $this->db->or_like('COL_GRIDSQUARE', $callsign); - $query = $this->db->get($this->config->item('table_name')); - - - $results = array(); - - foreach ($query->result() as $result) - { - $results[] = $result; - } - - header('Content-type: application/json'); - - //$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5); - echo $_GET['jsoncallback'].'('.json_encode($results).')'; //assign resulting code to $_GET['jsoncallback]. - - //echo json_encode($results); - + echo "nothing to see"; } function help() @@ -158,6 +127,30 @@ class API extends CI_Controller { } } + function station_info($key) { + $this->load->model('api_model'); + $this->load->model('stations'); + header("Content-type: application/json"); + if(substr($this->api_model->access($key),0,1) == 'r') { /* Checkpermission for _r_eading */ + $this->api_model->update_last_used($key); + $userid = $this->api_model->key_userid($key); + $station_ids = array(); + $stations=$this->stations->all_of_user($userid); + foreach ($stations->result() as $row) { + $result['station_id']=$row->station_id; + $result['station_profile_name']=$row->station_profile_name; + $result['station_gridsquare']=$row->station_gridsquare; + $result['station_callsign']=$row->station_callsign;; + $result['station_active']=$row->station_active; + array_push($station_ids, $result); + } + echo json_encode($station_ids); + } else { + http_response_code(401); + echo json_encode(['status' => 'failed', 'reason' => "missing or invalid api key"]); + } + } + // FUNCTION: search() // Handle search requests /* @@ -468,9 +461,7 @@ class API extends CI_Controller { if(isset($obj['station_profile_id'])) { - $this->logbook_model->import($record, $obj['station_profile_id'], NULL, NULL, NULL, NULL, false, false, true); - } else { - $this->logbook_model->import($record, 0, NULL, NULL, NULL, NULL, false, false, true); + $this->logbook_model->import($record, $obj['station_profile_id'], NULL, NULL, NULL, NULL, NULL, false, false, true); } }; diff --git a/application/controllers/Eqsl.php b/application/controllers/Eqsl.php index 642e6fa5..b18cf0b8 100644 --- a/application/controllers/Eqsl.php +++ b/application/controllers/Eqsl.php @@ -15,6 +15,7 @@ class eqsl extends CI_Controller { $folder_name = "images/eqsl_card_images"; $data['storage_used'] = $this->sizeFormat($this->folderSize($folder_name)); + // Render Page $data['page_title'] = "eQSL Cards"; @@ -29,6 +30,12 @@ class eqsl extends CI_Controller { $this->load->model('user_model'); if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); } + $this->load->model('stations'); + $data['station_profile'] = $this->stations->all_of_user(); + $active_station_id = $this->stations->find_active(); + $station_profile = $this->stations->profile($active_station_id); + $data['active_station_info'] = $station_profile->row(); + // Check if eQSL Nicknames have been defined $this->load->model('eqslmethods_model'); $eqsl_locations = $this->eqslmethods_model->all_of_user_with_eqsl_nick_defined(); @@ -71,29 +78,39 @@ class eqsl extends CI_Controller { $eqsl_results[] = $this->eqslimporter->fetch($eqsl_password); } - } - else - { - if ( ! $this->upload->do_upload()) - { - $data['page_title'] = "eQSL Import"; - $data['error'] = $this->upload->display_errors(); + } elseif ($this->input->post('eqslimport') == 'upload') { + $station_id4upload=$this->input->post('station_profile'); + if ($this->stations->check_station_is_accessible($station_id4upload)) { + $station_callsign=$this->stations->profile($station_id4upload)->row()->station_callsign; + if ( ! $this->upload->do_upload()) + { + $data['page_title'] = "eQSL Import"; + $data['error'] = $this->upload->display_errors(); - $this->load->view('interface_assets/header', $data); - $this->load->view('eqsl/import'); - $this->load->view('interface_assets/footer'); + $this->load->view('interface_assets/header', $data); + $this->load->view('eqsl/import'); + $this->load->view('interface_assets/footer'); - return; + return; + } else { + $data = array('upload_data' => $this->upload->data()); + + $this->load->library('EqslImporter'); + $this->eqslimporter->from_file('./uploads/'.$data['upload_data']['file_name'],$station_callsign); + + $eqsl_results[] = $this->eqslimporter->import(); + } + } else { + log_message('error',$station_id4upload." is not valid for user!"); } - else - { - $data = array('upload_data' => $this->upload->data()); + } else { + $data['page_title'] = "eQSL Import"; - $this->load->library('EqslImporter'); - $this->eqslimporter->from_file('./uploads/'.$data['upload_data']['file_name']); + $this->load->view('interface_assets/header', $data); + $this->load->view('eqsl/import'); + $this->load->view('interface_assets/footer'); - $eqsl_results[] = $this->eqslimporter->import(); - } + return; } $data['eqsl_results'] = $eqsl_results; diff --git a/application/controllers/Gridmap.php b/application/controllers/Gridmap.php index d4e32e6a..cc28c06e 100644 --- a/application/controllers/Gridmap.php +++ b/application/controllers/Gridmap.php @@ -11,11 +11,17 @@ class Gridmap extends CI_Controller { $this->load->model('bands'); $this->load->model('gridmap_model'); + $this->load->model('stations'); + + $data['homegrid'] = explode(',', $this->stations->find_gridsquare()); $data['modes'] = $this->gridmap_model->get_worked_modes(); $data['bands'] = $this->bands->get_worked_bands(); $data['sats_available'] = $this->bands->get_worked_sats(); + $data['user_gridmap_default_band'] = $this->session->userdata('user_gridmap_default_band'); + $data['user_gridmap_confirmation'] = $this->session->userdata('user_gridmap_confirmation'); + $data['layer'] = $this->optionslib->get_option('option_map_tile_server'); $data['attribution'] = $this->optionslib->get_option('option_map_tile_server_copyright'); @@ -27,6 +33,7 @@ class Gridmap extends CI_Controller { $footerData = []; $footerData['scripts'] = [ + 'assets/js/leaflet/geocoding.js', 'assets/js/leaflet/L.MaidenheadColouredGridMap.js', 'assets/js/sections/gridmap.js?' ]; @@ -175,4 +182,4 @@ class Gridmap extends CI_Controller { header('Content-Type: application/json'); echo json_encode($data); } -} \ No newline at end of file +} diff --git a/application/controllers/Hrdlog.php b/application/controllers/Hrdlog.php new file mode 100644 index 00000000..eca9ef47 --- /dev/null +++ b/application/controllers/Hrdlog.php @@ -0,0 +1,171 @@ +setOptions(); + + $this->load->model('logbook_model'); + + $station_ids = $this->logbook_model->get_station_id_with_hrdlog_code(); + + if ($station_ids) { + foreach ($station_ids as $station) { + $hrdlog_code = $station->hrdlog_code; + if($this->mass_upload_qsos($station->station_id, $hrdlog_code)) { + echo "QSOs have been uploaded to hrdlog.net."; + log_message('info', 'QSOs have been uploaded to hrdlog.net.'); + } else{ + echo "No QSOs found for upload."; + log_message('info', 'No QSOs found for upload.'); + } + } + } else { + echo "No station profiles with a hrdlog Code found."; + log_message('error', "No station profiles with a hrdlog Code found."); + } + + } + + function setOptions() { + $this->config->load('config'); + ini_set('memory_limit', '-1'); + ini_set('display_errors', 1); + ini_set('display_startup_errors', 1); + error_reporting(E_ALL); + } + + /* + * Function gets all QSOs from given station_id, that are not previously uploaded to hrdlog. + * Adif is build for each qso, and then uploaded, one at a time + */ + function mass_upload_qsos($station_id, $hrdlog_code) { + $i = 0; + $data['qsos'] = $this->logbook_model->get_hrdlog_qsos($station_id); + $errormessages=array(); + + $CI =& get_instance(); + $CI->load->library('AdifHelper'); + + if ($data['qsos']) { + foreach ($data['qsos']->result() as $qso) { + $adif = $CI->adifhelper->getAdifLine($qso); + + if ($qso->COL_HRDLOG_QSO_UPLOAD_STATUS == 'M') { + $result = $this->logbook_model->push_qso_to_hrdlog($hrdlog_code, $qso->COL_STATION_CALLSIGN,$adif, true); + } else { + $result = $this->logbook_model->push_qso_to_hrdlog($hrdlog_code, $qso->COL_STATION_CALLSIGN,$adif); + } + + if ( ($result['status'] == 'OK') || ( ($result['status'] == 'error') || ($result['status'] == 'duplicate')) ){ + $this->markqso($qso->COL_PRIMARY_KEY); + $i++; + } elseif ((substr($result['status'],0,11) == 'auth_error')) { + log_message('error', 'hrdlog upload failed for qso: Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON); + log_message('error', 'hrdlog upload failed with the following message: ' .$result['message']); + log_message('error', 'hrdlog upload stopped for Station_ID: ' .$station_id); + $errormessages[] = $result['message'] . 'Invalid HRDLog-Code, stopped at Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON; + break; /* If key is invalid, immediate stop syncing for more QSOs of this station */ + } else { + log_message('error', 'hrdlog upload failed for qso: Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON); + log_message('error', 'hrdlog upload failed with the following message: ' .$result['message']); + $errormessages[] = $result['message'] . ' Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON; + } + } + $result['status'] = 'OK'; + $result['count'] = $i; + $result['errormessages'] = $errormessages; + return $result; + } else { + $result['status'] = 'Error'; + $result['count'] = $i; + $result['errormessages'] = $errormessages; + return $result; + } + } + + /* + * Function marks QSO with given primarykey as uploaded to hrdlog + */ + function markqso($primarykey) { + $this->logbook_model->mark_hrdlog_qsos_sent($primarykey); + } + + /* + * Used for displaying the uid for manually selecting log for upload to hrdlog + */ + public function export() { + $this->load->model('stations'); + + $data['page_title'] = "HRDlog.net Logbook"; + + $data['station_profiles'] = $this->stations->all_of_user(); + $data['station_profile'] = $this->stations->stations_with_hrdlog_code(); + + $this->load->view('interface_assets/header', $data); + $this->load->view('hrdlog/export'); + $this->load->view('interface_assets/footer'); + } + + /* + * Used for ajax-function when selecting log for upload to hrdlog + */ + public function upload_station() { + $this->setOptions(); + $this->load->model('stations'); + + $postData = $this->input->post(); + + $this->load->model('logbook_model'); + $result = $this->logbook_model->exists_hrdlog_code($postData['station_id']); + $hrdlog_code = $result->hrdlog_code; + header('Content-type: application/json'); + $result = $this->mass_upload_qsos($postData['station_id'], $hrdlog_code); + if ($result['status'] == 'OK') { + $stationinfo = $this->stations->stations_with_hrdlog_code(); + $info = $stationinfo->result(); + + $data['status'] = 'OK'; + $data['info'] = $info; + $data['infomessage'] = $result['count'] . " QSOs are now uploaded to hrdlog"; + $data['errormessages'] = $result['errormessages']; + echo json_encode($data); + } else { + $data['status'] = 'Error'; + $data['info'] = 'Error: No QSOs found to upload.'; + $data['errormessages'] = $result['errormessages']; + echo json_encode($data); + } + } + + public function mark_hrdlog() { + // Set memory limit to unlimited to allow heavy usage + ini_set('memory_limit', '-1'); + + $station_id = $this->security->xss_clean($this->input->post('station_profile')); + + $this->load->model('adif_data'); + + $data['qsos'] = $this->adif_data->export_custom($this->input->post('from'), $this->input->post('to'), $station_id); + + $this->load->model('logbook_model'); + + foreach ($data['qsos']->result() as $qso) + { + $this->logbook_model->mark_hrdlog_qsos_sent($qso->COL_PRIMARY_KEY); + } + + $this->load->view('interface_assets/header', $data); + $this->load->view('hrdlog/mark_hrdlog', $data); + $this->load->view('interface_assets/footer'); + } +} diff --git a/application/controllers/Logbook.php b/application/controllers/Logbook.php index d1d797e2..87933907 100644 --- a/application/controllers/Logbook.php +++ b/application/controllers/Logbook.php @@ -98,30 +98,15 @@ class Logbook extends CI_Controller { $callsign = str_replace("-","/",$callsign); // Check if callsign is an LOTW User - $lotw_member = ""; - $lotw_file_name = "./updates/lotw_users.csv"; - - if (file_exists($lotw_file_name)) { - $f = fopen($lotw_file_name, "r"); - $result = false; - while ($row = fgetcsv($f)) { - if ($row[0] == strtoupper($callsign)) { - $result = $row[0]; - $lotw_member = "active"; - break; - } - } - - if($lotw_member != "active") { - $lotw_member = "not found"; - } - fclose($f); - } else { - $lotw_member = "not found"; - } - // Check Database for all other data $this->load->model('logbook_model'); + + $lotw_days=$this->logbook_model->check_last_lotw($callsign); + if ($lotw_days != null) { + $lotw_member="active"; + } else { + $lotw_member="not found"; + } $return = [ "callsign" => strtoupper($callsign), @@ -137,6 +122,7 @@ class Logbook extends CI_Controller { "bearing" => "", "workedBefore" => false, "lotw_member" => $lotw_member, + "lotw_days" => $lotw_days, "image" => "", ]; @@ -772,7 +758,7 @@ class Logbook extends CI_Controller { function querydb($id) { $this->db->from($this->config->item('table_name')); $this->db->join('station_profile', 'station_profile.station_id = '.$this->config->item('table_name').'.station_id'); - $this->db->join('dxcc_entities', 'dxcc_entities.adif = '.$this->config->item('table_name').'.COL_DXCC'); + $this->db->join('dxcc_entities', 'dxcc_entities.adif = '.$this->config->item('table_name').'.COL_DXCC', 'left outer'); $this->db->join('lotw_users', 'lotw_users.callsign = '.$this->config->item('table_name').'.col_call', 'left outer'); $this->db->group_start(); $this->db->like(''.$this->config->item('table_name').'.COL_CALL', $id); diff --git a/application/controllers/Logbookadvanced.php b/application/controllers/Logbookadvanced.php index b2ed5e60..384889f3 100644 --- a/application/controllers/Logbookadvanced.php +++ b/application/controllers/Logbookadvanced.php @@ -1,4 +1,4 @@ -logbook_model->fetchDxcc(); $pageData['iotaarray'] = $this->logbook_model->fetchIota(); $pageData['sats'] = $this->bands->get_worked_sats(); - + $pageData['bands'] = $this->bands->get_worked_bands(); - $CI =& get_instance(); + $CI =& get_instance(); // Get Date format if($CI->session->userdata('user_date_format')) { // If Logged in and session exists @@ -104,8 +104,17 @@ class Logbookadvanced extends CI_Controller { 'propmode' => xss_clean($this->input->post('propmode')), 'gridsquare' => xss_clean($this->input->post('gridsquare')), 'state' => xss_clean($this->input->post('state')), + 'cqzone' => xss_clean($this->input->post('cqzone')), 'qsoresults' => xss_clean($this->input->post('qsoresults')), 'sats' => xss_clean($this->input->post('sats')), + 'lotwSent' => xss_clean($this->input->post('lotwSent')), + 'lotwReceived' => xss_clean($this->input->post('lotwReceived')), + 'eqslSent' => xss_clean($this->input->post('eqslSent')), + 'eqslReceived' => xss_clean($this->input->post('eqslReceived')), + 'qslvia' => xss_clean($this->input->post('qslvia')), + 'sota' => xss_clean($this->input->post('sota')), + 'pota' => xss_clean($this->input->post('pota')), + 'wwff' => xss_clean($this->input->post('wwff')), ); $qsos = []; @@ -170,7 +179,7 @@ class Logbookadvanced extends CI_Controller { $data = $this->logbookadvanced_model->getQsosForAdif($ids, $user_id); $results = $data->result('array'); - + $qsos = []; foreach ($results as $data) { $qsos[] = new QSO($data); @@ -198,7 +207,7 @@ class Logbookadvanced extends CI_Controller { $data = $this->logbookadvanced_model->getQsosForAdif($ids, $user_id); $results = $data->result('array'); - + $qsos = []; foreach ($results as $data) { $qsos[] = new QSO($data); @@ -212,4 +221,4 @@ class Logbookadvanced extends CI_Controller { header("Content-Type: application/json"); print json_encode($q); } -} \ No newline at end of file +} diff --git a/application/controllers/Logbooks.php b/application/controllers/Logbooks.php index ed7a2d1a..a5f021c3 100644 --- a/application/controllers/Logbooks.php +++ b/application/controllers/Logbooks.php @@ -129,6 +129,12 @@ class Logbooks extends CI_Controller { $this->load->view('logbooks/components/publicSlugInputValidation', $data); } + public function save_publicsearch() { + $this->load->model('logbooks_model'); + $returndata = $this->logbooks_model->save_public_search($this->input->post('public_search'), $this->input->post('logbook_id')); + echo "
Public Search Setttings Saved
"; + } + public function save_publicslug() { $this->load->model('logbooks_model'); diff --git a/application/controllers/Lookup.php b/application/controllers/Lookup.php index 04c2ebcd..5e74dfed 100644 --- a/application/controllers/Lookup.php +++ b/application/controllers/Lookup.php @@ -53,10 +53,9 @@ class Lookup extends CI_Controller { $this->load->view('lookup/result', $data); } - public function scp($call) { - - if($call) { - $uppercase_callsign = strtoupper($call); + public function scp() { + if($_POST['callsign']) { + $uppercase_callsign = strtoupper($_POST['callsign']); } // SCP results from logbook diff --git a/application/controllers/Lotw.php b/application/controllers/Lotw.php index eb00dd44..d3d480be 100644 --- a/application/controllers/Lotw.php +++ b/application/controllers/Lotw.php @@ -192,6 +192,9 @@ class Lotw extends CI_Controller { */ public function lotw_upload() { + $this->load->model('user_model'); + $this->user_model->authorize(2); + // Fire OpenSSL missing error if not found if (!extension_loaded('openssl')) { echo "You must install php OpenSSL for LoTW functions to work"; @@ -200,154 +203,165 @@ class Lotw extends CI_Controller { // Get Station Profile Data $this->load->model('Stations'); - $station_profiles = $this->Stations->all(); + if ($this->user_model->authorize(2)) { + $station_profiles = $this->Stations->all_of_user($this->session->userdata('user_id')); + $sync_user_id=$this->session->userdata('user_id'); + } else { + $station_profiles = $this->Stations->all(); + $sync_user_id=null; + } // Array of QSO IDs being Uploaded $qso_id_array = array(); // Build TQ8 Outputs - if ($station_profiles->num_rows() >= 1) { + if ($station_profiles->num_rows() >= 1) { - foreach ($station_profiles->result() as $station_profile) - { + foreach ($station_profiles->result() as $station_profile) { - // Get Certificate Data - $this->load->model('LotwCert'); - $data['station_profile'] = $station_profile; - $data['lotw_cert_info'] = $this->LotwCert->lotw_cert_details($station_profile->station_callsign, $station_profile->station_dxcc); + // Get Certificate Data + $this->load->model('LotwCert'); + $data['station_profile'] = $station_profile; + $data['lotw_cert_info'] = $this->LotwCert->lotw_cert_details($station_profile->station_callsign, $station_profile->station_dxcc); - // If Station Profile has no LOTW Cert continue on. - if(!isset($data['lotw_cert_info']->cert_dxcc_id)) { - continue; - } - - // Check if LoTW certificate itself is valid - // Validty of QSO dates will be checked later - $current_date = date('Y-m-d H:i:s'); - if ($current_date <= $data['lotw_cert_info']->date_created) { - echo $data['lotw_cert_info']->callsign.": LoTW certificate not valid yet!"; - continue; - } - if ($current_date >= $data['lotw_cert_info']->date_expires) { - echo $data['lotw_cert_info']->callsign.": LoTW certificate expired!"; - continue; - } - - // Get QSOs - - $this->load->model('Logbook_model'); - - $data['qsos'] = $this->Logbook_model->get_lotw_qsos_to_upload($data['station_profile']->station_id, $data['lotw_cert_info']->qso_start_date, $data['lotw_cert_info']->qso_end_date); - - // Nothing to upload - if(empty($data['qsos']->result())){ - echo $station_profile->station_callsign." (".$station_profile->station_profile_name.") No QSOs to Upload
"; - continue; - } - - foreach ($data['qsos']->result() as $temp_qso) { - array_push($qso_id_array, $temp_qso->COL_PRIMARY_KEY); - } - - // Build File to save - $adif_to_save = $this->load->view('lotw_views/adif_views/adif_export', $data, TRUE); - - // create folder to store upload file - if (!file_exists('./uploads/lotw')) { - mkdir('./uploads/lotw', 0775, true); - } - - // Build Filename - $filename_for_saving = './uploads/lotw/'.preg_replace('/[^a-z0-9]+/', '-', strtolower($data['lotw_cert_info']->callsign))."-".date("Y-m-d-H-i-s")."-cloudlog.tq8"; - - $gzdata = gzencode($adif_to_save, 9); - $fp = fopen($filename_for_saving, "w"); - fwrite($fp, $gzdata); - fclose($fp); - - //The URL that accepts the file upload. - $url = 'https://lotw.arrl.org/lotw/upload'; - - //The name of the field for the uploaded file. - $uploadFieldName = 'upfile'; - - //The full path to the file that you want to upload - $filePath = realpath($filename_for_saving); - - //Initiate cURL - $ch = curl_init(); - - //Set the URL - curl_setopt($ch, CURLOPT_URL, $url); - - //Set the HTTP request to POST - curl_setopt($ch, CURLOPT_POST, true); - - //Tell cURL to return the output as a string. - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - //If the function curl_file_create exists - if(function_exists('curl_file_create')){ - //Use the recommended way, creating a CURLFile object. - $filePath = curl_file_create($filePath); - } else{ - //Otherwise, do it the old way. - //Get the canonicalized pathname of our file and prepend - //the @ character. - $filePath = '@' . realpath($filePath); - //Turn off SAFE UPLOAD so that it accepts files - //starting with an @ - curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false); - } - - //Setup our POST fields - $postFields = array( - $uploadFieldName => $filePath - ); - - curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); - - //Execute the request - $result = curl_exec($ch); - - //If an error occured, throw an exception - //with the error message. - if(curl_errno($ch)){ - throw new Exception(curl_error($ch)); - } - - $pos = strpos($result, ""); - - if ($pos === false) { - // Upload of TQ8 Failed for unknown reason - echo $station_profile->station_callsign." (".$station_profile->station_profile_name.") Upload Failed"."
"; - } else { - // Upload of TQ8 was successfull - - echo "Upload Successful - ".$filename_for_saving."
"; - - $this->LotwCert->last_upload($data['lotw_cert_info']->lotw_cert_id); - - // Mark QSOs as Sent - foreach ($qso_id_array as $qso_number) { - $this->Logbook_model->mark_lotw_sent($qso_number); - } - } - - // Delete TQ8 File - This is done regardless of whether upload was succcessful - unlink(realpath($filename_for_saving)); + // If Station Profile has no LOTW Cert continue on. + if(!isset($data['lotw_cert_info']->cert_dxcc_id)) { + continue; } - } else { - echo "No Station Profiles found to upload to LOTW"; + + // Check if LoTW certificate itself is valid + // Validty of QSO dates will be checked later + $current_date = date('Y-m-d H:i:s'); + if ($current_date <= $data['lotw_cert_info']->date_created) { + echo $data['lotw_cert_info']->callsign.": LoTW certificate not valid yet!"; + continue; + } + if ($current_date >= $data['lotw_cert_info']->date_expires) { + echo $data['lotw_cert_info']->callsign.": LoTW certificate expired!"; + continue; + } + + // Get QSOs + + $this->load->model('Logbook_model'); + + $data['qsos'] = $this->Logbook_model->get_lotw_qsos_to_upload($data['station_profile']->station_id, $data['lotw_cert_info']->qso_start_date, $data['lotw_cert_info']->qso_end_date); + + // Nothing to upload + if(empty($data['qsos']->result())){ + if ($this->user_model->authorize(2)) { // Only be verbose if we have a session + echo $station_profile->station_callsign." (".$station_profile->station_profile_name.") No QSOs to Upload
"; + } + continue; + } + + foreach ($data['qsos']->result() as $temp_qso) { + array_push($qso_id_array, $temp_qso->COL_PRIMARY_KEY); + } + + // Build File to save + $adif_to_save = $this->load->view('lotw_views/adif_views/adif_export', $data, TRUE); + + // create folder to store upload file + if (!file_exists('./uploads/lotw')) { + mkdir('./uploads/lotw', 0775, true); + } + + // Build Filename + $filename_for_saving = './uploads/lotw/'.preg_replace('/[^a-z0-9]+/', '-', strtolower($data['lotw_cert_info']->callsign))."-".date("Y-m-d-H-i-s")."-cloudlog.tq8"; + + $gzdata = gzencode($adif_to_save, 9); + $fp = fopen($filename_for_saving, "w"); + fwrite($fp, $gzdata); + fclose($fp); + + //The URL that accepts the file upload. + $url = 'https://lotw.arrl.org/lotw/upload'; + + //The name of the field for the uploaded file. + $uploadFieldName = 'upfile'; + + //The full path to the file that you want to upload + $filePath = realpath($filename_for_saving); + + //Initiate cURL + $ch = curl_init(); + + //Set the URL + curl_setopt($ch, CURLOPT_URL, $url); + + //Set the HTTP request to POST + curl_setopt($ch, CURLOPT_POST, true); + + //Tell cURL to return the output as a string. + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + //If the function curl_file_create exists + if(function_exists('curl_file_create')){ + //Use the recommended way, creating a CURLFile object. + $filePath = curl_file_create($filePath); + } else{ + //Otherwise, do it the old way. + //Get the canonicalized pathname of our file and prepend + //the @ character. + $filePath = '@' . realpath($filePath); + //Turn off SAFE UPLOAD so that it accepts files + //starting with an @ + curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false); + } + + //Setup our POST fields + $postFields = array( + $uploadFieldName => $filePath + ); + + curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); + + //Execute the request + $result = curl_exec($ch); + + //If an error occured, throw an exception + //with the error message. + if(curl_errno($ch)){ + throw new Exception(curl_error($ch)); + } + + $pos = strpos($result, ""); + + if ($pos === false) { + // Upload of TQ8 Failed for unknown reason + echo $station_profile->station_callsign." (".$station_profile->station_profile_name.") Upload Failed"."
"; + } else { + // Upload of TQ8 was successfull + + echo "Upload Successful - ".$filename_for_saving."
"; + + $this->LotwCert->last_upload($data['lotw_cert_info']->lotw_cert_id); + + // Mark QSOs as Sent + foreach ($qso_id_array as $qso_number) { + $this->Logbook_model->mark_lotw_sent($qso_number); + } + } + + // Delete TQ8 File - This is done regardless of whether upload was succcessful + unlink(realpath($filename_for_saving)); } + } else { + echo "No Station Profiles found to upload to LOTW"; + } /* | Download QSO Matches from LoTW - */ + */ + if ($this->user_model->authorize(2)) { echo "

"; - echo $this->lotw_download(); - + $sync_user_id=$this->session->userdata('user_id'); + } else { + $sync_user_id=null; + } + echo $this->lotw_download($sync_user_id); } /* @@ -497,23 +511,9 @@ class Lotw extends CI_Controller { $record['qsl_rcvd'] = $config['lotw_rcvd_mark']; } - $status = $this->logbook_model->import_check($time_on, $record['call'], $record['band']); - $skipNewQso = $this->input->post('importMissing'); // If import missing was checked + $status = $this->logbook_model->import_check($time_on, $record['call'], $record['band'], $record['mode'], $record['station_callsign']); - if($status[0] == "No Match" && $skipNewQso != NULL) { - - $station_id = $this->logbook_model->find_correct_station_id($record['station_callsign'], $record['my_gridsquare']); - - if ($station_id != NULL) { - $result = $this->logbook_model->import($record, $station_id, NULL, TRUE, NULL, NULL, true, false); // Create the Entry - if ($result == "") { - $lotw_status = 'QSO imported'; - } else { - $lotw_status = $result; - } - } - - } else { + if($status[0] == "Found") { if (isset($record['state'])) { $state = $record['state']; } else { @@ -526,6 +526,12 @@ class Lotw extends CI_Controller { $qsl_gridsquare = ""; } + if (isset($record['vucc_grids'])) { + $qsl_vucc_grids = $record['vucc_grids']; + } else { + $qsl_vucc_grids = ""; + } + if (isset($record['iota'])) { $iota = $record['iota']; } else { @@ -550,23 +556,36 @@ class Lotw extends CI_Controller { $ituz = ""; } - $lotw_status = $this->logbook_model->lotw_update($time_on, $record['call'], $record['band'], $qsl_date, $record['qsl_rcvd'], $state, $qsl_gridsquare, $iota, $cnty, $cqz, $ituz); + $lotw_status = $this->logbook_model->lotw_update($time_on, $record['call'], $record['band'], $qsl_date, $record['qsl_rcvd'], $state, $qsl_gridsquare, $qsl_vucc_grids, $iota, $cnty, $cqz, $ituz, $record['station_callsign']); + + $table .= ""; + $table .= "".$record['station_callsign'].""; + $table .= "".$time_on.""; + $table .= "".$record['call'].""; + $table .= "".$record['mode'].""; + $table .= "".$record['qsl_rcvd'].""; + $table .= "".$qsl_date.""; + $table .= "".$state.""; + $table .= "".($qsl_gridsquare != '' ? $qsl_gridsquare : $qsl_vucc_grids).""; + $table .= "".$iota.""; + $table .= "QSO Record: ".$status[0].""; + $table .= "LoTW Record: ".$lotw_status.""; + $table .= ""; + } else { + $table .= ""; + $table .= "".$record['station_callsign'].""; + $table .= "".$time_on.""; + $table .= "".$record['call'].""; + $table .= "".$record['mode'].""; + $table .= "".$record['qsl_rcvd'].""; + $table .= ""; + $table .= ""; + $table .= ""; + $table .= ""; + $table .= "QSO Record: ".$status[0].""; + $table .= ""; + $table .= ""; } - - - $table .= ""; - $table .= "".$record['station_callsign'].""; - $table .= "".$time_on.""; - $table .= "".$record['call'].""; - $table .= "".$record['mode'].""; - $table .= "".$record['qsl_rcvd'].""; - $table .= "".$qsl_date.""; - $table .= "".$state.""; - $table .= "".$qsl_gridsquare.""; - $table .= "".$iota.""; - $table .= "QSO Record: ".$status[0].""; - $table .= "LoTW Record: ".$lotw_status.""; - $table .= ""; } if ($table != "") @@ -578,17 +597,20 @@ class Lotw extends CI_Controller { unlink($filepath); - if(isset($data['lotw_table_headers'])) { - if($display_view == TRUE) { - $data['page_title'] = "LoTW ADIF Information"; - $this->load->view('interface_assets/header', $data); - $this->load->view('lotw/analysis'); - $this->load->view('interface_assets/footer'); + $this->load->model('user_model'); + if ($this->user_model->authorize(2)) { // Only Output results if authorized User + if(isset($data['lotw_table_headers'])) { + if($display_view == TRUE) { + $data['page_title'] = "LoTW ADIF Information"; + $this->load->view('interface_assets/header', $data); + $this->load->view('lotw/analysis'); + $this->load->view('interface_assets/footer'); + } else { + return $tableheaders.$table; + } } else { - return $tableheaders.$table; + echo "Downloaded LoTW report contains no matches."; } - } else { - echo "Downloaded LoTW report contains no matches."; } } @@ -601,21 +623,21 @@ class Lotw extends CI_Controller { | downloading matching QSOs. | */ - function lotw_download() { + function lotw_download($sync_user_id = null) { $this->load->model('user_model'); $this->load->model('logbook_model'); $query = $this->user_model->get_all_lotw_users(); if ($query->num_rows() >= 1) { - - foreach ($query->result() as $user) - { + $results=''; + foreach ($query->result() as $user) { + if ( ($sync_user_id != null) && ($sync_user_id != $user->user_id) ) { continue; } $config['upload_path'] = './uploads/'; $file = $config['upload_path'] . 'lotwreport_download.adi'; if (file_exists($file) && ! is_writable($file)) { - return "Temporary download file ".$file." is not writable. Aborting!"; + $result.= "Temporary download file ".$file." is not writable. Aborting!"; } // Get credentials for LoTW @@ -634,7 +656,7 @@ class Lotw extends CI_Controller { echo "You have not defined your ARRL LoTW credentials!"; } - $lotw_last_qsl_date = date('Y-m-d', strtotime($this->logbook_model->lotw_last_qsl_date())); + $lotw_last_qsl_date = date('Y-m-d', strtotime($this->logbook_model->lotw_last_qsl_date($user->user_id))); // Build URL for LoTW report file $lotw_url .= "?"; @@ -646,18 +668,19 @@ class Lotw extends CI_Controller { $lotw_url .= "$lotw_last_qsl_date"; if (! is_writable(dirname($file))) { - return "Temporary download directory ".dirname($file)." is not writable. Aborting!"; + $results.= "Temporary download directory ".dirname($file)." is not writable. Aborting!"; + continue; } file_put_contents($file, file_get_contents($lotw_url)); if (file_get_contents($file, false, null, 0, 39) != "ARRL Logbook of the World Status Report") { - return "LoTW downloading failed either due to it being down or incorrect logins."; + $results.= "LoTW downloading failed for User ".$data['user_lotw_name']." either due to it being down or incorrect logins."; + continue; } ini_set('memory_limit', '-1'); - $results = $this->loadFromFile($file, false); - - return $results; + $results.= $this->loadFromFile($file, false); } + return $results; } else { return "No LOTW User details found to carry out matches."; } @@ -707,7 +730,7 @@ class Lotw extends CI_Controller { } else { // Query the logbook to determine when the last LoTW confirmation was - $lotw_last_qsl_date = date('Y-m-d', strtotime($this->logbook_model->lotw_last_qsl_date())); + $lotw_last_qsl_date = date('Y-m-d', strtotime($this->logbook_model->lotw_last_qsl_date($this->session->userdata['user_id']))); } // Build URL for LoTW report file diff --git a/application/controllers/Qrz.php b/application/controllers/Qrz.php index 13d35421..68eb29db 100644 --- a/application/controllers/Qrz.php +++ b/application/controllers/Qrz.php @@ -71,9 +71,15 @@ class Qrz extends CI_Controller { $result = $this->logbook_model->push_qso_to_qrz($qrz_api_key, $adif); } - if ($result['status'] == 'OK') { + if ( ($result['status'] == 'OK') || ( ($result['status'] == 'error') && ($result['message'] == 'STATUS=FAIL&REASON=Unable to add QSO to database: duplicate&EXTENDED=')) ){ $this->markqso($qso->COL_PRIMARY_KEY); $i++; + } elseif ( ($result['status']=='error') && (substr($result['message'],0,11) == 'STATUS=AUTH')) { + log_message('error', 'QRZ upload failed for qso: Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON); + log_message('error', 'QRZ upload failed with the following message: ' .$result['message']); + log_message('error', 'QRZ upload stopped for Station_ID: ' .$station_id); + $errormessages[] = $result['message'] . ' Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON; + break; /* If key is invalid, immediate stop syncing for more QSOs of this station */ } else { log_message('error', 'QRZ upload failed for qso: Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON); log_message('error', 'QRZ upload failed with the following message: ' .$result['message']); diff --git a/application/controllers/Qsl.php b/application/controllers/Qsl.php index 2602fa78..89df8947 100644 --- a/application/controllers/Qsl.php +++ b/application/controllers/Qsl.php @@ -66,11 +66,15 @@ class Qsl extends CI_Controller { if (isset($_FILES['qslcardfront']) && $_FILES['qslcardfront']['name'] != "" && $_FILES['qslcardfront']['error'] == 0) { $result['front'] = $this->uploadQslCardFront($qsoid); + } else { + $result['front']['status'] = ''; } if (isset($_FILES['qslcardback']) && $_FILES['qslcardback']['name'] != "" && $_FILES['qslcardback']['error'] == 0) { $result['back'] = $this->uploadQslCardBack($qsoid); + } else { + $result['back']['status'] = ''; } header("Content-type: application/json"); @@ -170,6 +174,13 @@ class Qsl extends CI_Controller { echo json_encode($result); } + function viewQsl() { + $cleanid = $this->security->xss_clean($this->input->post('id')); + $this->load->model('Qsl_model'); + $data['qslimages'] = $this->Qsl_model->getQslForQsoId($cleanid); + $this->load->view('qslcard/qslcarousel', $data); + } + } // Functions for storage, these need shifted to a libary to use across Cloudlog diff --git a/application/controllers/Radio.php b/application/controllers/Radio.php index 491d98c3..a276f0fb 100755 --- a/application/controllers/Radio.php +++ b/application/controllers/Radio.php @@ -78,82 +78,95 @@ } - function json($id) - { + function json($id) { - header('Content-Type: application/json'); + $this->load->model('user_model'); - $this->load->model('cat'); + // Check if users logged in - $query = $this->cat->radio_status($id); + if($this->user_model->validate_session() == 0) { + // user is not logged in + // Return Json data + header('Content-Type: application/json'); + echo json_encode(array( + "error" => "not_logged_in" + ), JSON_PRETTY_PRINT); + } else { - if ($query->num_rows() > 0) - { - foreach ($query->result() as $row) + header('Content-Type: application/json'); + + $this->load->model('cat'); + + $query = $this->cat->radio_status($id); + + if ($query->num_rows() > 0) { + foreach ($query->result() as $row) + { - $frequency = $row->frequency; + $frequency = $row->frequency; - $frequency_rx = $row->frequency_rx; + $frequency_rx = $row->frequency_rx; - $power = $row->power; + $power = $row->power; - $prop_mode = $row->prop_mode; + $prop_mode = $row->prop_mode; - // Check Mode - $mode = strtoupper($row->mode); - if ($mode == "FMN") { - $mode = "FM"; - } - - if ($row->prop_mode == "SAT") { - // Get Satellite Name - if ($row->sat_name == "AO-07") { - $sat_name = "AO-7"; - } elseif ($row->sat_name == "LILACSAT") { - $sat_name = "CAS-3H"; - } else { - $sat_name = strtoupper($row->sat_name); + // Check Mode + $mode = strtoupper($row->mode); + if ($mode == "FMN") { + $mode = "FM"; } - // Get Satellite Mode - $sat_mode_uplink = $this->get_mode_designator($row->frequency); - $sat_mode_downlink = $this->get_mode_designator($row->frequency_rx); + if ($row->prop_mode == "SAT") { + // Get Satellite Name + if ($row->sat_name == "AO-07") { + $sat_name = "AO-7"; + } elseif ($row->sat_name == "LILACSAT") { + $sat_name = "CAS-3H"; + } else { + $sat_name = strtoupper($row->sat_name); + } - if (empty($sat_mode_uplink)) { + // Get Satellite Mode + $sat_mode_uplink = $this->get_mode_designator($row->frequency); + $sat_mode_downlink = $this->get_mode_designator($row->frequency_rx); + + if (empty($sat_mode_uplink)) { + $sat_mode = ""; + } elseif ($sat_mode_uplink !== $sat_mode_downlink) { + $sat_mode = $sat_mode_uplink."/".$sat_mode_downlink; + } else { + $sat_mode = $sat_mode_uplink; + } + } else { + $sat_name = ""; $sat_mode = ""; - } elseif ($sat_mode_uplink !== $sat_mode_downlink) { - $sat_mode = $sat_mode_uplink."/".$sat_mode_downlink; - } else { - $sat_mode = $sat_mode_uplink; } - } else { - $sat_name = ""; - $sat_mode = ""; + + // Calculate how old the data is in minutes + $datetime1 = new DateTime("now", new DateTimeZone('UTC')); // Today's Date/Time + $datetime2 = new DateTime($row->timestamp, new DateTimeZone('UTC')); + $interval = $datetime1->diff($datetime2); + + $minutes = $interval->days * 24 * 60; + $minutes += $interval->h * 60; + $minutes += $interval->i; + + $updated_at = $minutes; + + // Return Json data + echo json_encode(array( + "frequency" => $frequency, + "frequency_rx" => $frequency_rx, + "mode" => $mode, + "satmode" => $sat_mode, + "satname" => $sat_name, + "power" => $power, + "prop_mode" => $prop_mode, + "updated_minutes_ago" => $updated_at, + ), JSON_PRETTY_PRINT); } - - // Calculate how old the data is in minutes - $datetime1 = new DateTime("now", new DateTimeZone('UTC')); // Today's Date/Time - $datetime2 = new DateTime($row->timestamp, new DateTimeZone('UTC')); - $interval = $datetime1->diff($datetime2); - - $minutes = $interval->days * 24 * 60; - $minutes += $interval->h * 60; - $minutes += $interval->i; - - $updated_at = $minutes; - - // Return Json data - echo json_encode(array( - "frequency" => $frequency, - "frequency_rx" => $frequency_rx, - "mode" => $mode, - "satmode" => $sat_mode, - "satname" => $sat_name, - "power" => $power, - "prop_mode" => $prop_mode, - "updated_minutes_ago" => $updated_at, - ), JSON_PRETTY_PRINT); } } } diff --git a/application/controllers/Update.php b/application/controllers/Update.php index 59c914de..cd56804c 100644 --- a/application/controllers/Update.php +++ b/application/controllers/Update.php @@ -189,7 +189,7 @@ class Update extends CI_Controller { gzclose($gz); if (file_put_contents($this->make_update_path("cty.xml"), $data) === FALSE) { - $this->update_status("FAILED: Could not write to LoTW users file"); + $this->update_status("FAILED: Could not write to cty.xml file"); return; } diff --git a/application/controllers/User.php b/application/controllers/User.php index 2d89e0ad..e713146c 100644 --- a/application/controllers/User.php +++ b/application/controllers/User.php @@ -33,6 +33,7 @@ class User extends CI_Controller { $this->load->model('user_model'); if(!$this->user_model->authorize(99)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); } + $this->load->model('bands'); $this->load->library('form_validation'); $this->form_validation->set_rules('user_name', 'Username', 'required'); @@ -46,6 +47,8 @@ class User extends CI_Controller { $this->form_validation->set_rules('user_locator', 'Locator', 'callback_check_locator'); $this->form_validation->set_rules('user_timezone', 'Timezone', 'required'); + $data['bands'] = $this->bands->get_user_bands(); + // Get themes list $data['themes'] = $this->user_model->getThemes(); @@ -69,8 +72,8 @@ class User extends CI_Controller { $data['user_callsign'] = $this->input->post('user_callsign'); $data['user_locator'] = $this->input->post('user_locator'); $data['user_timezone'] = $this->input->post('user_timezone'); - $data['user_measurement_base'] = $this->input->post('user_measurement_base'); - $data['user_stylesheet'] = $this->input->post('user_stylesheet'); + $data['user_measurement_base'] = $this->input->post('user_measurement_base'); + $data['user_stylesheet'] = $this->input->post('user_stylesheet'); $data['user_qth_lookup'] = $this->input->post('user_qth_lookup'); $data['user_sota_lookup'] = $this->input->post('user_sota_lookup'); $data['user_wwff_lookup'] = $this->input->post('user_wwff_lookup'); @@ -84,6 +87,9 @@ class User extends CI_Controller { $data['user_show_profile_image'] = $this->input->post('user_show_profile_image'); $data['user_previous_qsl_type'] = $this->input->post('user_previous_qsl_type'); $data['user_amsat_status_upload'] = $this->input->post('user_amsat_status_upload'); + $data['user_mastodon_url'] = $this->input->post('user_mastodon_url'); + $data['user_gridmap_default_band'] = $this->input->post('user_gridmap_default_band'); + $data['user_gridmap_confirmation'] = ($this->input->post('user_gridmap_confirmation_qsl') !== null ? 'Q' : '').($this->input->post('user_gridmap_confirmation_lotw') !== null ? 'L' : '').($this->input->post('user_gridmap_confirmation_eqsl') !== null ? 'E' : ''); $this->load->view('user/add', $data); } else { $this->load->view('user/add', $data); @@ -116,7 +122,10 @@ class User extends CI_Controller { $this->input->post('user_column5'), $this->input->post('user_show_profile_image'), $this->input->post('user_previous_qsl_type'), - $this->input->post('user_amsat_status_upload'))) { + $this->input->post('user_amsat_status_upload'), + $this->input->post('user_mastodon_url'), + $this->input->post('user_gridmap_default_band'), + ($this->input->post('user_gridmap_confirmation_qsl') !== null ? 'Q' : '').($this->input->post('user_gridmap_confirmation_lotw') !== null ? 'L' : '').($this->input->post('user_gridmap_confirmation_eqsl') !== null ? 'E' : ''))) { // Check for errors case EUSERNAMEEXISTS: $data['username_error'] = 'Username '.$this->input->post('user_name').' already in use!'; @@ -144,8 +153,8 @@ class User extends CI_Controller { $data['user_lastname'] = $this->input->post('user_lastname'); $data['user_callsign'] = $this->input->post('user_callsign'); $data['user_locator'] = $this->input->post('user_locator'); - $data['user_measurement_base'] = $this->input->post('user_measurement_base'); - $data['user_stylesheet'] = $this->input->post('user_stylesheet'); + $data['user_measurement_base'] = $this->input->post('user_measurement_base'); + $data['user_stylesheet'] = $this->input->post('user_stylesheet'); $data['user_qth_lookup'] = $this->input->post('user_qth_lookup'); $data['user_sota_lookup'] = $this->input->post('user_sota_lookup'); $data['user_wwff_lookup'] = $this->input->post('user_wwff_lookup'); @@ -159,6 +168,9 @@ class User extends CI_Controller { $data['user_show_profile_image'] = $this->input->post('user_show_profile_image'); $data['user_previous_qsl_type'] = $this->input->post('user_previous_qsl_type'); $data['user_amsat_status_upload'] = $this->input->post('user_amsat_status_upload'); + $data['user_mastodon_url'] = $this->input->post('user_mastodon_url'); + $data['user_gridmap_default_band'] = $this->input->post('user_gridmap_default_band'); + $data['user_gridmap_confirmation'] = ($this->input->post('user_gridmap_confirmation_qsl') !== null ? 'Q' : '').($this->input->post('user_gridmap_confirmation_lotw') !== null ? 'L' : '').($this->input->post('user_gridmap_confirmation_eqsl') !== null ? 'E' : ''); $this->load->view('user/add', $data); $this->load->view('interface_assets/footer'); } @@ -166,9 +178,10 @@ class User extends CI_Controller { function edit() { $this->load->model('user_model'); - if((!$this->user_model->authorize(99)) && ($this->session->userdata('user_id') != $this->uri->segment(3))) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); } + if ( ($this->session->userdata('user_id') == '') || ((!$this->user_model->authorize(99)) && ($this->session->userdata('user_id') != $this->uri->segment(3))) ) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); } $query = $this->user_model->get_by_id($this->uri->segment(3)); + $this->load->model('bands'); $this->load->library('form_validation'); $this->form_validation->set_rules('user_name', 'Username', 'required|xss_clean'); @@ -183,6 +196,8 @@ class User extends CI_Controller { $this->form_validation->set_rules('user_locator', 'Locator', 'callback_check_locator'); $this->form_validation->set_rules('user_timezone', 'Timezone', 'required'); + $data['bands'] = $this->bands->get_user_bands(); + // Get themes list $data['themes'] = $this->user_model->getThemes(); @@ -300,23 +315,23 @@ class User extends CI_Controller { $data['user_eqsl_password'] = $q->user_eqsl_password; } - if($this->input->post('user_measurement_base')) { - $data['user_measurement_base'] = $this->input->post('user_measurement_base', true); - } else { - $data['user_measurement_base'] = $q->user_measurement_base; - } + if($this->input->post('user_measurement_base')) { + $data['user_measurement_base'] = $this->input->post('user_measurement_base', true); + } else { + $data['user_measurement_base'] = $q->user_measurement_base; + } if($this->input->post('user_date_format')) { - $data['user_date_format'] = $this->input->post('user_date_format', true); - } else { - $data['user_date_format'] = $q->user_date_format; - } + $data['user_date_format'] = $this->input->post('user_date_format', true); + } else { + $data['user_date_format'] = $q->user_date_format; + } - if($this->input->post('user_stylesheet')) { - $data['user_stylesheet'] = $this->input->post('user_stylesheet', true); - } else { - $data['user_stylesheet'] = $q->user_stylesheet; - } + if($this->input->post('user_stylesheet')) { + $data['user_stylesheet'] = $this->input->post('user_stylesheet', true); + } else { + $data['user_stylesheet'] = $q->user_stylesheet; + } if($this->input->post('user_qth_lookup')) { $data['user_qth_lookup'] = $this->input->post('user_qth_lookup', true); @@ -366,6 +381,24 @@ class User extends CI_Controller { $data['user_amsat_status_upload'] = $q->user_amsat_status_upload; } + if($this->input->post('user_mastodon_url')) { + $data['user_mastodon_url'] = $this->input->post('user_mastodon_url', false); + } else { + $data['user_mastodon_url'] = $q->user_mastodon_url; + } + + if($this->input->post('user_gridmap_default_band')) { + $data['user_gridmap_default_band'] = $this->input->post('user_gridmap_default_band', false); + } else { + $data['user_gridmap_default_band'] = $q->user_gridmap_default_band; + } + + if($this->input->post('user_gridmap_confirmation')) { + $data['user_gridmap_confirmation'] = ($this->input->post('user_gridmap_confirmation_qsl') !== null ? 'Q' : '').($this->input->post('user_gridmap_confirmation_lotw') !== null ? 'L' : '').($this->input->post('user_gridmap_confirmation_eqsl') !== null ? 'E' : ''); + } else { + $data['user_gridmap_confirmation'] = $q->user_gridmap_confirmation; + } + if($this->input->post('user_column1')) { $data['user_column1'] = $this->input->post('user_column1', true); } else { @@ -436,7 +469,7 @@ class User extends CI_Controller { $data['user_callsign'] = $this->input->post('user_callsign', true); $data['user_locator'] = $this->input->post('user_locator', true); $data['user_timezone'] = $this->input->post('user_timezone', true); - $data['user_stylesheet'] = $this->input->post('user_stylesheet'); + $data['user_stylesheet'] = $this->input->post('user_stylesheet'); $data['user_qth_lookup'] = $this->input->post('user_qth_lookup'); $data['user_sota_lookup'] = $this->input->post('user_sota_lookup'); $data['user_wwff_lookup'] = $this->input->post('user_wwff_lookup'); @@ -451,6 +484,9 @@ class User extends CI_Controller { $data['user_show_profile_image'] = $this->input->post('user_show_profile_image'); $data['user_previous_qsl_type'] = $this->input->post('user_previous_qsl_type'); $data['user_amsat_status_upload'] = $this->input->post('user_amsat_status_upload'); + $data['user_mastodon_url'] = $this->input->post('user_mastodon_url'); + $data['user_gridmap_default_band'] = $this->input->post('user_gridmap_default_band'); + $data['user_gridmap_confirmation'] = ($this->input->post('user_gridmap_confirmation_qsl') !== null ? 'Q' : '').($this->input->post('user_gridmap_confirmation_lotw') !== null ? 'L' : '').($this->input->post('user_gridmap_confirmation_eqsl') !== null ? 'E' : ''); $this->load->view('user/edit'); $this->load->view('interface_assets/footer'); } @@ -458,6 +494,7 @@ class User extends CI_Controller { function profile() { $this->load->model('user_model'); + if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); } $query = $this->user_model->get_by_id($this->session->userdata('user_id')); $q = $query->row(); $data['page_title'] = "Profile"; diff --git a/application/controllers/Visitor.php b/application/controllers/Visitor.php index c7dd7f1d..f2864135 100644 --- a/application/controllers/Visitor.php +++ b/application/controllers/Visitor.php @@ -20,6 +20,9 @@ class Visitor extends CI_Controller { elseif($method == "satellites") { $this->satellites($method); } + elseif($method == "search") { + $this->search($method); + } else { $this->index($method); } @@ -452,4 +455,37 @@ class Visitor extends CI_Controller { return false; } } + + public function public_search_enabled($slug) { + $this->load->model('Logbooks_model'); + $logbook_id = $this->Logbooks_model->public_slug_exists_logbook_id($slug); + if ($this->Logbooks_model->public_search_enabled($logbook_id) == 1) { + return true; + } else { + return false; + } + } + + public function search() { + $callsign = trim($this->security->xss_clean($this->input->post('callsign'))); + $public_slug = $this->security->xss_clean($this->input->post('public_slug')); + $this->load->model('publicsearch'); + $data['page_title'] = "Public Search"; + $data['callsign'] = $callsign; + $data['slug'] = $public_slug; + if ($callsign != '') { + $result = $this->publicsearch->search($public_slug, $callsign); + } + if (!empty($result) && $result->num_rows() > 0) { + $data['results'] = $result; + $this->load->view('visitor/layout/header', $data); + $this->load->view('public_search/result.php', $data); + $this->load->view('visitor/layout/footer'); + } else { + $this->load->view('visitor/layout/header', $data); + $this->load->view('public_search/empty.php', $data); + $this->load->view('visitor/layout/footer'); + } + } + } diff --git a/application/language/bulgarian/lotw_lang.php b/application/language/bulgarian/lotw_lang.php index e70ba49c..975aa1de 100644 --- a/application/language/bulgarian/lotw_lang.php +++ b/application/language/bulgarian/lotw_lang.php @@ -31,7 +31,6 @@ $lang['lotw_upload_exported_adif_file_from_lotw'] = 'Upload the Exported ADIF fi $lang['lotw_upload_type_must_be_adi'] = 'Log files must have the file type .adi'; $lang['lotw_pull_lotw_data_for_me'] = 'Pull LoTW data for me'; -$lang['lotw_import_missing_qsos_text'] = 'Import missing QSOs into the log. Call and gridsquare will be checked to try to find the correct profile to import the QSO into. If not found, the QSO will be skipped.'; $lang['lotw_report_download_overview_helptext'] ='Cloudlog will use the LoTW username and password stored in your user profile to download a report from LoTW for you. The report Cloudlog downloads will have all confirmations since chosen date, or since your last LoTW confirmation (fetched from your log), up until now.'; diff --git a/application/language/chinese_simplified/lotw_lang.php b/application/language/chinese_simplified/lotw_lang.php index 30153d06..b1b25958 100644 --- a/application/language/chinese_simplified/lotw_lang.php +++ b/application/language/chinese_simplified/lotw_lang.php @@ -33,7 +33,6 @@ $lang['lotw_upload_exported_adif_file_from_lotw'] = '下载从 LoTW CI->eqslmethods_model->eqsl_dupe_check($time_on, $record['call'], $record['band'], $config['eqsl_rcvd_mark']); + $dupe = $this->CI->eqslmethods_model->eqsl_dupe_check($time_on, $record['call'], $record['band'], $record['mode'],$config['eqsl_rcvd_mark'],$station_callsign); if ($dupe == false) { $updated += 1; - $eqsl_status = $this->CI->eqslmethods_model->eqsl_update($time_on, $record['call'], $record['band'], $config['eqsl_rcvd_mark']); + $eqsl_status = $this->CI->eqslmethods_model->eqsl_update($time_on, $record['call'], $record['band'], $record['mode'], $config['eqsl_rcvd_mark'],$station_callsign); } else { $dupes += 1; $eqsl_status = "Already received an eQSL for this QSO."; diff --git a/application/migrations/125_lotw_enddates.php b/application/migrations/125_lotw_enddates.php new file mode 100644 index 00000000..e09e26d3 --- /dev/null +++ b/application/migrations/125_lotw_enddates.php @@ -0,0 +1,21 @@ +db->table_exists('lotw_certs')) { + $sql = 'UPDATE lotw_certs SET qso_end_date = DATE_ADD(qso_end_date, INTERVAL 24*60*60 -1 SECOND) WHERE TIME(qso_end_date) = "00:00:00";'; + $this->db->query($sql); + } + } + + public function down() + { + if ($this->db->table_exists('lotw_certs')) { + $sql = 'UPDATE lotw_certs SET qso_end_date = DATE_SUB(qso_end_date, INTERVAL 24*60*60 -1 SECOND) WHERE TIME(qso_end_date) = "23:59:59";'; + $this->db->query($sql); + } + } +} diff --git a/application/migrations/126_mastodon_url.php b/application/migrations/126_mastodon_url.php new file mode 100644 index 00000000..ec2a5992 --- /dev/null +++ b/application/migrations/126_mastodon_url.php @@ -0,0 +1,30 @@ +db->field_exists('user_mastodon_url', 'users')) { + $fields = array( + 'user_mastodon_url varchar(32) default NULL', + ); + $this->dbforge->add_column('users', $fields, 'user_column5'); + } + } + + public function down() + { + $this->dbforge->drop_column('users', 'user_mastodon_url'); + } +} + + + diff --git a/application/migrations/127_add_hrdlog_fields.php b/application/migrations/127_add_hrdlog_fields.php new file mode 100644 index 00000000..8d1cdf1c --- /dev/null +++ b/application/migrations/127_add_hrdlog_fields.php @@ -0,0 +1,42 @@ +db->field_exists('hrdlogrealtime', 'station_profile')) { + $fields = array( + 'hrdlogrealtime tinyint(1)' + ); + $this->dbforge->add_column('station_profile', $fields); + } + + if (!$this->db->field_exists('hrdlog_code', 'station_profile')) { + $fields = array( + 'hrdlog_code varchar(20) DEFAULT NULL', + ); + $this->dbforge->add_column('station_profile', $fields); + } + + if ( (!$this->db->field_exists('COL_HRDLOG_QSO_UPLOAD_DATE', $this->config->item('table_name'))) && + (!$this->db->field_exists('COL_HRDLOG_QSO_UPLOAD_STATUS', $this->config->item('table_name')))) { + $fields = array( + 'COL_HRDLOG_QSO_UPLOAD_DATE datetime default NULL', + 'COL_HRDLOG_QSO_UPLOAD_STATUS varchar(10) default NULL' + ); + $this->dbforge->add_column($this->config->item('table_name'), $fields); + } + } + + public function down() + { + if ($this->db->field_exists('hrdlogrealtime', 'station_profile')) { + $this->dbforge->drop_column('station_profile', 'hrdlogrealtime'); + } + if ($this->db->field_exists('hrdlog_code', 'station_profile')) { + $this->dbforge->drop_column('station_profile', 'hrdlog_code'); + } + } +} diff --git a/application/migrations/128_user_default_map_settings.php b/application/migrations/128_user_default_map_settings.php new file mode 100644 index 00000000..79bee0af --- /dev/null +++ b/application/migrations/128_user_default_map_settings.php @@ -0,0 +1,43 @@ +db->field_exists('user_gridmap_default_band', 'users')) { + $fields = array( + 'user_gridmap_default_band varchar(10) default NULL', + ); + $this->dbforge->add_column('users', $fields); + } + if (!$this->db->field_exists('user_gridmap_confirmation', 'users')) { + $fields = array( + 'user_gridmap_confirmation varchar(3) default NULL', + ); + $this->dbforge->add_column('users', $fields); + } + $data = array( + 'user_gridmap_default_band' => 'All', + 'user_gridmap_confirmation' => 'QL', + ); + $this->db->update('users', $data); + } + + public function down() + { + $this->dbforge->drop_column('users', 'user_gridmap_default_band'); + $this->dbforge->drop_column('users', 'user_gridmap_confirmation'); + } +} + + + diff --git a/application/migrations/129_add_public_search_option.php b/application/migrations/129_add_public_search_option.php new file mode 100644 index 00000000..c98841fb --- /dev/null +++ b/application/migrations/129_add_public_search_option.php @@ -0,0 +1,28 @@ +db->field_exists('public_search', 'station_logbooks')) { + $fields = array( + 'public_search integer DEFAULT 0 AFTER public_slug', + ); + + $this->dbforge->add_column('station_logbooks', $fields); + } + } + + public function down() + { + if ($this->db->field_exists('public_search', 'logbooks')) { + $this->dbforge->drop_column('logbooks', 'public_search'); + } + } +} diff --git a/application/migrations/130_add_version_to_config.php b/application/migrations/130_add_version_to_config.php new file mode 100644 index 00000000..968377e0 --- /dev/null +++ b/application/migrations/130_add_version_to_config.php @@ -0,0 +1,25 @@ + "version", 'option_value' => "2.4.5", 'autoload' => "yes"), + ); + + $this->db->insert_batch('options', $data); + } + + public function down() + { + // No option to down + } +} \ No newline at end of file diff --git a/application/models/Eqslmethods_model.php b/application/models/Eqslmethods_model.php index 369a4117..5ad652dd 100644 --- a/application/models/Eqslmethods_model.php +++ b/application/models/Eqslmethods_model.php @@ -156,7 +156,7 @@ class Eqslmethods_model extends CI_Model { // Update a QSO with eQSL QSL info // We could also probably use this use this: http://eqsl.cc/qslcard/VerifyQSO.txt // http://www.eqsl.cc/qslcard/ImportADIF.txt - function eqsl_update($datetime, $callsign, $band, $qsl_status) { + function eqsl_update($datetime, $callsign, $band, $mode, $qsl_status,$station_callsign) { $data = array( 'COL_EQSL_QSLRDATE' => date('Y-m-d H:i:s'), // eQSL doesn't give us a date, so let's use current 'COL_EQSL_QSL_RCVD' => $qsl_status @@ -165,7 +165,9 @@ class Eqslmethods_model extends CI_Model { $this->db->where('COL_TIME_ON >= DATE_ADD(DATE_FORMAT("'.$datetime.'", \'%Y-%m-%d %H:%i\' ), INTERVAL -15 MINUTE )'); $this->db->where('COL_TIME_ON <= DATE_ADD(DATE_FORMAT("'.$datetime.'", \'%Y-%m-%d %H:%i\' ), INTERVAL 15 MINUTE )'); $this->db->where('COL_CALL', $callsign); + $this->db->where('COL_STATION_CALLSIGN', $station_callsign); $this->db->where('COL_BAND', $band); + $this->db->where('COL_MODE', $mode); $this->db->update($this->config->item('table_name'), $data); @@ -173,12 +175,14 @@ class Eqslmethods_model extends CI_Model { } // Determine if we've already received an eQSL for this QSO - function eqsl_dupe_check($datetime, $callsign, $band, $qsl_status) { + function eqsl_dupe_check($datetime, $callsign, $band, $mode, $qsl_status,$station_callsign) { $this->db->select('COL_EQSL_QSLRDATE'); $this->db->where('COL_TIME_ON >= DATE_ADD(DATE_FORMAT("'.$datetime.'", \'%Y-%m-%d %H:%i\' ), INTERVAL -15 MINUTE )'); $this->db->where('COL_TIME_ON <= DATE_ADD(DATE_FORMAT("'.$datetime.'", \'%Y-%m-%d %H:%i\' ), INTERVAL 15 MINUTE )'); $this->db->where('COL_CALL', $callsign); $this->db->where('COL_BAND', $band); + $this->db->where('COL_MODE', $mode); + $this->db->where('COL_STATION_CALLSIGN', $station_callsign); $this->db->where('COL_EQSL_QSL_RCVD', $qsl_status); $this->db->limit(1); diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index 71e7ac28..06c4b7eb 100755 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -252,6 +252,10 @@ class Logbook_model extends CI_Model { $data['COL_MY_GRIDSQUARE'] = strtoupper(trim($station['station_gridsquare'])); } + if ($this->exists_hrdlog_code($station_id)) { + $data['COL_HRDLOG_QSO_UPLOAD_STATUS'] = 'N'; + } + if ($this->exists_qrz_api_key($station_id)) { $data['COL_QRZCOM_QSO_UPLOAD_STATUS'] = 'N'; } @@ -292,6 +296,16 @@ class Logbook_model extends CI_Model { $this->add_qso($data, $skipexport = false); } + public function check_last_lotw($call){ // Fetch difference in days when $call has last updated LotW + + $sql="select datediff(now(),lastupload) as DAYS from lotw_users where callsign = ?"; // Use binding to prevent SQL-injection + $query = $this->db->query($sql, $call); + $row = $query->row(); + if (isset($row)) { + return($row->DAYS); + } + } + public function check_station($id){ $this->db->select('station_profile.*, dxcc_entities.name as station_country'); @@ -506,12 +520,26 @@ class Logbook_model extends CI_Model { $this->upload_amsat_status($data); } - // No point in fetching qrz api key and qrzrealtime setting if we're skipping the export + // No point in fetching hrdlog code or qrz api key and qrzrealtime setting if we're skipping the export if (!$skipexport) { - $result = $this->exists_qrz_api_key($data['station_id']); - // Push qso to qrz if apikey is set, and realtime upload is enabled, and we're not importing an adif-file + $result = $this->exists_hrdlog_code($data['station_id']); + // Push qso to hrdlog if code is set, and realtime upload is enabled, and we're not importing an adif-file + if (isset($result->hrdlog_code) && $result->hrdlogrealtime == 1) { + $CI =& get_instance(); + $CI->load->library('AdifHelper'); + $qso = $this->get_qso($last_id)->result(); + + $adif = $CI->adifhelper->getAdifLine($qso[0]); + $result = $this->push_qso_to_hrdlog($result->hrdlog_code, $data['COL_STATION_CALLSIGN'], $adif); + if ( ($result['status'] == 'OK') || ( ($result['status'] == 'error') || ($result['status'] == 'duplicate') || ($result['status'] == 'auth_error') )){ + $this->mark_hrdlog_qsos_sent($last_id); + } + } + $result = ''; // Empty result from previous hrdlog-attempt for safety + $result = $this->exists_qrz_api_key($data['station_id']); +// Push qso to qrz if apikey is set, and realtime upload is enabled, and we're not importing an adif-file if (isset($result->qrzapikey) && $result->qrzrealtime == 1) { $CI =& get_instance(); $CI->load->library('AdifHelper'); @@ -519,7 +547,7 @@ class Logbook_model extends CI_Model { $adif = $CI->adifhelper->getAdifLine($qso[0]); $result = $this->push_qso_to_qrz($result->qrzapikey, $adif); - if ($result['status'] == 'OK') { + if ( ($result['status'] == 'OK') || ( ($result['status'] == 'error') && ($result['message'] == 'STATUS=FAIL&REASON=Unable to add QSO to database: duplicate&EXTENDED=')) ){ $this->mark_qrz_qsos_sent($last_id); } } @@ -545,6 +573,24 @@ class Logbook_model extends CI_Model { } } + /* + * Function checks if a HRDLog Code exists in the table with the given station id + */ + function exists_hrdlog_code($station_id) { + $sql = 'select hrdlog_code, hrdlogrealtime from station_profile + where station_id = ' . $station_id; + + $query = $this->db->query($sql); + + $result = $query->row(); + + if ($result) { + return $result; + } else { + return false; + } + } + /* * Function checks if a QRZ API Key exists in the table with the given station id */ @@ -583,6 +629,59 @@ class Logbook_model extends CI_Model { } } + /* + * Function uploads a QSO to HRDLog with the API given. + * $adif contains a line with the QSO in the ADIF format. QSO ends with an + */ + function push_qso_to_hrdlog($apikey, $station_callsign, $adif, $replaceoption = false) { + $url = 'https://robot.hrdlog.net/newentry.aspx'; + + $post_data['Code'] = $apikey; + if ($replaceoption) { + $post_data['Cmd'] = 'UPDATE'; + $post_data['ADIFKey'] = $adif; + } + $post_data['ADIFData'] = $adif; + + $post_data['Callsign'] = $station_callsign; + + + $post_encoded=http_build_query($post_data); + + $ch = curl_init( $url ); + curl_setopt( $ch, CURLOPT_POST, true); + curl_setopt( $ch, CURLOPT_POSTFIELDS, $post_encoded); + curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt( $ch, CURLOPT_HEADER, 0); + curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); + $content = curl_exec($ch); + if ($content){ + if (stristr($content,'1')) { + $result['status'] = 'OK'; + return $result; + } elseif (stristr($content,'0')) { + $result['status'] = 'duplicate'; + $result['message'] = $content; + return $result; + } elseif (stristr($content,'Unknown user')) { + $result['status'] = 'auth_error'; + $result['message'] = $content; + return $result; + } else { + $result['status'] = 'error'; + $result['message'] = $content; + return $result; + } + } + if(curl_errno($ch)){ + $result['status'] = 'error'; + $result['message'] = 'Curl error: '. curl_errno($ch); + return $result; + } + curl_close($ch); + } + /* * Function uploads a QSO to QRZ with the API given. * $adif contains a line with the QSO in the ADIF format. QSO ends with an @@ -655,6 +754,23 @@ class Logbook_model extends CI_Model { return $response === 200; } + /* + * Function marks QSOs as uploaded to HRDLog. + * $primarykey is the unique id for that QSO in the logbook + */ + function mark_hrdlog_qsos_sent($primarykey) { + $data = array( + 'COL_HRDLOG_QSO_UPLOAD_DATE' => date("Y-m-d H:i:s", strtotime("now")), + 'COL_HRDLOG_QSO_UPLOAD_STATUS' => 'Y', + ); + + $this->db->where('COL_PRIMARY_KEY', $primarykey); + + $this->db->update($this->config->item('table_name'), $data); + + return true; + } + /* * Function marks QSOs as uploaded to QRZ. * $primarykey is the unique id for that QSO in the logbook @@ -694,10 +810,10 @@ class Logbook_model extends CI_Model { $sat_name = ''; if ($data['COL_SAT_NAME'] == 'AO-7') { if ($data['COL_BAND'] == '2m' && $data['COL_BAND_RX'] == '10m') { - $sat_name = '[A]_AO-7'; + $sat_name = 'AO-7[A]'; } if ($data['COL_BAND'] == '70cm' && $data['COL_BAND_RX'] == '2m') { - $sat_name = '[B]_AO-7'; + $sat_name = 'AO-7[B]'; } } else if ($data['COL_SAT_NAME'] == 'QO-100') { $sat_name = 'QO-100_NB'; @@ -940,6 +1056,10 @@ class Logbook_model extends CI_Model { 'COL_CNTY' => $uscounty ); + if ($this->exists_hrdlog_code($data['station_id'])) { + $data['COL_HRDLOG_QSO_UPLOAD_STATUS'] = 'M'; + } + if ($this->exists_qrz_api_key($data['station_id'])) { $data['COL_QRZCOM_QSO_UPLOAD_STATUS'] = 'M'; } @@ -1204,7 +1324,8 @@ class Logbook_model extends CI_Model { $data = array( 'COL_QSLSDATE' => date('Y-m-d H:i:s'), - 'COL_QSL_SENT' => 'R' + 'COL_QSL_SENT' => 'R', + 'COL_QSL_SENT_VIA' => $method ); $this->db->where('COL_PRIMARY_KEY', $qso_id); @@ -1311,6 +1432,23 @@ class Logbook_model extends CI_Model { return $this->db->get(); } + /* + * Function returns the QSOs from the logbook, which have not been either marked as uploaded to hrdlog, or has been modified with an edit + */ + function get_hrdlog_qsos($station_id){ + $sql = 'select *, dxcc_entities.name as station_country from ' . $this->config->item('table_name') . ' thcv ' . + ' left join station_profile on thcv.station_id = station_profile.station_id' . + ' left outer join dxcc_entities on thcv.col_my_dxcc = dxcc_entities.adif' . + ' where thcv.station_id = ' . $station_id . + ' and (COL_HRDLOG_QSO_UPLOAD_STATUS is NULL + or COL_HRDLOG_QSO_UPLOAD_STATUS = "" + or COL_HRDLOG_QSO_UPLOAD_STATUS = "M" + or COL_HRDLOG_QSO_UPLOAD_STATUS = "N")'; + + $query = $this->db->query($sql); + return $query; + } + /* * Function returns the QSOs from the logbook, which have not been either marked as uploaded to qrz, or has been modified with an edit */ @@ -1371,6 +1509,25 @@ class Logbook_model extends CI_Model { return $this->db->query($sql); } + /* + * Function returns all the station_id's with HRDLOG Code + */ + function get_station_id_with_hrdlog_code() { + $sql = 'select station_id, hrdlog_code from station_profile + where coalesce(hrdlog_code, "") <> ""'; + + $query = $this->db->query($sql); + + $result = $query->result(); + + if ($result) { + return $result; + } + else { + return null; + } + } + /* * Function returns all the station_id's with QRZ API Key's */ @@ -2469,13 +2626,15 @@ class Logbook_model extends CI_Model { } /* Used to check if the qso is already in the database */ - function import_check($datetime, $callsign, $band) { + function import_check($datetime, $callsign, $band, $mode, $station_callsign) { $this->db->select('COL_PRIMARY_KEY, COL_TIME_ON, COL_CALL, COL_BAND'); $this->db->where('COL_TIME_ON >= DATE_ADD(DATE_FORMAT("'.$datetime.'", \'%Y-%m-%d %H:%i\' ), INTERVAL -15 MINUTE )'); $this->db->where('COL_TIME_ON <= DATE_ADD(DATE_FORMAT("'.$datetime.'", \'%Y-%m-%d %H:%i\' ), INTERVAL 15 MINUTE )'); $this->db->where('COL_CALL', $callsign); + $this->db->where('COL_STATION_CALLSIGN', $station_callsign); $this->db->where('COL_BAND', $band); + $this->db->where('COL_MODE', $mode); $query = $this->db->get($this->config->item('table_name')); @@ -2488,7 +2647,7 @@ class Logbook_model extends CI_Model { } } - function lotw_update($datetime, $callsign, $band, $qsl_date, $qsl_status, $state, $qsl_gridsquare, $iota, $cnty, $cqz, $ituz) { + function lotw_update($datetime, $callsign, $band, $qsl_date, $qsl_status, $state, $qsl_gridsquare, $qsl_vucc_grids, $iota, $cnty, $cqz, $ituz, $station_callsign) { $data = array( 'COL_LOTW_QSLRDATE' => $qsl_date, @@ -2517,48 +2676,39 @@ class Logbook_model extends CI_Model { $this->db->where('date_format(COL_TIME_ON, \'%Y-%m-%d %H:%i\') = "'.$datetime.'"'); $this->db->where('COL_CALL', $callsign); $this->db->where('COL_BAND', $band); + $this->db->where('COL_STATION_CALLSIGN', $station_callsign); $this->db->update($this->config->item('table_name'), $data); unset($data); - if($qsl_gridsquare != "") { + if($qsl_gridsquare != "" || $qsl_vucc_grids != "") { $data = array( - 'COL_GRIDSQUARE' => $qsl_gridsquare, 'COL_DISTANCE' => 0 ); - $this->db->select('station_profile.station_gridsquare as station_gridsquare'); - $this->db->where('date_format(COL_TIME_ON, \'%Y-%m-%d %H:%i\') = "'.$datetime.'"'); - $this->db->where('COL_CALL', $callsign); - $this->db->where('COL_BAND', $band); - $this->db->join('station_profile', $this->config->item('table_name').'.station_id = station_profile.station_id', 'left outer'); - $this->db->limit(1); - $query = $this->db->get($this->config->item('table_name')); - $row = $query->row(); - if (isset($row)) { - $station_gridsquare = $row->station_gridsquare; + $this->db->select('station_profile.station_gridsquare as station_gridsquare'); + $this->db->where('date_format(COL_TIME_ON, \'%Y-%m-%d %H:%i\') = "'.$datetime.'"'); + $this->db->where('COL_CALL', $callsign); + $this->db->where('COL_BAND', $band); + $this->db->join('station_profile', $this->config->item('table_name').'.station_id = station_profile.station_id', 'left outer'); + $this->db->limit(1); + $query = $this->db->get($this->config->item('table_name')); + $row = $query->row(); + $station_gridsquare = ''; + if (isset($row)) { + $station_gridsquare = $row->station_gridsquare; + } $this->load->library('Qra'); - - $data['COL_DISTANCE'] = $this->qra->distance($station_gridsquare, $qsl_gridsquare, 'K'); + if ($qsl_gridsquare != "") { + $data['COL_GRIDSQUARE'] = $qsl_gridsquare; + $data['COL_DISTANCE'] = $this->qra->distance($station_gridsquare, $qsl_gridsquare, 'K'); + } elseif ($qsl_vucc_grids != "") { + $data['COL_VUCC_GRIDS'] = $qsl_vucc_grids; + $data['COL_DISTANCE'] = $this->qra->distance($station_gridsquare, $qsl_vucc_grids, 'K'); } $this->db->where('date_format(COL_TIME_ON, \'%Y-%m-%d %H:%i\') = "'.$datetime.'"'); $this->db->where('COL_CALL', $callsign); $this->db->where('COL_BAND', $band); - $this->db->group_start(); - $this->db->where('COL_VUCC_GRIDS'); - $this->db->or_where('COL_VUCC_GRIDS', ''); - $this->db->group_end(); - if(strlen($qsl_gridsquare) > 4) { - $this->db->group_start(); - $this->db->where('COL_GRIDSQUARE', ""); - $this->db->or_where('COL_GRIDSQUARE', substr($qsl_gridsquare, 0, 4)); - if(strlen($qsl_gridsquare) > 6) { - $this->db->or_where('COL_GRIDSQUARE', substr($qsl_gridsquare, 0, 6)); - } - $this->db->group_end(); - } else { - $this->db->where('COL_GRIDSQUARE', ""); - } $this->db->update($this->config->item('table_name'), $data); } @@ -2566,30 +2716,29 @@ class Logbook_model extends CI_Model { return "Updated"; } - function lotw_last_qsl_date() { - $this->db->select('COL_LOTW_QSLRDATE'); - $this->db->where('COL_LOTW_QSLRDATE IS NOT NULL'); - $this->db->order_by("COL_LOTW_QSLRDATE", "desc"); - $this->db->limit(1); + function lotw_last_qsl_date($user_id) { + $sql="SELECT MAX(COALESCE(COL_LOTW_QSLRDATE, '1900-01-01 00:00:00')) MAXDATE + FROM ".$this->config->item('table_name')." INNER JOIN station_profile ON (".$this->config->item('table_name').".station_id = station_profile.station_id) + WHERE station_profile.user_id=".$user_id." and COL_LOTW_QSLRDATE is not null"; + $query = $this->db->query($sql); + $row = $query->row(); - $query = $this->db->get($this->config->item('table_name')); - $row = $query->row(); + if (isset($row)) { + return $row->MAXDATE; + } - if (isset($row)) { - return $row->COL_LOTW_QSLRDATE; - } - - return '1900-01-01 00:00:00.000'; - } + return '1900-01-01 00:00:00.000'; + } /* * $skipDuplicate - used in ADIF import to skip duplicate checking when importing QSOs * $markLoTW - used in ADIF import to mark QSOs as exported to LoTW when importing QSOs * $dxccAdif - used in ADIF import to determine if DXCC From ADIF is used, or if Cloudlog should try to guess * $markQrz - used in ADIF import to mark QSOs as exported to QRZ Logbook when importing QSOs + * $markHrd - used in ADIF import to mark QSOs as exported to HRDLog.net Logbook when importing QSOs * $skipexport - used in ADIF import to skip the realtime upload to QRZ Logbook when importing QSOs from ADIF */ - function import($record, $station_id = "0", $skipDuplicate = false, $markLotw = false, $dxccAdif = false, $markQrz = false, $skipexport = false, $operatorName = false, $apicall = false) { + function import($record, $station_id = "0", $skipDuplicate = false, $markLotw = false, $dxccAdif = false, $markQrz = false, $markHrd = false,$skipexport = false, $operatorName = false, $apicall = false) { // be sure that station belongs to user $CI =& get_instance(); $CI->load->model('Stations'); @@ -2597,6 +2746,12 @@ class Logbook_model extends CI_Model { return 'Station not accessible
'; } + $station_profile=$CI->Stations->profile_clean($station_id); + $station_profile_call=$station_profile->station_callsign; + if (($station_id != 0) && ($record['station_callsign'] != $station_profile_call)) { // Check if station_call from import matches profile ONLY when submitting via GUI. + return "Wrong station_callsign ".$record['station_callsign']." while importing QSO with ".$record['call']." for ".$station_profile_call; + } + $CI =& get_instance(); $CI->load->library('frequency'); $my_error = ""; @@ -2928,12 +3083,19 @@ class Logbook_model extends CI_Model { $operatorName = (!empty($record['operator'])) ? $record['operator'] : ''; } - // If user checked to mark QSOs as uploaded to QRZ Logbook, or else we try to find info in ADIF import. + // If user checked to mark QSOs as uploaded to QRZ or HRDLog Logbook, or else we try to find info in ADIF import. + if ($markHrd != null) { + $input_hrdlog_qso_upload_status = 'Y'; + $input_hrdlog_qso_upload_date = $date = date("Y-m-d H:i:s", strtotime("now")); + } + if ($markQrz != null) { $input_qrzcom_qso_upload_status = 'Y'; $input_qrzcom_qso_upload_date = $date = date("Y-m-d H:i:s", strtotime("now")); } else { + $input_hrdlog_qso_upload_date = (!empty($record['hrdlog_qso_upload_date'])) ? $record['hrdlog_qso_upload_date'] : null; + $input_hrdlog_qso_upload_status = (!empty($record['hrdlog_qso_upload_status'])) ? $record['hrdlog_qso_upload_status'] : ''; $input_qrzcom_qso_upload_date = (!empty($record['qrzcom_qso_upload_date'])) ? $record['qrzcom_qso_upload_date'] : null; $input_qrzcom_qso_upload_status = (!empty($record['qrzcom_qso_upload_status'])) ? $record['qrzcom_qso_upload_status'] : ''; } @@ -3049,6 +3211,8 @@ class Logbook_model extends CI_Model { 'COL_PRECEDENCE' => (!empty($record['precedence'])) ? $record['precedence'] : '', 'COL_PROP_MODE' => (!empty($record['prop_mode'])) ? $record['prop_mode'] : '', 'COL_PUBLIC_KEY' => (!empty($record['public_key'])) ? $record['public_key'] : '', + 'COL_HRDLOG_QSO_UPLOAD_DATE' => $input_hrdlog_qso_upload_date, + 'COL_HRDLOG_QSO_UPLOAD_STATUS' => $input_hrdlog_qso_upload_status, 'COL_QRZCOM_QSO_UPLOAD_DATE' => $input_qrzcom_qso_upload_date, 'COL_QRZCOM_QSO_UPLOAD_STATUS' => $input_qrzcom_qso_upload_status, 'COL_QSL_RCVD' => $input_qsl_rcvd, @@ -3763,28 +3927,6 @@ class Logbook_model extends CI_Model { return $query->result(); } - /* - * This function tries to locate the correct station_id used for importing QSOs from the downloaded LoTWreport - * $station_callsign is the call listed for the qso in lotwreport - * $my_gridsquare is the gridsquare listed for the qso in lotwreport - * Returns station_id if found - */ - function find_correct_station_id($station_callsign, $my_gridsquare) { - $sql = 'select station_id from station_profile - where station_callsign = "' . $station_callsign . '" and station_gridsquare like "%' . substr($my_gridsquare,0, 4) . '%"'; - - $query = $this->db->query($sql); - - $result = $query->row(); - - if ($result) { - return $result->station_id; - } - else { - return null; - } - } - function get_lotw_qsos_to_upload($station_id, $start_date, $end_date) { $this->db->select('COL_PRIMARY_KEY,COL_CALL, COL_BAND, COL_BAND_RX, COL_TIME_ON, COL_RST_RCVD, COL_RST_SENT, COL_MODE, COL_SUBMODE, COL_FREQ, COL_FREQ_RX, COL_GRIDSQUARE, COL_SAT_NAME, COL_PROP_MODE, COL_LOTW_QSL_SENT, station_id'); diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php index 490450cf..c6cfe6d4 100644 --- a/application/models/Logbookadvanced_model.php +++ b/application/models/Logbookadvanced_model.php @@ -56,6 +56,24 @@ class Logbookadvanced_model extends CI_Model { $binding[] = $searchCriteria['qslReceived']; } + if ($searchCriteria['lotwSent'] !== '') { + $conditions[] = "COL_LOTW_QSL_SENT = ?"; + $binding[] = $searchCriteria['lotwSent']; + } + if ($searchCriteria['lotwReceived'] !== '') { + $conditions[] = "COL_LOTW_QSL_RCVD = ?"; + $binding[] = $searchCriteria['lotwReceived']; + } + + if ($searchCriteria['eqslSent'] !== '') { + $conditions[] = "COL_EQSL_QSL_SENT = ?"; + $binding[] = $searchCriteria['eqslSent']; + } + if ($searchCriteria['eqslReceived'] !== '') { + $conditions[] = "COL_EQSL_QSL_RCVD = ?"; + $binding[] = $searchCriteria['eqslReceived']; + } + if ($searchCriteria['iota'] !== '') { $conditions[] = "COL_IOTA = ?"; $binding[] = $searchCriteria['iota']; @@ -71,6 +89,31 @@ class Logbookadvanced_model extends CI_Model { $binding[] = $searchCriteria['state']; } + if ($searchCriteria['cqzone'] !== '') { + $conditions[] = "COL_CQZ = ?"; + $binding[] = $searchCriteria['cqzone']; + } + + if ($searchCriteria['qslvia'] !== '') { + $conditions[] = "COL_QSL_VIA like ?"; + $binding[] = $searchCriteria['qslvia'].'%'; + } + + if ($searchCriteria['sota'] !== '') { + $conditions[] = "COL_SOTA_REF like ?"; + $binding[] = $searchCriteria['sota'].'%'; + } + + if ($searchCriteria['pota'] !== '') { + $conditions[] = "COL_POTA_REF like ?"; + $binding[] = $searchCriteria['pota'].'%'; + } + + if ($searchCriteria['wwff'] !== '') { + $conditions[] = "COL_WWFF_REF like ?"; + $binding[] = $searchCriteria['wwff'].'%'; + } + if ($searchCriteria['gridsquare'] !== '') { $conditions[] = "(COL_GRIDSQUARE like ? or COL_VUCC_GRIDS like ?)"; $binding[] = '%' . $searchCriteria['gridsquare'] . '%'; @@ -101,6 +144,11 @@ class Logbookadvanced_model extends CI_Model { INNER JOIN station_profile ON qsos.station_id=station_profile.station_id LEFT OUTER JOIN dxcc_entities ON qsos.col_dxcc=dxcc_entities.adif LEFT OUTER JOIN lotw_users ON qsos.col_call=lotw_users.callsign + LEFT OUTER JOIN ( + select count(*) as qslcount, qsoid + from qsl_images + group by qsoid + ) x on qsos.COL_PRIMARY_KEY = x.qsoid WHERE station_profile.user_id = ? $where ORDER BY qsos.COL_TIME_ON desc, qsos.COL_PRIMARY_KEY desc @@ -110,12 +158,12 @@ class Logbookadvanced_model extends CI_Model { $data = $this->db->query($sql, $binding); $results = $data->result('array'); - + $qsos = []; foreach ($results as $data) { $qsos[] = new QSO($data); } - + return $qsos; } @@ -132,12 +180,17 @@ class Logbookadvanced_model extends CI_Model { $order = $this->getSortorder($sortorder); $sql = " - SELECT qsos.*, d2.*, lotw_users.*, station_profile.*, dxcc_entities.name AS station_country + SELECT qsos.*, d2.*, lotw_users.*, station_profile.*, x.qslcount, dxcc_entities.name AS station_country FROM " . $this->config->item('table_name') . " qsos INNER JOIN station_profile ON qsos.station_id = station_profile.station_id LEFT OUTER JOIN dxcc_entities ON qsos.COL_MY_DXCC = dxcc_entities.adif LEFT OUTER JOIN dxcc_entities d2 ON qsos.COL_DXCC = d2.adif LEFT OUTER JOIN lotw_users ON qsos.col_call=lotw_users.callsign + LEFT OUTER JOIN ( + select count(*) as qslcount, qsoid + from qsl_images + group by qsoid + ) x on qsos.COL_PRIMARY_KEY = x.qsoid WHERE station_profile.user_id = ? $where $order @@ -212,7 +265,7 @@ class Logbookadvanced_model extends CI_Model { ); $this->db->where_in('COL_PRIMARY_KEY', json_decode($ids, true)); $this->db->update($this->config->item('table_name'), $data); - + return array('message' => 'OK'); } } @@ -230,7 +283,7 @@ class Logbookadvanced_model extends CI_Model { ); $this->db->where_in('COL_PRIMARY_KEY', json_decode($ids, true)); $this->db->update($this->config->item('table_name'), $data); - + return array('message' => 'OK'); } } @@ -282,19 +335,19 @@ class Logbookadvanced_model extends CI_Model { $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; } $modes = array(); - + $this->db->select('distinct col_mode, coalesce(col_submode, "") col_submode', FALSE); $this->db->where_in('station_id', $logbooks_locations_array); $this->db->order_by('col_mode, col_submode', 'ASC'); $query = $this->db->get($this->config->item('table_name')); - + foreach($query->result() as $mode){ if ($mode->col_submode == null || $mode->col_submode == "") { array_push($modes, $mode->col_mode); diff --git a/application/models/Logbooks_model.php b/application/models/Logbooks_model.php index 87753953..8b4ce1c3 100644 --- a/application/models/Logbooks_model.php +++ b/application/models/Logbooks_model.php @@ -210,6 +210,16 @@ class Logbooks_model extends CI_Model { } } + function save_public_search($public_search, $logbook_id) { + $data = array( + 'public_search' => xss_clean($public_search), + ); + + $this->db->where('user_id', $this->session->userdata('user_id')); + $this->db->where('logbook_id', xss_clean($logbook_id)); + $this->db->update('station_logbooks', $data); + } + function save_public_slug($public_slug, $logbook_id) { $data = array( 'public_slug' => xss_clean($public_slug), @@ -322,5 +332,14 @@ class Logbooks_model extends CI_Model { return 0; } } + + function public_search_enabled($logbook_id) { + $this->db->select('public_search'); + $this->db->where('logbook_id', $logbook_id); + + $query = $this->db->get('station_logbooks'); + + return $query->result_array()[0]['public_search']; + } } ?> diff --git a/application/models/LotwCert.php b/application/models/LotwCert.php index 1d1fd03d..1dab4515 100644 --- a/application/models/LotwCert.php +++ b/application/models/LotwCert.php @@ -6,7 +6,7 @@ class LotwCert extends CI_Model { |-------------------------------------------------------------------------- | Function: lotw_certs |-------------------------------------------------------------------------- - | + | | Returns all lotw_certs for a selected user via the $user_id parameter | */ @@ -17,7 +17,7 @@ class LotwCert extends CI_Model { $this->db->join('dxcc_entities','lotw_certs.cert_dxcc_id = dxcc_entities.adif','left'); $this->db->order_by('cert_dxcc', 'ASC'); $query = $this->db->get('lotw_certs'); - + return $query; } @@ -46,7 +46,7 @@ class LotwCert extends CI_Model { 'date_created' => $date_created, 'date_expires' => $date_expires, 'qso_start_date' => $qso_start_date, - 'qso_end_date' => $qso_end_date, + 'qso_end_date' => $qso_end_date . ' 23:59:59', 'cert_key' => $cert_key, 'cert' => $general_cert, ); @@ -60,7 +60,7 @@ class LotwCert extends CI_Model { 'date_created' => $date_created, 'date_expires' => $date_expires, 'qso_start_date' => $qso_start_date, - 'qso_end_date' => $qso_end_date, + 'qso_end_date' => $qso_end_date . ' 23:59:59', 'cert_key' => $cert_key, 'cert' => $general_cert ); @@ -90,9 +90,9 @@ class LotwCert extends CI_Model { return "Updated"; } - + function empty_table($table) { - $this->db->empty_table($table); + $this->db->empty_table($table); } function lotw_cert_expired($user_id, $date) { diff --git a/application/models/Pota.php b/application/models/Pota.php index 117a8c42..1c5c8a40 100644 --- a/application/models/Pota.php +++ b/application/models/Pota.php @@ -15,6 +15,8 @@ class Pota extends CI_Model { $bandslots = $this->bands->get_worked_bands('pota'); + if(!$bandslots) return null; + $this->db->where_in("station_id", $logbooks_locations_array); $this->db->where_in("col_band", $bandslots); $this->db->order_by("COL_POTA_REF", "ASC"); diff --git a/application/models/Publicsearch.php b/application/models/Publicsearch.php new file mode 100644 index 00000000..304f3d11 --- /dev/null +++ b/application/models/Publicsearch.php @@ -0,0 +1,38 @@ +public_search_enabled($slug)) { + $userid = $this->get_userid_for_slug($slug); + $this->db->like('COL_CALL', $callsign); + $this->db->join('station_profile', 'station_profile.station_id = '.$this->config->item('table_name').'.station_id'); + $this->db->join('lotw_users', 'lotw_users.callsign = '.$this->config->item('table_name').'.col_call', 'left outer'); + $this->db->where('station_profile.user_id', $userid); + $this->db->order_by('COL_TIME_ON', 'DESC'); + $query = $this->db->get($this->config->item('table_name')); + return $query; + } + return false; + } + + function get_userid_for_slug($slug) { + $this->db->select('user_id'); + $this->db->where('public_slug', $slug); + $query = $this->db->get('station_logbooks'); + return $query->result_array()[0]['user_id']; + } + + function public_search_enabled($slug) { + $this->db->select('public_search'); + $this->db->where('public_slug', $slug); + $query = $this->db->get('station_logbooks'); + if ($query->result_array()[0]['public_search'] == 1) { + return true; + } + return false; + } + +} + +?> diff --git a/application/models/Sota.php b/application/models/Sota.php index 6d47334e..46d7e5f5 100644 --- a/application/models/Sota.php +++ b/application/models/Sota.php @@ -15,6 +15,8 @@ class Sota extends CI_Model { $bandslots = $this->bands->get_worked_bands('sota'); + if(!$bandslots) return null; + $this->db->where_in("station_id", $logbooks_locations_array); $this->db->where_in("col_band", $bandslots); $this->db->order_by("COL_SOTA_REF", "ASC"); diff --git a/application/models/Stations.php b/application/models/Stations.php index 7d9e8823..b780b0a9 100644 --- a/application/models/Stations.php +++ b/application/models/Stations.php @@ -23,9 +23,12 @@ class Stations extends CI_Model { return $this->db->get(); } - function all_of_user() { + function all_of_user($userid = null) { + if ($userid == null) { + $userid=$this->session->userdata('user_id'); // Fallback to session-uid, if userid is omitted + } $this->db->select('station_profile.*, dxcc_entities.name as station_country, dxcc_entities.end as dxcc_end'); - $this->db->where('user_id', $this->session->userdata('user_id')); + $this->db->where('user_id', $userid); $this->db->join('dxcc_entities','station_profile.station_dxcc = dxcc_entities.adif','left outer'); return $this->db->get('station_profile'); } @@ -88,9 +91,11 @@ class Stations extends CI_Model { 'station_cq' => xss_clean($this->input->post('station_cq', true)), 'station_itu' => xss_clean($this->input->post('station_itu', true)), 'state' => $state, - 'eqslqthnickname' => xss_clean($this->input->post('eqslnickname', true)), - 'qrzapikey' => xss_clean($this->input->post('qrzapikey', true)), - 'qrzrealtime' => xss_clean($this->input->post('qrzrealtime', true)), + 'eqslqthnickname' => xss_clean($this->input->post('eqslnickname', true)), + 'hrdlog_code' => xss_clean($this->input->post('hrdlog_code', true)), + 'hrdlogrealtime' => xss_clean($this->input->post('hrdlogrealtime', true)), + 'qrzapikey' => xss_clean($this->input->post('qrzapikey', true)), + 'qrzrealtime' => xss_clean($this->input->post('qrzrealtime', true)), 'oqrs' => xss_clean($this->input->post('oqrs', true)), 'oqrs_email' => xss_clean($this->input->post('oqrsemail', true)), 'oqrs_text' => xss_clean($this->input->post('oqrstext', true)), @@ -130,8 +135,10 @@ class Stations extends CI_Model { 'station_itu' => xss_clean($this->input->post('station_itu', true)), 'state' => $state, 'eqslqthnickname' => xss_clean($this->input->post('eqslnickname', true)), - 'qrzapikey' => xss_clean($this->input->post('qrzapikey', true)), - 'qrzrealtime' => xss_clean($this->input->post('qrzrealtime', true)), + 'hrdlog_code' => xss_clean($this->input->post('hrdlog_code', true)), + 'hrdlogrealtime' => xss_clean($this->input->post('hrdlogrealtime', true)), + 'qrzapikey' => xss_clean($this->input->post('qrzapikey', true)), + 'qrzrealtime' => xss_clean($this->input->post('qrzrealtime', true)), 'oqrs' => xss_clean($this->input->post('oqrs', true)), 'oqrs_email' => xss_clean($this->input->post('oqrsemail', true)), 'oqrs_text' => xss_clean($this->input->post('oqrstext', true)), @@ -339,6 +346,35 @@ class Stations extends CI_Model { } } + function stations_with_hrdlog_code() { + $sql = "select station_profile.station_id, station_profile.station_profile_name, station_profile.station_callsign, modc.modcount, notc.notcount, totc.totcount + from station_profile + left outer join ( + select count(*) modcount, station_id + from ". $this->config->item('table_name') . + " where COL_HRDLOG_QSO_UPLOAD_STATUS = 'M' + group by station_id + ) as modc on station_profile.station_id = modc.station_id + left outer join ( + select count(*) notcount, station_id + from " . $this->config->item('table_name') . + " where (coalesce(COL_HRDLOG_QSO_UPLOAD_STATUS, '') = '' + or COL_HRDLOG_QSO_UPLOAD_STATUS = 'N') + group by station_id + ) as notc on station_profile.station_id = notc.station_id + left outer join ( + select count(*) totcount, station_id + from " . $this->config->item('table_name') . + " where COL_HRDLOG_QSO_UPLOAD_STATUS = 'Y' + group by station_id + ) as totc on station_profile.station_id = totc.station_id + where coalesce(station_profile.hrdlog_code, '') <> '' + and station_profile.user_id = " . $this->session->userdata('user_id'); + $query = $this->db->query($sql); + + return $query; + } + function stations_with_qrz_api_key() { $sql = "select station_profile.station_id, station_profile.station_profile_name, station_profile.station_callsign, modc.modcount, notc.notcount, totc.totcount from station_profile @@ -372,14 +408,14 @@ class Stations extends CI_Model { $sql=" SELECT station_profile.station_id, station_profile.station_profile_name, station_profile.station_callsign, notc.c notcount, totc.c totcount FROM station_profile - INNER JOIN ( + LEFT OUTER JOIN ( SELECT qsos.station_id, COUNT(qsos.COL_PRIMARY_KEY) c FROM %s qsos LEFT JOIN webadif ON qsos.COL_PRIMARY_KEY = webadif.qso_id WHERE webadif.qso_id IS NULL AND qsos.COL_SAT_NAME = 'QO-100' GROUP BY qsos.station_id ) notc ON station_profile.station_id = notc.station_id - INNER JOIN ( + LEFT JOIN ( SELECT qsos.station_id, COUNT(qsos.COL_PRIMARY_KEY) c FROM %s qsos WHERE qsos.COL_SAT_NAME = 'QO-100' diff --git a/application/models/User_model.php b/application/models/User_model.php index d58cf883..dc9eff52 100644 --- a/application/models/User_model.php +++ b/application/models/User_model.php @@ -123,7 +123,8 @@ class User_Model extends CI_Model { function add($username, $password, $email, $type, $firstname, $lastname, $callsign, $locator, $timezone, $measurement, $user_date_format, $user_stylesheet, $user_qth_lookup, $user_sota_lookup, $user_wwff_lookup, $user_pota_lookup, $user_show_notes, $user_column1, $user_column2, $user_column3, $user_column4, $user_column5, - $user_show_profile_image, $user_previous_qsl_type, $user_amsat_status_upload) { + $user_show_profile_image, $user_previous_qsl_type, $user_amsat_status_upload, $user_mastodon_url, + $user_gridmap_default_band, $user_gridmap_confirmation) { // Check that the user isn't already used if(!$this->exists($username)) { $data = array( @@ -152,6 +153,9 @@ class User_Model extends CI_Model { 'user_show_profile_image' => xss_clean($user_show_profile_image), 'user_previous_qsl_type' => xss_clean($user_previous_qsl_type), 'user_amsat_status_upload' => xss_clean($user_amsat_status_upload), + 'user_mastodon_url' => xss_clean($user_mastodon_url), + 'user_gridmap_default_band' => xss_clean($user_gridmap_default_band), + 'user_gridmap_confirmation' => xss_clean($user_gridmap_confirmation), ); // Check the password is valid @@ -208,6 +212,9 @@ class User_Model extends CI_Model { 'user_show_profile_image' => xss_clean($fields['user_show_profile_image']), 'user_previous_qsl_type' => xss_clean($fields['user_previous_qsl_type']), 'user_amsat_status_upload' => xss_clean($fields['user_amsat_status_upload']), + 'user_mastodon_url' => xss_clean($fields['user_mastodon_url']), + 'user_gridmap_default_band' => xss_clean($fields['user_gridmap_default_band']), + 'user_gridmap_confirmation' => (isset($fields['user_gridmap_confirmation_qsl']) ? 'Q' : '').(isset($fields['user_gridmap_confirmation_lotw']) ? 'L' : '').(isset($fields['user_gridmap_confirmation_eqsl']) ? 'E' : ''), ); // Check to see if the user is allowed to change user levels @@ -328,6 +335,9 @@ class User_Model extends CI_Model { 'user_column5' => isset($u->row()->user_column5) ? $u->row()->user_column5: 'Country', 'user_previous_qsl_type' => isset($u->row()->user_previous_qsl_type) ? $u->row()->user_previous_qsl_type: 0, 'user_amsat_status_upload' => isset($u->row()->user_amsat_status_upload) ? $u->row()->user_amsat_status_upload: 0, + 'user_mastodon_url' => $u->row()->user_mastodon_url, + 'user_gridmap_default_band' => $u->row()->user_gridmap_default_band, + 'user_gridmap_confirmation' => $u->row()->user_gridmap_confirmation, 'active_station_logbook' => $u->row()->active_station_logbook, ); diff --git a/application/models/Wwff.php b/application/models/Wwff.php index 93908d7e..e15584c3 100644 --- a/application/models/Wwff.php +++ b/application/models/Wwff.php @@ -15,6 +15,8 @@ class Wwff extends CI_Model { $bandslots = $this->bands->get_worked_bands('wwff'); + if(!$bandslots) return null; + $this->db->where_in("station_id", $logbooks_locations_array); $this->db->where_in("col_band", $bandslots); $this->db->order_by("COL_WWFF_REF", "ASC"); diff --git a/application/views/adif/import.php b/application/views/adif/import.php index c2c36fac..3b310065 100644 --- a/application/views/adif/import.php +++ b/application/views/adif/import.php @@ -59,6 +59,16 @@ +
+
+
+ + +
+
Select if ADIF being imported does not contain this information.
+
+
+
diff --git a/application/views/dashboard/index.php b/application/views/dashboard/index.php index 5300a281..a65ec044 100644 --- a/application/views/dashboard/index.php +++ b/application/views/dashboard/index.php @@ -22,8 +22,8 @@ function echo_table_col($row, $name) { $ci =& get_instance(); switch($name) { case 'Mode': echo ''; echo $row->COL_SUBMODE==null?$row->COL_MODE:$row->COL_SUBMODE . ''; break; - case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; - case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; + case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; + case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; case 'Country': echo '' . ucwords(strtolower(($row->COL_COUNTRY))); if ($row->end != NULL) echo ' '.$ci->lang->line('gen_hamradio_deleted_dxcc').'' . ''; break; case 'IOTA': echo '' . ($row->COL_IOTA) . ''; break; case 'SOTA': echo '' . ($row->COL_SOTA_REF) . ''; break; diff --git a/application/views/debug/main.php b/application/views/debug/main.php index 64e9857a..504eadf7 100644 --- a/application/views/debug/main.php +++ b/application/views/debug/main.php @@ -11,7 +11,7 @@ - + @@ -38,6 +38,11 @@ + + + + +
Versionconfig->item('app_version')."\n"; ?>optionslib->get_option('version')."\n"; ?>
LanguagePHP Version
MySQL Versiondb->version(); ?>
@@ -169,6 +174,8 @@ $commitDate = trim(exec('git log --pretty="%ci" -n1 HEAD')); $line = trim(exec('git log -n 1 --pretty=%D HEAD')); $pieces = explode(', ', $line); + $lastFetch = trim(exec('stat -c %Y .git/FETCH_HEAD')); + $dt = new DateTime("@$lastFetch"); if (isset($pieces[1])) { $remote = substr($pieces[1], 0, strpos($pieces[1], '/')); $branch = substr($pieces[1], strpos($pieces[1], '/')+1); @@ -225,6 +232,12 @@ + + Last Fetch + + format(\DateTime::RFC850); ?> + +
diff --git a/application/views/eqsl/import.php b/application/views/eqsl/import.php index 1808f11e..2c9edf72 100644 --- a/application/views/eqsl/import.php +++ b/application/views/eqsl/import.php @@ -29,10 +29,18 @@ -

+

Upload the Exported ADIF file from eQSL from the Download Inbox page, to mark QSOs as confirmed on eQSL.

Important Log files must have the file type .adi

+

+

Choose Station(location) eQSL File belongs to:

+

diff --git a/application/views/gridmap/index.php b/application/views/gridmap/index.php index 93a2cdeb..158ed40c 100644 --- a/application/views/gridmap/index.php +++ b/application/views/gridmap/index.php @@ -6,9 +6,9 @@ padding: 6px 8px; font: 14px Arial, Helvetica, sans-serif; background: white; - background: rgba(255, 255, 255, 0.8); line-height: 24px; color: #555; + border-radius: 10px; } .legend h4 { text-align: center; @@ -25,7 +25,19 @@ height: 18px; float: left; margin: 0 8px 0 0; - opacity: 0.7; +} +.coordinates { + justify-content: center; + align-items: stretch; +} +.cohidden { + display:none; +} +#latDeg, #lngDeg { + width: 170px; +} +#locator, #distance, #bearing { + width: 120px; }
@@ -38,13 +50,17 @@ - disabled> ' . $sat . ''."\n"; @@ -67,15 +83,27 @@
- + '; ?>
- + '; ?>
- + '; ?>
@@ -94,14 +122,27 @@
+
+
Latitude:
+
+
Longitude:
+
+
Gridsquare:
+
+
Distance:
+
+
Bearing:
+
+
\ No newline at end of file + diff --git a/application/views/hrdlog/export.php b/application/views/hrdlog/export.php new file mode 100644 index 00000000..85767b58 --- /dev/null +++ b/application/views/hrdlog/export.php @@ -0,0 +1,96 @@ + +
+ +

+ +
+
+ + +
+ +
+
+
+

Here you can see and upload all QSOs which have not been previously uploaded to a HRDLog logbook.

+

You need to set a HRDLog Logbook API Code in your station profile. Only station profiles with an API Key set are displayed.

+

The Code can be demanded at http://www.hrdlog.net/EditUser.aspx

+

Warning This might take a while as QSO uploads are processed sequentially.

+ +result()) { + echo ' + + + + + + + + + + + + '; + foreach ($station_profile->result() as $station) { // Fills the table with the data + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
Profile nameStation callsignEdited QSOs not uploadedTotal QSOs not uploadedTotal QSOs uploadedActions
' . $station->station_profile_name . '' . $station->station_callsign . '' . $station->modcount . '' . $station->notcount . '' . $station->totcount . '
'; + + } + else { + echo ''; + } + ?> + +
+
+ +
+ +

Warning If a date range is not selected then all QSOs will be marked!

+

From date:

+
+
+ +
+
+
+
+
+

To date:

+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
diff --git a/application/views/hrdlog/mark_hrdlog.php b/application/views/hrdlog/mark_hrdlog.php new file mode 100644 index 00000000..629e1efe --- /dev/null +++ b/application/views/hrdlog/mark_hrdlog.php @@ -0,0 +1,22 @@ +
+
+ session->flashdata('message')) { ?> + +
+

session->flashdata('message'); ?>

+
+ + +
+
+ QSOs marked +
+
+

Yay, it's done!

+

The QSOs are marked as exported to HRDLog Logbook.

+
+
+ + +
+ diff --git a/application/views/interface_assets/footer.php b/application/views/interface_assets/footer.php index cb3e3c63..574f57fb 100644 --- a/application/views/interface_assets/footer.php +++ b/application/views/interface_assets/footer.php @@ -71,7 +71,7 @@ function load_was_map() { -uri->segment(1) == "adif" || $this->uri->segment(1) == "qrz" || $this->uri->segment(1) == "webadif") { ?> +uri->segment(1) == "adif" || $this->uri->segment(1) == "qrz" || $this->uri->segment(1) == "hrdlog" ||$this->uri->segment(1) == "webadif") { ?> @@ -1235,97 +1235,110 @@ $(document).on('keypress',function(e) { @@ -1702,6 +1715,9 @@ $(document).ready(function(){ + uri->segment(1) == "hrdlog") { ?> + + uri->segment(1) == "qrz") { ?> @@ -2007,7 +2023,7 @@ $(document).ready(function(){ success: function (dataofconfirm) { $(".edit-dialog").modal('hide'); $(".qso-dialog").modal('hide'); - uri->segment(1) != "search" && $this->uri->segment(2) != "filter" && $this->uri->segment(1) != "qso") { ?>location.reload(); + uri->segment(1) != "search" && $this->uri->segment(2) != "filter" && $this->uri->segment(1) != "qso" && $this->uri->segment(1) != "logbookadvanced") { ?>location.reload(); }, error: function(xhr, status, error) { console.log(xhr.responseText); @@ -2398,7 +2414,7 @@ function viewEqsl(picture, callsign) { $("#qslcardfront").val(null); } - } else { + } else if (data.status.front.status != '') { $("#qslupload").append('
×Front QSL Card:' + data.status.front.error + '
'); @@ -2436,7 +2452,7 @@ function viewEqsl(picture, callsign) { $(".carouselExampleIndicators").carousel(); $("#qslcardback").val(null); } - } else { + } else if (data.status.back.status != '') { $("#qslupload").append('
×\nBack QSL Card: ' + data.status.back.error + '
'); diff --git a/application/views/interface_assets/header.php b/application/views/interface_assets/header.php index 2cd82483..df346f2b 100644 --- a/application/views/interface_assets/header.php +++ b/application/views/interface_assets/header.php @@ -260,6 +260,7 @@ $oqrs_requests = $CI->oqrs_model->oqrs_requests($location_list); + diff --git a/application/views/logbookadvanced/index.php b/application/views/logbookadvanced/index.php index 45539220..13528f30 100644 --- a/application/views/logbookadvanced/index.php +++ b/application/views/logbookadvanced/index.php @@ -55,7 +55,7 @@
+ + '. $i .''; + } + ?> + ?> + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
- +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + + + + + + + +
- +
+
+ With selected : + + + + + + + + + + + + + + +
+
+
- With selected : - - - - - - - - - - - - - - - + Quick search with selected : + + + + + + + + + + +
+ @@ -239,4 +335,4 @@ -
\ No newline at end of file +
diff --git a/application/views/logbooks/edit.php b/application/views/logbooks/edit.php index 81811052..092e5bc4 100644 --- a/application/views/logbooks/edit.php +++ b/application/views/logbooks/edit.php @@ -68,6 +68,18 @@ Visit Public Page /public_slug; ?> +
+ +

Enabling public search function offers a search input box on the public logbook page accessed via public slug. Search only covers this logbook.

+ + +
+

+

+
diff --git a/application/views/logbooks/index.php b/application/views/logbooks/index.php index d9e0f07f..c510b2b5 100644 --- a/application/views/logbooks/index.php +++ b/application/views/logbooks/index.php @@ -36,6 +36,7 @@ Edit Delete Link + Public Search @@ -65,6 +66,13 @@ public_slug; ?>" class="btn btn-outline-primary btn-sm" > + + public_search == 1) { + echo "Enabled"; + } else { + echo "Disabled"; + } ?> + diff --git a/application/views/lotw/import.php b/application/views/lotw/import.php index 76139dea..d76e9239 100644 --- a/application/views/lotw/import.php +++ b/application/views/lotw/import.php @@ -41,14 +41,6 @@
-

diff --git a/application/views/options/appearance.php b/application/views/options/appearance.php index eaf229fa..1f407d00 100644 --- a/application/views/options/appearance.php +++ b/application/views/options/appearance.php @@ -59,15 +59,12 @@ - -
- - - -
diff --git a/application/views/public_search/empty.php b/application/views/public_search/empty.php new file mode 100644 index 00000000..c9fc3fde --- /dev/null +++ b/application/views/public_search/empty.php @@ -0,0 +1,4 @@ +
+

Results Searching for

+ +
diff --git a/application/views/public_search/result.php b/application/views/public_search/result.php new file mode 100644 index 00000000..36662dc3 --- /dev/null +++ b/application/views/public_search/result.php @@ -0,0 +1,76 @@ +
+

Results Searching for

+
+
+ + +
+ + + + + + + + + + + + + result() as $row) { + echo ''; ?> + + + + + + + + +
Station Callsign
COL_TIME_ON); echo date($this->config->item('qso_date_format'), $timestamp); ?> + COL_CALL)); ?> + + COL_SUBMODE==null ? $row->COL_MODE : $row->COL_SUBMODE; ?> + + COL_SAT_NAME != null) { echo $row->COL_SAT_NAME; } else { echo strtolower($row->COL_BAND); } ?> + + station_callsign; ?> +
+ + + pagination)){ ?> + '; + $config['full_tag_close'] = ''; + $config['attributes'] = ['class' => 'page-link']; + $config['first_link'] = false; + $config['last_link'] = false; + $config['first_tag_open'] = '
  • '; + $config['first_tag_close'] = '
  • '; + $config['prev_link'] = '«'; + $config['prev_tag_open'] = '
  • '; + $config['prev_tag_close'] = '
  • '; + $config['next_link'] = '»'; + $config['next_tag_open'] = '
  • '; + $config['next_tag_close'] = '
  • '; + $config['last_tag_open'] = '
  • '; + $config['last_tag_close'] = '
  • '; + $config['cur_tag_open'] = '
  • '; + $config['cur_tag_close'] = '(current)
  • '; + $config['num_tag_open'] = '
  • '; + $config['num_tag_close'] = '
  • '; + $this->pagination->initialize($config); + ?> + + pagination->create_links(); ?> + + + +
    +
    +
    +
    + diff --git a/application/views/qrz/export.php b/application/views/qrz/export.php index 0bb24e4f..1f51b4c8 100644 --- a/application/views/qrz/export.php +++ b/application/views/qrz/export.php @@ -21,7 +21,7 @@

    Here you can see and upload all QSOs which have not been previously uploaded to a QRZ logbook.

    You need to set a QRZ Logbook API key in your station profile. Only station profiles with an API Key set are displayed.

    -

    WarningThis might take a while as QSO uploads are processed sequentially.

    +

    Warning This might take a while as QSO uploads are processed sequentially.

    result()) { @@ -61,9 +61,9 @@

    Warning If a date range is not selected then all QSOs will be marked!

    diff --git a/application/views/qslcard/qslcarousel.php b/application/views/qslcard/qslcarousel.php new file mode 100644 index 00000000..78aad712 --- /dev/null +++ b/application/views/qslcard/qslcarousel.php @@ -0,0 +1,38 @@ + + + + Previous + + + + Next + +
    \ No newline at end of file diff --git a/application/views/qso/index.php b/application/views/qso/index.php index b649aa2f..4533b6b5 100755 --- a/application/views/qso/index.php +++ b/application/views/qso/index.php @@ -65,7 +65,7 @@
    - +
    diff --git a/application/views/search/search_result_ajax.php b/application/views/search/search_result_ajax.php index f47f04c8..173af8c4 100644 --- a/application/views/search/search_result_ajax.php +++ b/application/views/search/search_result_ajax.php @@ -130,8 +130,8 @@ $ci =& get_instance(); switch($this->session->userdata('user_column1')==""?'Mode':$this->session->userdata('user_column1')) { case 'Mode': echo ''; echo $row->COL_SUBMODE==null?$row->COL_MODE:$row->COL_SUBMODE; break; - case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; - case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; + case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; + case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; case 'Country': echo '' . ucwords(strtolower(($row->COL_COUNTRY)));; break; case 'IOTA': echo '' . ($row->COL_IOTA); break; case 'SOTA': echo '' . ($row->COL_SOTA_REF); break; @@ -142,13 +142,13 @@ $ci =& get_instance(); case 'Band': echo ''; if($row->COL_SAT_NAME != null) { echo $row->COL_SAT_NAME; } else { echo strtolower($row->COL_BAND); }; break; case 'State': echo '' . ($row->COL_STATE); break; case 'Operator': echo '' . ($row->COL_OPERATOR); break; - case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ''.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ''.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; + case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ' '.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ' '.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; } echo ''; switch($this->session->userdata('user_column2')==""?'RSTS':$this->session->userdata('user_column2')) { case 'Mode': echo ''; echo $row->COL_SUBMODE==null?$row->COL_MODE:$row->COL_SUBMODE; break; - case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; - case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; + case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; + case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; case 'Country': echo '' . ucwords(strtolower(($row->COL_COUNTRY)));; break; case 'IOTA': echo '' . ($row->COL_IOTA); break; case 'SOTA': echo '' . ($row->COL_SOTA_REF); break; @@ -159,14 +159,14 @@ $ci =& get_instance(); case 'Band': echo ''; if($row->COL_SAT_NAME != null) { echo $row->COL_SAT_NAME; } else { echo strtolower($row->COL_BAND); }; break; case 'State': echo '' . ($row->COL_STATE); break; case 'Operator': echo '' . ($row->COL_OPERATOR); break; - case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ''.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ''.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; + case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ' '.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ' '.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; } echo ''; switch($this->session->userdata('user_column3')==""?'RSTR':$this->session->userdata('user_column3')) { case 'Mode': echo ''; echo $row->COL_SUBMODE==null?$row->COL_MODE:$row->COL_SUBMODE; break; - case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; - case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; + case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; + case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; case 'Country': echo '' . ucwords(strtolower(($row->COL_COUNTRY)));; break; case 'IOTA': echo '' . ($row->COL_IOTA); break; case 'SOTA': echo '' . ($row->COL_SOTA_REF); break; @@ -177,13 +177,13 @@ $ci =& get_instance(); case 'Band': echo ''; if($row->COL_SAT_NAME != null) { echo $row->COL_SAT_NAME; } else { echo strtolower($row->COL_BAND); }; break; case 'State': echo '' . ($row->COL_STATE); break; case 'Operator': echo '' . ($row->COL_OPERATOR); break; - case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ''.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ''.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; + case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ' '.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ' '.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; } echo ''; switch($this->session->userdata('user_column4')==""?'Band':$this->session->userdata('user_column4')) { case 'Mode': echo ''; echo $row->COL_SUBMODE==null?$row->COL_MODE:$row->COL_SUBMODE; break; - case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; - case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; + case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; + case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; case 'Country': echo '' . ucwords(strtolower(($row->COL_COUNTRY)));; break; case 'IOTA': echo '' . ($row->COL_IOTA); break; case 'SOTA': echo '' . ($row->COL_SOTA_REF); break; @@ -194,13 +194,13 @@ $ci =& get_instance(); case 'Band': echo ''; if($row->COL_SAT_NAME != null) { echo $row->COL_SAT_NAME; } else { echo strtolower($row->COL_BAND); }; break; case 'State': echo '' . ($row->COL_STATE); break; case 'Operator': echo '' . ($row->COL_OPERATOR); break; - case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ''.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ''.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; + case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ' '.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ' '.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; } echo ''; switch($this->session->userdata('user_column5')==""?'Country':$this->session->userdata('user_column5')) { case 'Mode': echo ''; echo $row->COL_SUBMODE==null?$row->COL_MODE:$row->COL_SUBMODE; break; - case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; - case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; + case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; + case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; case 'Country': echo '' . ucwords(strtolower(($row->COL_COUNTRY)));; break; case 'IOTA': echo '' . ($row->COL_IOTA); break; case 'SOTA': echo '' . ($row->COL_SOTA_REF); break; @@ -211,7 +211,7 @@ $ci =& get_instance(); case 'Band': echo ''; if($row->COL_SAT_NAME != null) { echo $row->COL_SAT_NAME; } else { echo strtolower($row->COL_BAND); }; break; case 'State': echo '' . ($row->COL_STATE); break; case 'Operator': echo '' . ($row->COL_OPERATOR); break; - case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ''.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ''.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; + case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ' '.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ' '.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; } echo ''; if(($this->config->item('use_auth')) && ($this->session->userdata('user_type') >= 2)) { ?> diff --git a/application/views/station_profile/create.php b/application/views/station_profile/create.php index 3350451e..5f6efd3e 100644 --- a/application/views/station_profile/create.php +++ b/application/views/station_profile/create.php @@ -249,6 +249,20 @@ eQSL QTH Nickname.
    + +
    +
    + + Find your API key on HRDLog Userprofile +
    +
    + +
    +
    + diff --git a/application/views/station_profile/edit.php b/application/views/station_profile/edit.php index f2809222..d263e17d 100644 --- a/application/views/station_profile/edit.php +++ b/application/views/station_profile/edit.php @@ -371,6 +371,27 @@ +
    +
    +
    +
    HRDLog.net
    +
    +
    + + hrdlog_code; } ?>"> + Create your API Code on HRDLog.net Userprofile page +
    +
    + + +
    +
    +
    +
    +
    diff --git a/application/views/user/add.php b/application/views/user/add.php index d3a0492e..a7bd8897 100644 --- a/application/views/user/add.php +++ b/application/views/user/add.php @@ -514,6 +514,73 @@
    +
    +
    +
    + +
    +
    +
    + + +
    Main URL of your Mastodon server, e.g. https://radiosocial.de
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + + + +
    +
    + +
    + '; ?> + +
    +
    + '; ?> + +
    +
    + '; ?> + +
    +
    +
    +
    +
    diff --git a/application/views/user/edit.php b/application/views/user/edit.php index ff3586c2..23c1d781 100644 --- a/application/views/user/edit.php +++ b/application/views/user/edit.php @@ -476,7 +476,7 @@
    - +
    @@ -512,7 +512,73 @@
    +
    +
    +
    + +
    +
    +
    + + +
    Main URL of your Mastodon server, e.g. https://radiosocial.de
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + '; ?> + +
    +
    + '; ?> + +
    +
    + '; ?> + +
    +
    +
    +
    +
    diff --git a/application/views/view_log/partial/log_ajax.php b/application/views/view_log/partial/log_ajax.php index d317f0f6..e0afda10 100644 --- a/application/views/view_log/partial/log_ajax.php +++ b/application/views/view_log/partial/log_ajax.php @@ -23,8 +23,8 @@ function echo_table_col($row, $name) { $ci =& get_instance(); switch($name) { case 'Mode': echo ''; echo $row->COL_SUBMODE==null?$row->COL_MODE:$row->COL_SUBMODE . ''; break; - case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; - case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; + case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; + case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; case 'Country': echo '' . ucwords(strtolower(($row->name==null?"- NONE -":$row->name))); if ($row->end != null) echo ' '.$ci->lang->line('gen_hamradio_deleted_dxcc').'' . ''; break; case 'IOTA': echo '' . ($row->COL_IOTA) . ''; break; case 'SOTA': echo '' . ($row->COL_SOTA_REF) . ''; break; @@ -32,8 +32,8 @@ function echo_table_col($row, $name) { case 'POTA': echo '' . ($row->COL_POTA_REF) . ''; break; case 'Grid': echo ''; echoQrbCalcLink($row->station_gridsquare, $row->COL_VUCC_GRIDS, $row->COL_GRIDSQUARE); echo ''; break; case 'Distance':echo '' . ($row->COL_DISTANCE ? $row->COL_DISTANCE . ' km' : '') . ''; break; - case 'Band': echo ''; if($row->COL_SAT_NAME != null) { echo ''.$row->COL_SAT_NAME.''; } else { if ($row->COL_FREQ != null) { echo ''. strtolower($row->COL_BAND).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; - case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ''.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ''.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; + case 'Band': echo ''; if($row->COL_SAT_NAME != null) { echo ''.$row->COL_SAT_NAME.''; } else { if ($row->COL_FREQ != null) { echo ' '. strtolower($row->COL_BAND).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; + case 'Frequency': echo ''; if($row->COL_SAT_NAME != null) { echo ''; if ($row->COL_FREQ != null) { echo ' '.$row->COL_SAT_NAME.''; } else { echo $row->COL_SAT_NAME; } echo ''; } else { if ($row->COL_FREQ != null) { echo ' '.$ci->frequency->hz_to_mhz($row->COL_FREQ).''; } else { echo strtolower($row->COL_BAND); } } echo ''; break; case 'State': echo '' . ($row->COL_STATE) . ''; break; case 'Operator':echo '' . ($row->COL_OPERATOR) . ''; break; case 'Location':echo '' . ($row->station_profile_name) . ''; break; diff --git a/application/views/view_log/qso.php b/application/views/view_log/qso.php index 0071fc06..e036b4e5 100644 --- a/application/views/view_log/qso.php +++ b/application/views/view_log/qso.php @@ -407,6 +407,7 @@ ?>
    Tweet
    + session->userdata('user_mastodon_url') != null) { echo '
    Toot
    '; } ?> @@ -508,70 +509,61 @@

    -
    +
    +
    +
    -
    - - +
    + + +
    + + + + +
    +
    +
    + + +
    + +
    - -
    - - -
    - - - - - -
    + +

    +

    +
    + + + + + +
    +
    +

    +

    +
    + + + + + + +
    +
    - + load->view('qslcard/qslcarousel', $qslimages); ?>
    eqsl_image_file .'" alt="QSL picture #'. $i++.'">'; + if ($row->eqsl_image_file != null) { + echo 'QSL picture #'. $i++.''; + } ?>
    '; echo $row->COL_SUBMODE==null?$row->COL_MODE:$row->COL_SUBMODE . ''; break; - case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; - case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo 'COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; + case 'RSTS': echo '' . $row->COL_RST_SENT; if ($row->COL_STX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_STX); echo '';} if ($row->COL_STX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_STX_STRING . '';} echo ''; break; + case 'RSTR': echo '' . $row->COL_RST_RCVD; if ($row->COL_SRX) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">'; printf("%03d", $row->COL_SRX); echo '';} if ($row->COL_SRX_STRING) { echo ' COL_CONTEST_ID:"n/a").'" class="badge badge-light">' . $row->COL_SRX_STRING . '';} echo ''; break; case 'Country': echo '' . ucwords(strtolower(($row->COL_COUNTRY))) . ''; break; case 'IOTA': echo '' . ($row->COL_IOTA) . ''; break; case 'SOTA': echo '' . ($row->COL_SOTA_REF) . ''; break; @@ -50,7 +50,7 @@ function echoQrbCalcLink($mygrid, $grid, $vucc) {
    -
    +
    @@ -231,3 +231,5 @@ function echoQrbCalcLink($mygrid, $grid, $vucc) {
    + +
    diff --git a/application/views/visitor/layout/footer.php b/application/views/visitor/layout/footer.php index 23689ee2..d51f5bba 100644 --- a/application/views/visitor/layout/footer.php +++ b/application/views/visitor/layout/footer.php @@ -23,7 +23,8 @@ - + + CI->public_search_enabled($slug) || $this->session->userdata('user_type') >= 2) { ?> + + + + + + + + + diff --git a/application/views/visitor/layout/header.php b/application/views/visitor/layout/header.php index 8cef7e98..f83b58aa 100644 --- a/application/views/visitor/layout/header.php +++ b/application/views/visitor/layout/header.php @@ -9,6 +9,7 @@ optionslib->get_theme()) { ?> + @@ -71,6 +72,18 @@ + +
    + CI =& get_instance(); + if ($this->CI->public_search_enabled($slug) || $this->session->userdata('user_type') >= 2) { ?> +
    + aria-label="Search" data-toogle="tooltip" data-placement="bottom" data-original-title="Please enter a callsign!"> + + +
    +
    diff --git a/application/views/webadif/export.php b/application/views/webadif/export.php index 11756f21..f968d582 100644 --- a/application/views/webadif/export.php +++ b/application/views/webadif/export.php @@ -24,6 +24,11 @@ result()) { + $queuedqsos = 0; + foreach ($station_profile->result() as $count) { // Fills the table with the data + $queuedqsos += $count->notcount; + } + if ($queuedqsos > 0) { ?>

    You need to set a QO-100 Dx Club API key in your station profile. Only station profiles with an API Key are displayed.

    Warning This might take a while as QSO uploads are processed sequentially.

    @@ -41,15 +46,25 @@ '; foreach ($station_profile->result() as $station) { // Fills the table with the data - echo ''; - echo '' . $station->station_profile_name . ''; - echo '' . $station->station_callsign . ''; - echo '' . $station->notcount . ''; - echo '' . $station->totcount . ''; - echo ''; - echo ''; + if ($station->notcount != null) { + echo ''; + echo '' . $station->station_profile_name . ''; + echo '' . $station->station_callsign . ''; + echo '' . $station->notcount . ''; + echo '' . $station->totcount . ''; + echo ''; + echo ''; + } } echo ''; + } else { + ?> +
    + There are currently no outstanding QSOs that need to be uploaded to the QO-100 Dx Club's API.
    + Go ahead and turn on your QO-100 station! +
    + 0 */1 * * * curl --silent /lotw/lotw_upload &>/dev/null

    + # Upload QSOs to HRDLog.net Logbook (ignore cron job if this integration is not required)
    + 0 */6 * * * curl --silent /hrdlog/upload &>/dev/null
    +
    # Upload QSOs to QRZ Logbook (ignore cron job if this integration is not required)
    0 */6 * * * curl --silent /qrz/upload &>/dev/null

    @@ -153,4 +156,4 @@

    - \ No newline at end of file + diff --git a/assets/css/general.css b/assets/css/general.css index edfa24c7..70bfbfa1 100644 --- a/assets/css/general.css +++ b/assets/css/general.css @@ -42,6 +42,11 @@ thead > tr > td { padding-top: 15px; } +.publicsearch { + padding-top: 15px; + max-width: 540px; +} + .search { padding-top: 15px; } diff --git a/assets/css/visitor.css b/assets/css/visitor.css new file mode 100644 index 00000000..a8a4ea21 --- /dev/null +++ b/assets/css/visitor.css @@ -0,0 +1,3 @@ +#searchcall:focus { + text-transform: uppercase; +} diff --git a/assets/js/leaflet/geocoding.js b/assets/js/leaflet/geocoding.js new file mode 100644 index 00000000..4730d2ae --- /dev/null +++ b/assets/js/leaflet/geocoding.js @@ -0,0 +1,167 @@ +const isValidLocatorString = locatorString => locatorString.match(/^[A-Ra-r][A-Ra-r]\d\d[A-Xa-x][A-Xa-x]/) !== null; +const charToNumber = char => char.toUpperCase().charCodeAt(0) - CHAR_CODE_OFFSET; +const numberToChar = number => String.fromCharCode(number + CHAR_CODE_OFFSET); +const CHAR_CODE_OFFSET = 65; +const degToRad = deg => (deg % 360) * Math.PI / 180; +const radToDeg = rad => (rad / Math.PI *180) % 360; +const isValidPoint = (lat, lng) => (lat >= -90 && lat <= 90) && (lng >= -180 && lng <= 180); + +function ConvertDDToDMS(lat, lng) { + var LatLng = []; + + if (lng < -180) { + lng = lng + 360; + } + if (lng > 180) { + lng = lng - 360; + } + + LatLng['latDeg'] = (lat < 0 ? "S" : "N") + " " + pad((0 |(lat < 0 ? (lat = -lat) : lat)), 2) + "° " + pad(0 | (((lat += 1e-9) % 1) * 60),2) + "' " + ((0 | (((lat * 60) % 1) * 6000)) / 100) + "\""; + + LatLng['lngDeg'] = (lng < 0 ? "W" : "E") + " " + pad((0 | (lng < 0 ? (lng = -lng) : lng)), 3) + "° " + pad(0 | (((lng += 1e-9) % 1) * 60),2) + "' " + ((0 | (((lng * 60) % 1) * 6000)) / 100) + "\""; + + return LatLng; +} + +function pad(n, width, z) { + z = z || '0'; + n = n + ''; + return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; +} + +const latLngToLocator = (lat, lng) => { + if (lng < -180) { + lng = lng + 360; + } + if (lng > 180) { + lng = lng - 360; + } + if (!isValidPoint(lat, lng)) { + throw new Error('Input is not a valid coordinate'); + } + + const longitude = lng + 180; + const latitude = lat + 90; + + const fieldLng = numberToChar(Math.floor(longitude / 20)); + const fieldLat = numberToChar(Math.floor(latitude / 10)); + + const squareLng = Math.floor(longitude % 20 / 2); + const squareLat = Math.floor(latitude % 10); + + const subsquareLng = numberToChar(Math.floor((longitude % 20 % 2) * 12)).toLowerCase(); + const subsquareLat = numberToChar((latitude % 10 - squareLat) * 24).toLowerCase(); + + return fieldLng + fieldLat + squareLng + squareLat + subsquareLng + subsquareLat; +}; + +function onMapMove(event) { + var LatLng = event.latlng; + var lat = LatLng.lat; + var lng = LatLng.lng; + var LatLng2 = ConvertDDToDMS(lat, lng); + $('#latDeg').html(LatLng2.latDeg); + $('#lngDeg').html(LatLng2.lngDeg); + var locator = latLngToLocator(lat,lng); + $('#locator').html(locator); + var distance = bearingDistance(homegrid, locator); + + $('#bearing').html(distance.deg + ' deg'); + $('#distance').html(Math.round(distance.km * 10) / 10 + ' km'); +}; + +function onMapClick(event) { + var LatLng = event.latlng; + var lat = LatLng.lat; + var lng = LatLng.lng; + var locator = latLngToLocator(lat,lng); + var fromCoords = locatorToLatLng(homegrid); + + var marker = L.marker([fromCoords[0], fromCoords[1]], {closeOnClick: false, autoClose: false}).addTo(map).bindPopup(homegrid); + + var result = bearingDistance(homegrid, locator); + + var distance = Math.round(result.km * 10) / 10 + ' km'; + var bearing = Math.round(result.deg * 10) / 10 + ' deg'; + var popupmessage = ''; + + const multiplelines = []; + multiplelines.push( + new L.LatLng(fromCoords[0], fromCoords[1]), + new L.LatLng(lat, lng) + ) + + if (lng < -170) { + lng = parseFloat(lng) + 360; + } + + var marker2 = L.marker([lat, lng], {closeOnClick: false, autoClose: false}).addTo(map); + + marker2.bindTooltip(popupmessage); + + const geodesic = L.geodesic(multiplelines, { + weight: 3, + opacity: 1, + color: 'red', + wrap: false, + steps: 100 + }).addTo(map); +}; + +const bearingDistance = (from, to) => { + const fromCoords = locatorToLatLng(from); + const toCoords = locatorToLatLng(to); + const dLat = degToRad(toCoords[0] - fromCoords[0]); + const dLon = degToRad(toCoords[1] - fromCoords[1]); + const fromLat = degToRad(fromCoords[0]); + const toLat = degToRad(toCoords[0]); + const a = Math.pow(Math.sin(dLat / 2), 2) + Math.pow(Math.sin(dLon / 2), 2) * Math.cos(fromLat) * Math.cos(toLat); + const b = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + const y = (dLon) * Math.cos(fromLat) * Math.cos(toLat); + const x = Math.sin(toLat) - Math.sin(fromLat) * Math.cos(b); + + let az = Math.atan2(y, x); + + if (az < 0) { + az += 2 * Math.PI; + } + + return { + km: b * 6371, + deg: calcAngle(fromCoords, toCoords) + }; +}; + +var calcAngle = function (p1, p2) { + var lat1 = p1[0] / 180 * Math.PI; + var lat2 = p2[0] / 180 * Math.PI; + var lng1 = p1[1] / 180 * Math.PI; + var lng2 = p2[1] / 180 * Math.PI; + var y = Math.sin(lng2-lng1) * Math.cos(lat2); + var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(lng2-lng1); + var brng = (Math.atan2(y, x) * 180 / Math.PI + 360).toFixed(0); + + return (brng % 360); +} + +const locatorToLatLng = (locatorString) => { + locatorString += 'll'; // append subsquare in case is 4 chars long... If not, is ignored. + if (!isValidLocatorString(locatorString)) { + throw new Error('Input is not valid locator string'); + } + + const fieldLng = charToNumber(locatorString[0]) * 20; + const fieldLat = charToNumber(locatorString[1]) * 10; + const squareLng = Number.parseInt(locatorString[2]) * 2; + const squareLat = Number.parseInt(locatorString[3]); + const subsquareLng = (charToNumber(locatorString[4]) + 0.5) / 12; + const subsquareLat = (charToNumber(locatorString[5]) + 0.5) / 24; + + return [ + fieldLat + squareLat + subsquareLat - 90, + fieldLng + squareLng + subsquareLng - 180 + ]; +}; diff --git a/assets/js/sections/common.js b/assets/js/sections/common.js index ceb493e5..030a298f 100644 --- a/assets/js/sections/common.js +++ b/assets/js/sections/common.js @@ -1,4 +1,6 @@ function qsl_rcvd(id, method) { + $(".ld-ext-right-r-"+method).addClass('running'); + $(".ld-ext-right-r-"+method).prop('disabled', true); $.ajax({ url: base_url + 'index.php/qso/qsl_rcvd_ajax', type: 'post', @@ -6,6 +8,8 @@ function qsl_rcvd(id, method) { 'method': method }, success: function(data) { + $(".ld-ext-right-r-"+method).removeClass('running'); + $(".ld-ext-right-r-"+method).prop('disabled', false); if (data.message == 'OK') { $("#qsl_" + id).find("span:eq(1)").attr('class', 'qsl-green'); // Paints arrow green $(".qsl_rcvd_" + id).remove(); // removes choice from menu @@ -39,6 +43,8 @@ function qsl_sent(id, method) { // Function: qsl_requested // Marks QSL card requested against the QSO. function qsl_requested(id, method) { + $(".ld-ext-right-t-"+method).addClass('running'); + $(".ld-ext-right-t-"+method).prop('disabled', true); $.ajax({ url: base_url + 'index.php/qso/qsl_requested_ajax', type: 'post', @@ -46,6 +52,8 @@ function qsl_requested(id, method) { 'method': method }, success: function(data) { + $(".ld-ext-right-t-"+method).removeClass('running'); + $(".ld-ext-right-t-"+method).prop('disabled', false); if (data.message == 'OK') { $("#qsl_" + id).find("span:eq(0)").attr('class', 'qsl-yellow'); // Paints arrow yellow } @@ -59,6 +67,8 @@ function qsl_requested(id, method) { // Function: qsl_ignore // Marks QSL card ignore against the QSO. function qsl_ignore(id, method) { + $(".ld-ext-right-ignore").addClass('running'); + $(".ld-ext-right-ignore").prop('disabled', true); $.ajax({ url: base_url + 'index.php/qso/qsl_ignore_ajax', type: 'post', @@ -66,6 +76,8 @@ function qsl_ignore(id, method) { 'method': method }, success: function(data) { + $(".ld-ext-right-ignore").removeClass('running'); + $(".ld-ext-right-ignore").prop('disabled', false); if (data.message == 'OK') { $("#qsl_" + id).find("span:eq(0)").attr('class', 'qsl-grey'); // Paints arrow grey } @@ -358,7 +370,7 @@ function validateLocator(locator) { } // This displays the dialog with the form and it's where the resulttable is displayed -function spawnLookupModal() { +function spawnLookupModal(searchphrase, searchtype) { $.ajax({ url: base_url + 'index.php/lookup', type: 'post', @@ -372,38 +384,22 @@ function spawnLookupModal() { onshown: function(dialog) { $('#quicklookuptype').change(function(){ var type = $('#quicklookuptype').val(); - if (type == "dxcc") { - $('#quicklookupdxcc').show(); - $('#quicklookupiota').hide(); - $('#quicklookupcqz').hide(); - $('#quicklookupwas').hide(); - $('#quicklookuptext').hide(); - } else if (type == "iota") { - $('#quicklookupiota').show(); - $('#quicklookupdxcc').hide(); - $('#quicklookupcqz').hide(); - $('#quicklookupwas').hide(); - $('#quicklookuptext').hide(); - } else if (type == "vucc" || type == "sota" || type == "wwff") { - $('#quicklookuptext').show(); - $('#quicklookupiota').hide(); - $('#quicklookupdxcc').hide(); - $('#quicklookupcqz').hide(); - $('#quicklookupwas').hide(); - } else if (type == "cq") { - $('#quicklookupcqz').show(); - $('#quicklookupiota').hide(); - $('#quicklookupdxcc').hide(); - $('#quicklookupwas').hide(); - $('#quicklookuptext').hide(); - } else if (type == "was") { - $('#quicklookupwas').show(); - $('#quicklookupcqz').hide(); - $('#quicklookupiota').hide(); - $('#quicklookupdxcc').hide(); - $('#quicklookuptext').hide(); - } + changeLookupType(type); }); + if (searchtype !== undefined) { + $('#quicklookuptype').val(searchtype); + if (searchtype == 'dxcc') { + $("#quicklookupdxcc").val(searchphrase); + } else if (searchtype == 'iota') { + $("#quicklookupiota").val(searchphrase); + } else if (searchtype == 'cq') { + $("#quicklookupcqz").val(searchphrase); + } else { + $("#quicklookuptext").val(searchphrase); + } + changeLookupType(searchtype); + getLookupResult(this.form); + } }, buttons: [{ label: 'Close', @@ -416,6 +412,40 @@ function spawnLookupModal() { }); } +function changeLookupType(type) { + if (type == "dxcc") { + $('#quicklookupdxcc').show(); + $('#quicklookupiota').hide(); + $('#quicklookupcqz').hide(); + $('#quicklookupwas').hide(); + $('#quicklookuptext').hide(); + } else if (type == "iota") { + $('#quicklookupiota').show(); + $('#quicklookupdxcc').hide(); + $('#quicklookupcqz').hide(); + $('#quicklookupwas').hide(); + $('#quicklookuptext').hide(); + } else if (type == "vucc" || type == "sota" || type == "wwff") { + $('#quicklookuptext').show(); + $('#quicklookupiota').hide(); + $('#quicklookupdxcc').hide(); + $('#quicklookupcqz').hide(); + $('#quicklookupwas').hide(); + } else if (type == "cq") { + $('#quicklookupcqz').show(); + $('#quicklookupiota').hide(); + $('#quicklookupdxcc').hide(); + $('#quicklookupwas').hide(); + $('#quicklookuptext').hide(); + } else if (type == "was") { + $('#quicklookupwas').show(); + $('#quicklookupcqz').hide(); + $('#quicklookupiota').hide(); + $('#quicklookupdxcc').hide(); + $('#quicklookuptext').hide(); + } +} + // This function executes the call to the backend for fetching queryresult and displays the table in the dialog function getLookupResult() { $(".ld-ext-right").addClass('running'); @@ -457,3 +487,31 @@ function getDxccResult(dxcc, name) { } }); } + +function displayQsl(id) { + $.ajax({ + url: base_url + 'index.php/qsl/viewQsl', + type: 'post', + data: { + id: id, + }, + success: function (html) { + BootstrapDialog.show({ + title: 'QSL Card', + size: BootstrapDialog.SIZE_WIDE, + cssClass: 'lookup-dialog', + nl2br: false, + message: html, + onshown: function(dialog) { + + }, + buttons: [{ + label: 'Close', + action: function (dialogItself) { + dialogItself.close(); + } + }] + }); + } + }); +} diff --git a/assets/js/sections/contesting.js b/assets/js/sections/contesting.js index c2b0b2d9..9675cbcb 100644 --- a/assets/js/sections/contesting.js +++ b/assets/js/sections/contesting.js @@ -211,10 +211,19 @@ $('#start_date').change(function() { $("#callsign").keyup(function () { var call = $(this).val(); if (call.length >= 3) { - $.get('lookup/scp/' + call.toUpperCase(), function (result) { - $('.callsign-suggestions').text(result); - highlight(call.toUpperCase()); - }); + + $.ajax({ + url: 'lookup/scp', + method: 'POST', + data: { + callsign: $(this).val().toUpperCase() + }, + success: function(result) { + $('.callsign-suggestions').text(result); + highlight(call.toUpperCase()); + } + }); + checkIfWorkedBefore(); var qTable = $('.qsotable').DataTable(); qTable.search(call).draw(); diff --git a/assets/js/sections/gridmap.js b/assets/js/sections/gridmap.js index cec89f61..06af4d2f 100644 --- a/assets/js/sections/gridmap.js +++ b/assets/js/sections/gridmap.js @@ -40,6 +40,7 @@ function gridPlot(form) { sat: $("#sats").val(), }, success: function (data) { + $('.cohidden').show(); $(".ld-ext-right").removeClass('running'); $(".ld-ext-right").prop('disabled', false); $('#plot').prop("disabled", false); @@ -89,6 +90,9 @@ function gridPlot(form) { legend.addTo(map); var maidenhead = L.maidenhead().addTo(map); + map.on('mousemove', onMapMove); + map.on('click', onMapClick); + }, error: function (data) { }, @@ -113,7 +117,7 @@ function spawnGridsquareModal(loc_4char) { nl2br: false, message: html, onshown: function(dialog) { - + $('[data-toggle="tooltip"]').tooltip(); $('.contacttable').DataTable({ "pageLength": 25, @@ -142,4 +146,8 @@ function spawnGridsquareModal(loc_4char) { }); } }); -} \ No newline at end of file +} + +$(document).ready(function(){ + gridPlot(this.form); +}) diff --git a/assets/js/sections/hrdlog.js b/assets/js/sections/hrdlog.js new file mode 100644 index 00000000..9679c50a --- /dev/null +++ b/assets/js/sections/hrdlog.js @@ -0,0 +1,59 @@ +$(function () { + $('#datetimepicker5').datetimepicker({ + format: 'DD/MM/YYYY', + }); +}); + +$(function () { + $('#datetimepicker6').datetimepicker({ + format: 'DD/MM/YYYY', + }); +}); + +function ExportHrd(station_id) { + if ($(".alert").length > 0) { + $(".alert").remove(); + } + if ($(".errormessages").length > 0) { + $(".errormessages").remove(); + } + $(".ld-ext-right").addClass('running'); + $(".ld-ext-right").prop('disabled', true); + + $.ajax({ + url: base_url + 'index.php/hrdlog/upload_station', + type: 'post', + data: {'station_id': station_id}, + success: function (data) { + $(".ld-ext-right").removeClass('running'); + $(".ld-ext-right").prop('disabled', false); + if (data.status == 'OK') { + $.each(data.info, function(index, value){ + $('#modcount'+value.station_id).html(value.modcount); + $('#notcount'+value.station_id).html(value.notcount); + $('#totcount'+value.station_id).html(value.totcount); + }); + $(".card-body").append(''); + } + else { + $(".card-body").append(''); + } + + if (data.errormessages.length > 0) { + $(".card-body").append('' + + '

    \n' + + ' \n' + + '

    \n' + + '
    \n' + + '
    \n' + + '
    \n' + + '
    '); + $.each(data.errormessages, function(index, value) { + $(".errors").append('
  • ' + value); + }); + } + } + }); +} diff --git a/assets/js/sections/logbookadvanced.js b/assets/js/sections/logbookadvanced.js index f447c8d2..5a639c5b 100644 --- a/assets/js/sections/logbookadvanced.js +++ b/assets/js/sections/logbookadvanced.js @@ -43,9 +43,9 @@ function updateRow(qso) { cells.eq(c++).html(qso.lotw); } cells.eq(c++).text(qso.qslMessage); - cells.eq(c++).text(qso.dxcc); + cells.eq(c++).html(qso.dxcc); cells.eq(c++).text(qso.state); - cells.eq(c++).text(qso.cqzone); + cells.eq(c++).html(qso.cqzone); cells.eq(c++).html(qso.iota); $('[data-toggle="tooltip"]').tooltip(); @@ -73,7 +73,7 @@ function loadQSOTable(rows) { var table = $('#qsoList').DataTable(); table.clear(); - + for (i = 0; i < rows.length; i++) { let qso = rows[i]; @@ -102,7 +102,7 @@ function loadQSOTable(rows) { data.push(qso.state); data.push(qso.cqzone); data.push(qso.iota); - + let createdRow = table.row.add(data).index(); table.rows(createdRow).nodes().to$().data('qsoID', qso.qsoID); table.row(createdRow).node().id = 'qsoID-' + qso.qsoID; @@ -187,7 +187,16 @@ $(document).ready(function () { gridsquare: this.gridsquare.value, state: this.state.value, qsoresults: this.qsoResults.value, - sats: this.sats.value + sats: this.sats.value, + cqzone: this.cqzone.value, + lotwSent: this.lotwSent.value, + lotwReceived: this.lotwReceived.value, + eqslSent: this.eqslSent.value, + eqslReceived: this.eqslReceived.value, + qslvia: $('[name="qslviainput"]').val(), + sota: this.sota.value, + pota: this.pota.value, + wwff: this.wwff.value, }, dataType: 'json', success: function (data) { @@ -355,6 +364,98 @@ $(document).ready(function () { handleQslReceived('Y','D', 'receivedDirect'); }); + $('#searchGridsquare').click(function (event) { + quickSearch('gridsquare'); + }); + + $('#searchState').click(function (event) { + quickSearch('state'); + }); + + $('#searchIota').click(function (event) { + quickSearch('iota'); + }); + + $('#searchDxcc').click(function (event) { + quickSearch('dxcc'); + }); + + $('#searchCallsign').click(function (event) { + quickSearch('dx'); + }); + + $('#searchCqZone').click(function (event) { + quickSearch('cqzone'); + }); + + $('#searchMode').click(function (event) { + quickSearch('mode'); + }); + + $('#searchBand').click(function (event) { + quickSearch('band'); + }); + + $('#searchSota').click(function (event) { + quickSearch('sota'); + }); + + $('#searchWwff').click(function (event) { + quickSearch('wwff'); + }); + + $('#searchPota').click(function (event) { + quickSearch('pota'); + }); + + function quickSearch(type) { + var elements = $('#qsoList tbody input:checked'); + var nElements = elements.length; + if (nElements == 0) { + return; + } + if (nElements > 1) { + BootstrapDialog.alert({ + title: 'WARNING', + message: 'Only 1 row can be selected for Quickfilter!', + type: BootstrapDialog.TYPE_WARNING, + closable: false, + draggable: false, + callback: function (result) { + } + }); + } + var offset = 0; + + if (!$(".eqslconfirmation")[0]){ + offset--; + } + if (!$(".lotwconfirmation")[0]){ + offset--; + } + elements.each(function() { + var currentRow = $(this).first().closest('tr'); + var col1 = ''; + switch (type) { + case 'dxcc': var tdoffset = (offset + 16); col1 = currentRow.find("td:eq("+tdoffset+")").html(); col1 = col1.match(/\d/g); col1 = col1.join(""); break; + case 'cqzone': var tdoffset = (offset + 18); col1 = currentRow.find("td:eq("+tdoffset+")").text(); break; + case 'iota': var tdoffset = (offset + 19); col1 = currentRow.find("td:eq("+tdoffset+")").text(); col1 = col1.trim(); break; + case 'state': var tdoffset = (offset + 17); col1 = currentRow.find("td:eq("+tdoffset+")").text(); break; + case 'dx': col1 = currentRow.find("td:eq(3)").text(); col1 = col1.match(/^([^\s]+)/gm); break; + case 'gridsquare': col1 = $(currentRow).find('#dxgrid').text(); col1 = col1.substring(0, 4); break; + case 'sota': col1 = $(currentRow).find('#dxsota').text(); break; + case 'wwff': col1 = $(currentRow).find('#dxwwff').text(); break; + case 'pota': col1 = $(currentRow).find('#dxpota').text(); break; + case 'mode': col1 = currentRow.find("td:eq(4)").text(); break; + case 'band': col1 = currentRow.find("td:eq(7)").text(); col1 = col1.match(/\S\w*/); break; + } + if (col1.length == 0) return; + $('#searchForm').trigger("reset"); + $("#"+type).val(col1); + $('#searchForm').submit(); + }); + } + $('#printLabel').click(function (event) { var elements = $('#qsoList tbody input:checked'); var nElements = elements.length; @@ -380,10 +481,10 @@ $(document).ready(function () { return xhr; }, success: function(data) { - if(data){ + if(data){ var file = new Blob([data], {type: 'application/pdf'}); var fileURL = URL.createObjectURL(file); - window.open(fileURL); + window.open(fileURL); } $.each(id_list, function(k, v) { unselectQsoID(this); diff --git a/assets/js/sections/qso.js b/assets/js/sections/qso.js index b72576ce..e6d4e998 100644 --- a/assets/js/sections/qso.js +++ b/assets/js/sections/qso.js @@ -329,6 +329,9 @@ function reset_fields() { $('#country').val(""); $('#continent').val(""); $('#lotw_info').text(""); + $('#lotw_info').removeClass("lotw_info_red"); + $('#lotw_info').removeClass("lotw_info_yellow"); + $('#lotw_info').removeClass("lotw_info_orange"); $('#qrz_info').text(""); $('#hamqth_info').text(""); $('#sota_info').text(""); @@ -457,6 +460,17 @@ $("#callsign").focusout(function() { if(result.lotw_member == "active") { $('#lotw_info').text("LoTW"); + if (result.lotw_days > 365) { + $('#lotw_info').addClass('lotw_info_red'); + } else if (result.lotw_days > 30) { + $('#lotw_info').addClass('lotw_info_orange'); + $lotw_hint = ' lotw_info_orange'; + } else if (result.lotw_days > 7) { + $('#lotw_info').addClass('lotw_info_yellow'); + } + $('#lotw_info').attr('data-toggle',"tooltip"); + $('#lotw_info').attr('data-original-title',"LoTW User. Last upload was "+result.lotw_days+" days ago"); + $('[data-toggle="tooltip"]').tooltip(); } $('#qrz_info').html(''); $('#qrz_info').attr('title', 'Lookup '+find_callsign+' info on qrz.com'); @@ -774,12 +788,19 @@ $("#callsign").on("keypress", function(e) { // On Key up check and suggest callsigns $("#callsign").keyup(function() { if ($(this).val().length >= 3) { - $('.callsign-suggest').show(); - $.get('lookup/scp/' + $(this).val().toUpperCase(), function(result) { - $('.callsign-suggestions').text(result); - }); + $('.callsign-suggest').show(); + $.ajax({ + url: 'lookup/scp', + method: 'POST', + data: { + callsign: $(this).val().toUpperCase() + }, + success: function(result) { + $('.callsign-suggestions').text(result); + } + }); } -}); + }); //Reset QSO form Fields function function resetDefaultQSOFields() { diff --git a/install/config/config.php b/install/config/config.php index c1f01bdb..9a17f463 100644 --- a/install/config/config.php +++ b/install/config/config.php @@ -14,7 +14,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); */ $config['app_name'] = "Cloudlog"; -$config['app_version'] = "2.4.4"; +$config['app_version'] = "2.4.5"; $config['directory'] = "%directory%"; $config['callbook'] = "hamqth"; // Options are hamqth or qrz diff --git a/install/index.php b/install/index.php index 55d2ecdf..cc0e5d8b 100644 --- a/install/index.php +++ b/install/index.php @@ -131,8 +131,8 @@ if($_POST) {
    Configuration Settings - " class="input_text" name="directory" /> - " class="input_text" name="websiteurl" /> + " class="input_text" name="directory" /> + " class="input_text" name="websiteurl" />
    diff --git a/src/QSLManager/QSO.php b/src/QSLManager/QSO.php index 98a4a614..3b00aa06 100644 --- a/src/QSLManager/QSO.php +++ b/src/QSLManager/QSO.php @@ -15,7 +15,7 @@ class QSO private string $dx; private string $mode; private string $submode; - private string $band; + private ?string $band; private string $bandRX; private string $rstR; private string $rstS; @@ -45,6 +45,8 @@ class QSO private string $dxSigInfo; private string $dxDARCDOK; private string $dxSOTAReference; + private string $dxPOTAReference; + private string $dxWWFFReference; /** @var string[] */ private string $dxVUCCGridsquares; private string $QSLMsg; @@ -107,6 +109,8 @@ class QSO 'COL_MY_SOTA_REF', 'COL_MY_VUCC_GRIDS', 'COL_SOTA_REF', + 'COL_POTA_REF', + 'COL_WWFF_REF', 'COL_SUBMODE', 'COL_VUCC_GRIDS', 'COL_CQZ', @@ -125,7 +129,7 @@ class QSO $this->qsoID = $data['COL_PRIMARY_KEY']; - $CI =& get_instance(); + $CI =& get_instance(); // Get Date format if($CI->session->userdata('user_date_format')) { // If Logged in and session exists @@ -134,7 +138,7 @@ class QSO // Get Default date format from /config/cloudlog.php $custom_date_format = $CI->config->item('qso_date_format'); } - $this->qsoDateTime = date($custom_date_format . " H:i", strtotime($data['COL_TIME_ON'])); + $this->qsoDateTime = date($custom_date_format . " H:i", strtotime($data['COL_TIME_ON'])); $this->de = $data['COL_STATION_CALLSIGN']; $this->dx = $data['COL_CALL']; @@ -171,6 +175,8 @@ class QSO $this->dxDARCDOK = $data['COL_DARC_DOK'] ?? ''; $this->dxSOTAReference = $data['COL_SOTA_REF'] ?? ''; + $this->dxPOTAReference = $data['COL_POTA_REF'] ?? ''; + $this->dxWWFFReference = $data['COL_WWFF_REF'] ?? ''; $this->dxVUCCGridsquares = $data['COL_VUCC_GRIDS'] ?? ''; @@ -183,14 +189,14 @@ class QSO $this->QSLSent = ($data['COL_QSL_SENT'] === null) ? '' : $data['COL_QSL_SENT']; $this->QSLSentVia = ($data['COL_QSL_SENT_VIA'] === null) ? '' : $data['COL_QSL_SENT_VIA']; $this->QSLVia = ($data['COL_QSL_VIA'] === null) ? '' : $data['COL_QSL_VIA']; - + $this->qsl = $this->getQslString($data, $custom_date_format); $this->lotw = $this->getLotwString($data, $custom_date_format); $this->eqsl = $this->getEqslString($data, $custom_date_format); - - $this->cqzone = ($data['COL_CQZ'] === null) ? '' : $data['COL_CQZ']; + + $this->cqzone = ($data['COL_CQZ'] === null) ? '' : ''.$data['COL_CQZ'].''; $this->state = ($data['COL_STATE'] === null) ? '' :$data['COL_STATE']; - $this->dxcc = ($data['name'] === null) ? '- NONE -' : ucwords(strtolower($data['name']), "- (/"); + $this->dxcc = ($data['name'] === null) ? '- NONE -' : ''.ucwords(strtolower($data['name']), "- (/").''; $this->iota = ($data['COL_IOTA'] === null) ? '' : $this->getIotaLink($data['COL_IOTA']); if (array_key_exists('end', $data)) { $this->end = ($data['end'] === null) ? null : DateTime::createFromFormat("Y-m-d", $data['end'], new DateTimeZone('UTC')); @@ -227,7 +233,7 @@ class QSO */ function getQSLString($data, $custom_date_format): string { - $CI =& get_instance(); + $CI =& get_instance(); $qslstring = 'lang->line('general_word_qslcard_electronic').")"; break; } - } + } $qslstring .= '">▲lang->line('general_word_qslcard_electronic').")"; break; } - } + } $qslstring .= '">▼'; + if ($data['qslcount'] != null) { + $qslstring .= ' '; + } return $qslstring; } - + /** * @return string */ function getLotwString($data, $custom_date_format): string { - $CI =& get_instance(); + $CI =& get_instance(); $lotwstring = 'lang->line('lotw_short')." ".$CI->lang->line('general_word_sent'); - if ($data['COL_LOTW_QSLSDATE'] != null) { - $timestamp = strtotime($data['COL_LOTW_QSLSDATE']); - $lotwstring .= " ". ($timestamp != '' ? date($custom_date_format, $timestamp) : ''); - } - $lotwstring .= "\" data-toggle=\"tooltip\""; - } + if ($data['COL_LOTW_QSL_SENT'] == "Y") { + $lotwstring .= "data-original-title=\"" . $CI->lang->line('lotw_short')." ".$CI->lang->line('general_word_sent'); + if ($data['COL_LOTW_QSLSDATE'] != null) { + $timestamp = strtotime($data['COL_LOTW_QSLSDATE']); + $lotwstring .= " ". ($timestamp != '' ? date($custom_date_format, $timestamp) : ''); + } + $lotwstring .= "\" data-toggle=\"tooltip\""; + } $lotwstring .= ' class="lotw-' . (($data['COL_LOTW_QSL_SENT']=='Y') ? 'green' : 'red') . '">▲'; $lotwstring .= 'lang->line('lotw_short') ." ". $CI->lang->line('general_word_received'); - - if ($data['COL_LOTW_QSLRDATE'] != null) { - $timestamp = strtotime($data['COL_LOTW_QSLRDATE']); - $lotwstring .= " ". ($timestamp != '' ? date($custom_date_format, $timestamp) : ''); - } - - $lotwstring .= "\" data-toggle=\"tooltip\""; - } + if ($data['COL_LOTW_QSL_RCVD'] == "Y") { + $lotwstring .= "data-original-title=\"". $CI->lang->line('lotw_short') ." ". $CI->lang->line('general_word_received'); + + if ($data['COL_LOTW_QSLRDATE'] != null) { + $timestamp = strtotime($data['COL_LOTW_QSLRDATE']); + $lotwstring .= " ". ($timestamp != '' ? date($custom_date_format, $timestamp) : ''); + } + + $lotwstring .= "\" data-toggle=\"tooltip\""; + } $lotwstring .= ' class="lotw-' . (($data['COL_LOTW_QSL_RCVD']=='Y') ? 'green':'red') . '">▼'; @@ -362,32 +371,32 @@ class QSO */ function getEqslString($data, $custom_date_format): string { - $CI =& get_instance(); + $CI =& get_instance(); $eqslstring = 'lang->line('eqsl_short')." ".$CI->lang->line('general_word_sent'); - - if ($data['COL_EQSL_QSLSDATE'] != null) { - $timestamp = strtotime($data['COL_EQSL_QSLSDATE']); - $eqslstring .= " ".($timestamp!=''?date($custom_date_format, $timestamp):''); - } - - $eqslstring .= "\" data-toggle=\"tooltip\""; - } - + if ($data['COL_EQSL_QSL_SENT'] == "Y") { + $eqslstring .= "data-original-title=\"".$CI->lang->line('eqsl_short')." ".$CI->lang->line('general_word_sent'); + + if ($data['COL_EQSL_QSLSDATE'] != null) { + $timestamp = strtotime($data['COL_EQSL_QSLSDATE']); + $eqslstring .= " ".($timestamp!=''?date($custom_date_format, $timestamp):''); + } + + $eqslstring .= "\" data-toggle=\"tooltip\""; + } + $eqslstring .= ' class="eqsl-' . (($data['COL_EQSL_QSL_SENT'] =='Y') ? 'green':'red') . '">▲lang->line('eqsl_short')." ".$CI->lang->line('general_word_received'); - - if ($data['COL_EQSL_QSLRDATE'] != null) { - $timestamp = strtotime($data['COL_EQSL_QSLRDATE']); - $eqslstring .= " ".($timestamp!=''?date($custom_date_format, $timestamp):''); - } - $eqslstring .= "\" data-toggle=\"tooltip\""; - } + if ($data['COL_EQSL_QSL_RCVD'] == "Y") { + $eqslstring .= "data-original-title=\"".$CI->lang->line('eqsl_short')." ".$CI->lang->line('general_word_received'); + + if ($data['COL_EQSL_QSLRDATE'] != null) { + $timestamp = strtotime($data['COL_EQSL_QSLRDATE']); + $eqslstring .= " ".($timestamp!=''?date($custom_date_format, $timestamp):''); + } + $eqslstring .= "\" data-toggle=\"tooltip\""; + } $eqslstring .= ' class="eqsl-' . (($data['COL_EQSL_QSL_RCVD'] =='Y')?'green':'red') . '">'; @@ -634,6 +643,22 @@ class QSO return $this->dxSOTAReference; } + /** + * @return string + */ + public function getDxPOTAReference(): string + { + return $this->dxPOTAReference; + } + + /** + * @return string + */ + public function getWWFFReference(): string + { + return $this->dxWWFFReference; + } + /** * @return string[] */ @@ -838,12 +863,18 @@ class QSO { $refs = []; if ($this->dxVUCCGridsquares !== '') { - $refs[] = $this->dxVUCCGridsquares . ' ' .$this->getQrbLink($this->stationGridsquare, $this->dxVUCCGridsquares, $this->dxGridsquare); + $refs[] = '' . $this->dxVUCCGridsquares . ' ' .$this->getQrbLink($this->stationGridsquare, $this->dxVUCCGridsquares, $this->dxGridsquare); } else if ($this->dxGridsquare !== '') { - $refs[] = $this->dxGridsquare . ' ' .$this->getQrbLink($this->stationGridsquare, $this->dxVUCCGridsquares, $this->dxGridsquare); + $refs[] = '' . $this->dxGridsquare . ' ' .$this->getQrbLink($this->stationGridsquare, $this->dxVUCCGridsquares, $this->dxGridsquare); } if ($this->dxSOTAReference !== '') { - $refs[] = "SOTA:" . $this->dxSOTAReference; + $refs[] = "SOTA: " . '' . $this->dxSOTAReference. ''; + } + if ($this->dxPOTAReference !== '') { + $refs[] = "POTA: " . '' . $this->dxPOTAReference. ''; + } + if ($this->dxWWFFReference !== '') { + $refs[] = "WWFF: " . '' . $this->dxWWFFReference. ''; } if ($this->dxSig !== '') { $refs[] = $this->dxSig . ":" . $this->dxSigInfo; @@ -961,7 +992,7 @@ class QSO private function getIotaLink($iota) : string { if ($iota !== '') { - return '' . $iota . ''; + return ''.$iota.' '; } return ''; }