From 120845e5e029195059ec4e154e0f3cbaf3a97750 Mon Sep 17 00:00:00 2001 From: int2001 Date: Sun, 16 Nov 2025 09:58:28 +0000 Subject: [PATCH 1/3] Move creation to model and fix UUID/null Handling --- application/controllers/Stationsetup.php | 68 +++---------------- application/models/Stationsetup_model.php | 82 ++++++++++++++++++----- 2 files changed, 76 insertions(+), 74 deletions(-) diff --git a/application/controllers/Stationsetup.php b/application/controllers/Stationsetup.php index 30378ebe2..89f555e83 100644 --- a/application/controllers/Stationsetup.php +++ b/application/controllers/Stationsetup.php @@ -543,8 +543,8 @@ class Stationsetup extends CI_Controller { public function import_locations(){ if (empty($_FILES['file']['tmp_name'])) { $this->output - ->set_content_type('application/json') - ->set_output(json_encode(['status' => 'error', 'message' => 'No file uploaded'])); + ->set_content_type('application/json') + ->set_output(json_encode(['status' => 'error', 'message' => 'No file uploaded'])); return; } @@ -553,68 +553,22 @@ class Stationsetup extends CI_Controller { if ($locations === null) { $this->output - ->set_content_type('application/json') - ->set_output(json_encode(['status' => 'error', 'message' => 'Invalid JSON file'])); + ->set_content_type('application/json') + ->set_output(json_encode(['status' => 'error', 'message' => 'Invalid JSON file'])); return; } // Load your model $this->load->model('stationsetup_model'); - $imported = 0; - foreach ($locations as $loc) { - if ($imported >= 1000){ - $this->output - ->set_content_type('application/json') - ->set_output(json_encode(['status' => 'success', 'message' => "$imported locations imported. Maximum limit of 1000 locations reached."])); - return; // Prevent importing more than 1000 locations at once - } - // Data for station_profile - $dbdata = [ - 'station_active' => 0, - 'station_profile_name' => ((isset($loc['station_profile_name']) && $loc['station_profile_name'] != "") ? xss_clean($loc['station_profile_name']) : ''), - 'station_gridsquare' => ((isset($loc['station_gridsquare']) && $loc['station_gridsquare'] != "") ? xss_clean($loc['station_gridsquare']) : ''), - 'station_city' => ((isset($loc['station_city']) && $loc['station_city'] != "") ? xss_clean($loc['station_city']) : ''), - 'station_iota' => ((isset($loc['station_iota']) && $loc['station_iota'] != "") ? xss_clean($loc['station_iota']) : ''), - 'station_sota' => ((isset($loc['station_sota']) && $loc['station_sota'] != "") ? xss_clean($loc['station_sota']) : ''), - 'station_callsign' => ((isset($loc['station_callsign']) && $loc['station_callsign'] != "") ? xss_clean($loc['station_callsign']) : null), - 'station_power' => ((isset($loc['station_power']) && $loc['station_power'] != "") ? xss_clean($loc['station_power']) : null), - 'station_dxcc' => ((isset($loc['station_dxcc']) && $loc['station_dxcc'] != "") ? xss_clean($loc['station_dxcc']) : null), - 'station_cq' => ((isset($loc['station_cq']) && $loc['station_cq'] != "") ? xss_clean($loc['station_cq']) : null), - 'station_itu' => ((isset($loc['station_itu']) && $loc['station_itu'] != "") ? xss_clean($loc['station_itu']) : null), - 'station_sig' => ((isset($loc['station_sig']) && $loc['station_sig'] != "") ? xss_clean($loc['station_sig']) : null), - 'station_sig_info' => ((isset($loc['station_sig_info']) && $loc['station_sig_info'] != "") ? xss_clean($loc['station_sig_info']) : null), - 'station_wwff' => ((isset($loc['station_wwff']) && $loc['station_wwff'] != "") ? xss_clean($loc['station_wwff']) : null), - 'station_pota' => ((isset($loc['station_pota']) && $loc['station_pota'] != "") ? xss_clean($loc['station_pota']) : null), - 'state' => ((isset($loc['state']) && $loc['state'] != "") ? xss_clean($loc['state']) : null), - 'station_cnty' => ((isset($loc['station_cnty']) && $loc['station_cnty'] != "") ? xss_clean($loc['station_cnty']) : null), - 'qrzrealtime' => ((isset($loc['qrzrealtime']) && $loc['qrzrealtime'] != "") ? xss_clean($loc['qrzrealtime']) : 0), - 'oqrs' => ((isset($loc['oqrs']) && $loc['oqrs'] != "") ? xss_clean($loc['oqrs']) : 0), - 'oqrs_text' => ((isset($loc['oqrs_text']) && $loc['oqrs_text'] != "") ? xss_clean($loc['oqrs_text']) : null), - 'oqrs_email' => ((isset($loc['oqrs_email']) && $loc['oqrs_email'] != "") ? xss_clean($loc['oqrs_email']) : null), - 'webadifrealtime' => ((isset($loc['webadifrealtime']) && $loc['webadifrealtime'] != "") ? xss_clean($loc['webadifrealtime']) : null), - 'clublogignore' => ((isset($loc['clublogignore']) && $loc['clublogignore'] != "") ? xss_clean($loc['clublogignore']) : 1), - 'clublogrealtime' => ((isset($loc['clublogrealtime']) && $loc['clublogrealtime'] != "") ? xss_clean($loc['clublogrealtime']) : 0), - 'hrdlogrealtime' => ((isset($loc['hrdlogrealtime']) && $loc['hrdlogrealtime'] != "") ? xss_clean($loc['hrdlogrealtime']) : 0), - 'hrdlog_username' => ((isset($loc['hrdlog_username']) && $loc['hrdlog_username'] != "") ? xss_clean($loc['hrdlog_username']) : null), - 'eqslqthnickname' => ((isset($loc['eqslqthnickname']) && $loc['eqslqthnickname'] != "") ? xss_clean($loc['eqslqthnickname']) : null), - 'webadifapiurl' => 'https://qo100dx.club/api', - 'station_uuid' => xss_clean($loc['station_uuid'] ?? null), - 'user_id' => $this->session->userdata('user_id'), - ]; - - // Data for user_options - $optiondata = [ - 'eqsl_default_qslmsg' => xss_clean($loc['eqsl_default_qslmsg'] ?? null), - ]; - - // Insert or update location in DB - $imported += $this->stationsetup_model->save_location($dbdata, $optiondata); + $imported = $this->stationsetup_model->import_locations_parse($locations); + if (($imported[0] ?? '0') == 'limit') { + $this->output->set_content_type('application/json')->set_output(json_encode(['status' => 'success', 'message' => ($imported[1] ?? '0')." locations imported. Maximum limit of 1000 locations reached."])); + } else { + $this->output + ->set_content_type('application/json') + ->set_output(json_encode(['status' => 'success', 'message' => ($imported[1] ?? '0')." locations imported."])); } - - $this->output - ->set_content_type('application/json') - ->set_output(json_encode(['status' => 'success', 'message' => "$imported locations imported."])); } } diff --git a/application/models/Stationsetup_model.php b/application/models/Stationsetup_model.php index 1ad4e3986..ae1f1590c 100644 --- a/application/models/Stationsetup_model.php +++ b/application/models/Stationsetup_model.php @@ -258,6 +258,57 @@ class Stationsetup_model extends CI_Model { return $result; } + public function import_locations_parse($locations) { + $imported=0; + foreach ($locations as $loc) { + if ($imported >= 1000){ + return (array('limit',$imported."locations imported. Maximum limit of 1000 locations reached.")); // Prevent importing more than 1000 locations at once + } + // Data for station_profile + $dbdata = [ + 'station_active' => 0, + 'station_profile_name' => ((isset($loc['station_profile_name']) && $loc['station_profile_name'] != "") ? xss_clean($loc['station_profile_name']) : ''), + 'station_gridsquare' => ((isset($loc['station_gridsquare']) && $loc['station_gridsquare'] != "") ? xss_clean($loc['station_gridsquare']) : ''), + 'station_city' => ((isset($loc['station_city']) && $loc['station_city'] != "") ? xss_clean($loc['station_city']) : ''), + 'station_iota' => ((isset($loc['station_iota']) && $loc['station_iota'] != "") ? xss_clean($loc['station_iota']) : ''), + 'station_sota' => ((isset($loc['station_sota']) && $loc['station_sota'] != "") ? xss_clean($loc['station_sota']) : ''), + 'station_callsign' => ((isset($loc['station_callsign']) && $loc['station_callsign'] != "") ? xss_clean($loc['station_callsign']) : ''), + 'station_power' => ((isset($loc['station_power']) && $loc['station_power'] != "") ? xss_clean($loc['station_power']) : null), + 'station_dxcc' => ((isset($loc['station_dxcc']) && $loc['station_dxcc'] != "") ? xss_clean($loc['station_dxcc']) : null), + 'station_cq' => ((isset($loc['station_cq']) && $loc['station_cq'] != "") ? xss_clean($loc['station_cq']) : null), + 'station_itu' => ((isset($loc['station_itu']) && $loc['station_itu'] != "") ? xss_clean($loc['station_itu']) : null), + 'station_sig' => ((isset($loc['station_sig']) && $loc['station_sig'] != "") ? xss_clean($loc['station_sig']) : null), + 'station_sig_info' => ((isset($loc['station_sig_info']) && $loc['station_sig_info'] != "") ? xss_clean($loc['station_sig_info']) : null), + 'station_wwff' => ((isset($loc['station_wwff']) && $loc['station_wwff'] != "") ? xss_clean($loc['station_wwff']) : null), + 'station_pota' => ((isset($loc['station_pota']) && $loc['station_pota'] != "") ? xss_clean($loc['station_pota']) : null), + 'state' => ((isset($loc['state']) && $loc['state'] != "") ? xss_clean($loc['state']) : null), + 'station_cnty' => ((isset($loc['station_cnty']) && $loc['station_cnty'] != "") ? xss_clean($loc['station_cnty']) : null), + 'qrzrealtime' => ((isset($loc['qrzrealtime']) && $loc['qrzrealtime'] != "") ? xss_clean($loc['qrzrealtime']) : 0), + 'oqrs' => ((isset($loc['oqrs']) && $loc['oqrs'] != "") ? xss_clean($loc['oqrs']) : 0), + 'oqrs_text' => ((isset($loc['oqrs_text']) && $loc['oqrs_text'] != "") ? xss_clean($loc['oqrs_text']) : null), + 'oqrs_email' => ((isset($loc['oqrs_email']) && $loc['oqrs_email'] != "") ? xss_clean($loc['oqrs_email']) : null), + 'webadifrealtime' => ((isset($loc['webadifrealtime']) && $loc['webadifrealtime'] != "") ? xss_clean($loc['webadifrealtime']) : null), + 'clublogignore' => ((isset($loc['clublogignore']) && $loc['clublogignore'] != "") ? xss_clean($loc['clublogignore']) : 1), + 'clublogrealtime' => ((isset($loc['clublogrealtime']) && $loc['clublogrealtime'] != "") ? xss_clean($loc['clublogrealtime']) : 0), + 'hrdlogrealtime' => ((isset($loc['hrdlogrealtime']) && $loc['hrdlogrealtime'] != "") ? xss_clean($loc['hrdlogrealtime']) : 0), + 'hrdlog_username' => ((isset($loc['hrdlog_username']) && $loc['hrdlog_username'] != "") ? xss_clean($loc['hrdlog_username']) : null), + 'eqslqthnickname' => ((isset($loc['eqslqthnickname']) && $loc['eqslqthnickname'] != "") ? xss_clean($loc['eqslqthnickname']) : null), + 'webadifapiurl' => 'https://qo100dx.club/api', + 'station_uuid' => xss_clean($loc['station_uuid'] ?? ($this->db->query("SELECT UUID() as uuid")->row()->uuid)), // Generate one, if not present + 'user_id' => $this->session->userdata('user_id'), + ]; + + // Data for user_options + $optiondata = [ + 'eqsl_default_qslmsg' => xss_clean($loc['eqsl_default_qslmsg'] ?? null), + ]; + + // Insert or update location in DB + $imported += $this->save_location($dbdata, $optiondata); + } + return (array('OK',$imported)); + } + public function save_location($dbdata, $optiondata) { // Make sure we have the needed fields if (empty($dbdata['station_profile_name']) || empty($dbdata['station_callsign'])) { @@ -268,19 +319,20 @@ class Stationsetup_model extends CI_Model { $sql = " SELECT * FROM station_profile - WHERE station_profile_name = ? + WHERE (station_profile_name = ? AND station_callsign = ? - AND station_gridsquare = ? - AND station_city = ? - AND station_iota = ? - AND station_sota = ? - AND state = ? - AND station_cnty = ? - AND station_dxcc = ? - AND station_wwff = ? - AND station_pota = ? - AND station_sig = ? - AND station_sig_info = ? + AND station_gridsquare <=> ? + AND station_city <=> ? + AND station_iota <=> ? + AND station_sota <=> ? + AND state <=> ? + AND station_cnty <=> ? + AND station_dxcc <=> ? + AND station_wwff <=> ? + AND station_pota <=> ? + AND station_sig <=> ? + AND station_sig_info <=> ? + OR station_uuid <=> ?) AND user_id = ?; "; @@ -298,6 +350,7 @@ class Stationsetup_model extends CI_Model { $dbdata['station_pota'], $dbdata['station_sig'], $dbdata['station_sig_info'], + $dbdata['station_uuid'], $this->session->userdata('user_id') ]); @@ -306,11 +359,6 @@ class Stationsetup_model extends CI_Model { return 0; } else { // Insert new location - // Generate UUID if not provided - if (empty($dbdata['station_uuid'])) { - $dbdata['station_uuid'] = $this->db->query("SELECT UUID() as uuid")->row()->uuid; - } - $this->db->insert('station_profile', $dbdata); $location_id = $this->db->insert_id(); From ad417fd66f10ff2c692fc7a8de98465590709ce7 Mon Sep 17 00:00:00 2001 From: int2001 Date: Sun, 16 Nov 2025 11:06:56 +0000 Subject: [PATCH 2/3] API implemented --- application/controllers/Api.php | 41 +++++++++++++++++++++++ application/models/Stationsetup_model.php | 12 +++---- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/application/controllers/Api.php b/application/controllers/Api.php index 8ffcc2d9d..1f16567f5 100644 --- a/application/controllers/Api.php +++ b/application/controllers/Api.php @@ -117,6 +117,47 @@ class API extends CI_Controller { } } + function create_station($key = '') { + $this->load->model('api_model'); + if ($this->api_model->access($key) == "No Key Found" || $this->api_model->access($key) == "Key Disabled") { + $this->output->set_status_header(401)->set_content_type('application/json')->set_output(json_encode(['status' => 'error', 'message' => 'Auth Error, invalid key'])); + return; + } + try { + $raw = file_get_contents("php://input"); + if ($raw === false) { + throw new Exception("Failed to read input data"); + } + + if (empty($raw)) { + $this->output->set_status_header(400)->set_content_type('application/json')->set_output(json_encode(['status' => 'error', 'message' => 'No file uploaded'])); + return; + } + + $raw = preg_replace('#<([eE][oO][rR])>[\r\n\t]+#', '<$1>', $raw); + if ($raw === null) { + throw new Exception("Regex processing failed"); + } + + $locations = json_decode($raw, true); + + if ($locations === null) { + $this->output->set_status_header(400)->set_content_type('application/json')->set_output(json_encode(['status' => 'error', 'message' => 'Invalid JSON file'])); + return; + } + } catch (Exception $e) { + $this->output->set_status_header(500)->set_content_type('application/json')->set_output(json_encode(['status' => 'error', 'message' => 'Processing error: ' . $e->getMessage()])); + } + $this->load->model('stationsetup_model'); + $user_id = $this->api_model->key_userid($key); + $imported = $this->stationsetup_model->import_locations_parse($locations,$user_id); + if (($imported[0] ?? '0') == 'limit') { + $this->output->set_status_header(200)->set_content_type('application/json')->set_output(json_encode(['status' => 'success', 'message' => ($imported[1] ?? '0')." locations imported. Maximum limit of 1000 locations reached."])); + } else { + $this->output->set_status_header(201)->set_content_type('application/json')->set_output(json_encode(['status' => 'success', 'message' => ($imported[1] ?? '0')." locations imported."])); + } + } + function station_info($key = '') { $this->load->model('api_model'); $this->load->model('stations'); diff --git a/application/models/Stationsetup_model.php b/application/models/Stationsetup_model.php index ae1f1590c..360008151 100644 --- a/application/models/Stationsetup_model.php +++ b/application/models/Stationsetup_model.php @@ -258,7 +258,7 @@ class Stationsetup_model extends CI_Model { return $result; } - public function import_locations_parse($locations) { + public function import_locations_parse($locations, $user_id = null) { $imported=0; foreach ($locations as $loc) { if ($imported >= 1000){ @@ -295,7 +295,7 @@ class Stationsetup_model extends CI_Model { 'eqslqthnickname' => ((isset($loc['eqslqthnickname']) && $loc['eqslqthnickname'] != "") ? xss_clean($loc['eqslqthnickname']) : null), 'webadifapiurl' => 'https://qo100dx.club/api', 'station_uuid' => xss_clean($loc['station_uuid'] ?? ($this->db->query("SELECT UUID() as uuid")->row()->uuid)), // Generate one, if not present - 'user_id' => $this->session->userdata('user_id'), + 'user_id' => $user_id ?? $this->session->userdata('user_id') ]; // Data for user_options @@ -304,12 +304,12 @@ class Stationsetup_model extends CI_Model { ]; // Insert or update location in DB - $imported += $this->save_location($dbdata, $optiondata); + $imported += $this->save_location($dbdata, $optiondata, $user_id); } return (array('OK',$imported)); } - public function save_location($dbdata, $optiondata) { + public function save_location($dbdata, $optiondata, $user_id = null) { // Make sure we have the needed fields if (empty($dbdata['station_profile_name']) || empty($dbdata['station_callsign'])) { return false; @@ -351,7 +351,7 @@ class Stationsetup_model extends CI_Model { $dbdata['station_sig'], $dbdata['station_sig_info'], $dbdata['station_uuid'], - $this->session->userdata('user_id') + $user_id ?? $this->session->userdata('user_id') ]); if ($query->num_rows() > 0) { @@ -364,7 +364,7 @@ class Stationsetup_model extends CI_Model { if (!empty(trim($optiondata['eqsl_default_qslmsg']))) { $this->load->model('user_options_model'); - $this->user_options_model->set_option('eqsl_default_qslmsg', 'key_station_id', array($location_id => $optiondata['eqsl_default_qslmsg'])); + $this->user_options_model->set_option('eqsl_default_qslmsg', 'key_station_id', array($location_id => $optiondata['eqsl_default_qslmsg']),($user_id ?? $this->session->userdata('user_id'))); } } From 1edb73ac26932695448076953695f4bf98742572 Mon Sep 17 00:00:00 2001 From: int2001 Date: Sun, 16 Nov 2025 11:15:03 +0000 Subject: [PATCH 3/3] Better handling --- application/controllers/Api.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/application/controllers/Api.php b/application/controllers/Api.php index 1f16567f5..60ee9a0f0 100644 --- a/application/controllers/Api.php +++ b/application/controllers/Api.php @@ -152,9 +152,13 @@ class API extends CI_Controller { $user_id = $this->api_model->key_userid($key); $imported = $this->stationsetup_model->import_locations_parse($locations,$user_id); if (($imported[0] ?? '0') == 'limit') { - $this->output->set_status_header(200)->set_content_type('application/json')->set_output(json_encode(['status' => 'success', 'message' => ($imported[1] ?? '0')." locations imported. Maximum limit of 1000 locations reached."])); + $this->output->set_status_header(201)->set_content_type('application/json')->set_output(json_encode(['status' => 'success', 'message' => ($imported[1] ?? '0')." locations imported. Maximum limit of 1000 locations reached."])); } else { - $this->output->set_status_header(201)->set_content_type('application/json')->set_output(json_encode(['status' => 'success', 'message' => ($imported[1] ?? '0')." locations imported."])); + if (($imported[1] ?? 0) == 0) { + $this->output->set_status_header(200)->set_content_type('application/json')->set_output(json_encode(['status' => 'dupe', 'message' => ($imported[1] ?? '0')." locations imported."])); + } else { + $this->output->set_status_header(201)->set_content_type('application/json')->set_output(json_encode(['status' => 'success', 'message' => ($imported[1] ?? '0')." locations imported."])); + } } }