From 1001647687c051c3422cd080851f474a4292e9af Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Tue, 18 Nov 2025 12:05:35 +0100 Subject: [PATCH 1/5] [ADIF Import] More fences for INVALID DATA --- application/models/Logbook_model.php | 34 ++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index a0779e0eb..5314684eb 100644 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -4706,7 +4706,7 @@ class Logbook_model extends CI_Model { // lotw_qslrdate can obly be valid if lotw_qsl_rcvd is one of the following values // ref: https://www.adif.org.uk/316/ADIF_316.htm#QSO_Field_LOTW_QSLRDATE $valid_lotw_rcvd = ['Y', 'I', 'V']; - if (($record['lotw_qslrdate'] ?? '') != '' && in_array(strtoupper($input_lotw_qsl_rcvd), $valid_lotw_rcvd)) { + if (($record['lotw_qslrdate'] ?? '') != '' && in_array(strtoupper($input_lotw_qsl_rcvd ?? ''), $valid_lotw_rcvd)) { if (validateADIFDate($record['lotw_qslrdate']) == true) { $input_lotw_qslrdate = $record['lotw_qslrdate']; } else { @@ -4777,10 +4777,24 @@ class Logbook_model extends CI_Model { $input_eqsl_qso_upload_status = 'Y'; $input_eqsl_qso_upload_date = $date = date("Y-m-d H:i:s", strtotime("now")); } else { - $input_eqsl_qso_upload_date = (!empty($record['eqsl_qslsdate'])) ? $record['eqsl_qslsdate'] : null; + if (validateADIFDate($record['eqsl_qslsdate'] ?? '') == false) { + $input_eqsl_qso_upload_date = null; + $my_error .= "Error QSO: Date: " . $time_on . " Callsign: " . $record['call'] . " ".__("the eqsl_qslsdate is invalid (YYYYMMDD)").": " . ($record['eqsl_qslsdate'] ?? '') . "
"; + } else { + $input_eqsl_qso_upload_date = (!empty($record['eqsl_qslsdate'])) ? $record['eqsl_qslsdate'] : null; + } $input_eqsl_qso_upload_status = (!empty($record['eqsl_qsl_sent'])) ? $record['eqsl_qsl_sent'] : ''; } + if (validateADIFDate($record['eqsl_qslrdate'] ?? '') == false) { + $input_eqsl_qslrdate = null; + $my_error .= "Error QSO: Date: " . $time_on . " Callsign: " . $record['call'] . " ".__("the eqsl_qslrdate is invalid (YYYYMMDD)").": " . ($record['eqsl_qslrdate'] ?? '') . "
"; + } else { + $input_eqsl_qslrdate = (!empty($record['eqsl_qslrdate'])) ? $record['eqsl_qslrdate'] : null; + } + + + if ($markDcl != null) { $input_dcl_qso_upload_status = 'Y'; $input_dcl_qso_upload_date = $date = date("Y-m-d H:i:s", strtotime("now")); @@ -4835,7 +4849,7 @@ class Logbook_model extends CI_Model { 'COL_EQ_CALL' => (!empty($record['eq_call'])) ? $record['eq_call'] : '', 'COL_EQSL_QSL_RCVD' => (!empty($record['eqsl_qsl_rcvd'])) ? $record['eqsl_qsl_rcvd'] : null, 'COL_EQSL_QSL_SENT' => $input_eqsl_qso_upload_status, - 'COL_EQSL_QSLRDATE' => (!empty($record['eqsl_qslrdate'])) ? $record['eqsl_qslrdate'] : null, + 'COL_EQSL_QSLRDATE' => $input_eqsl_qslrdate, 'COL_EQSL_QSLSDATE' => $input_eqsl_qso_upload_date, 'COL_EQSL_STATUS' => (!empty($record['eqsl_status'])) ? $record['eqsl_status'] : '', 'COL_EQSL_AG' => (!empty($record['eqsl_ag'])) ? $record['eqsl_ag'] : '', @@ -6177,6 +6191,16 @@ class Logbook_model extends CI_Model { } function validateADIFDate($date, $format = 'Ymd') { - $d = DateTime::createFromFormat($format, $date); - return $d && $d->format($format) == $date; + try { + $d = DateTime::createFromFormat($format, $date); + + // Check if parsing failed or if the formatted date doesn't match input + if (!$d || $d->format($format) !== $date) { + return false; + } + + return true; // Valid date + } catch (Exception $e) { + return false; // Catch unexpected errors + } } From 23b650d4aeb27d9dad0af99b68ab7c2ea553019d Mon Sep 17 00:00:00 2001 From: phl0 Date: Thu, 20 Nov 2025 11:59:38 +0100 Subject: [PATCH 2/5] Validate QSO date --- application/models/Logbook_model.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index 5314684eb..8f7725529 100644 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -4297,6 +4297,12 @@ class Logbook_model extends CI_Model { $my_error = ""; + if (validateADIFDate($record['qso_date']) != true) { + log_message("Error", "Trying to import QSO with invalid date: " . $record['qso_date']."."); + $returner['error']=__("QSO on")." ".$record['qso_date'].": ".__("You tried to import a QSO without valid date. This QSO wasn't imported. It's invalid") . "
"; + return($returner); + } + // Join date+time $time_on = date('Y-m-d', strtotime($record['qso_date'] ?? '1970-01-01')) . " " . date('H:i:s', strtotime($record['time_on'] ?? '00:00:00')); From 1f54cd8cda00332c1ceba02c7f2a6eb1c74214b5 Mon Sep 17 00:00:00 2001 From: phl0 Date: Fri, 21 Nov 2025 13:38:36 +0100 Subject: [PATCH 3/5] Apply LoTW verifications to eQSL also --- application/models/Logbook_model.php | 77 +++++++++++++++++----------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index 8f7725529..85d079972 100644 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -4717,8 +4717,6 @@ class Logbook_model extends CI_Model { $input_lotw_qslrdate = $record['lotw_qslrdate']; } else { $input_lotw_qslrdate = NULL; - $my_error .= "Error QSO: Date: " . $time_on . " Callsign: " . $record['call'] . " ".__("the lotw_qslrdate is invalid (YYYYMMDD)").": " . $record['lotw_qslrdate'] . "; " . __("LoTW Rcvd status will be reset.") . "
"; - $input_lotw_qsl_rcvd = NULL; } } else { $input_lotw_qslrdate = NULL; @@ -4742,13 +4740,56 @@ class Logbook_model extends CI_Model { $input_lotw_qslsdate = $record['lotw_qslsdate']; } else { $input_lotw_qslsdate = NULL; - $my_error .= "Error QSO: Date: " . $time_on . " Callsign: " . $record['call'] . " ".__("the lotw_qslsdate is invalid (YYYYMMDD)").": " . $record['lotw_qslsdate'] . "; " . __("LoTW Sent status will be reset.") . "
"; - $input_lotw_qsl_sent = NULL; } } else { $input_lotw_qslsdate = NULL; } + /** + * Validate eQSL Fields + */ + if (isset($record['eqsl_qsl_rcvd'])) { + $input_eqsl_qsl_rcvd = mb_strimwidth($record['eqsl_qsl_rcvd'], 0, 1); + } else { + $input_eqsl_qsl_rcvd = NULL; + } + + // eqsl_qslrdate can obly be valid if EQSL_QSL_RCVD is one of the following values + // ref: https://www.adif.org.uk/316/ADIF_316.htm#QSO_Field_EQSL_QSLRDATE + $valid_eqsl_rcvd = ['Y', 'I', 'V']; + if (($record['eqsl_qslrdate'] ?? '') != '' && in_array(strtoupper($input_eqsl_qsl_rcvd ?? ''), $valid_eqsl_rcvd)) { + if (validateADIFDate($record['eqsl_qslrdate']) == true) { + $input_eqsl_qslrdate = $record['eqsl_qslrdate']; + } else { + $input_eqsl_qslrdate = NULL; + } + } else { + $input_eqsl_qslrdate = NULL; + } + + if ($markEqsl != NULL) { + $input_eqsl_qsl_sent = 'Y'; + } elseif (isset($record['eqsl_qsl_sent'])) { + $input_eqsl_qsl_sent = mb_strimwidth($record['eqsl_qsl_sent'], 0, 1); + } else { + $input_eqsl_qsl_sent = NULL; + } + + // eqsl_qslsdate can obly be valid if eqsl_qsl_sent is one of the following values + // ref: https://www.adif.org.uk/316/ADIF_316.htm#QSO_Field_EQSL_QSLSDATE + $valid_eqsl_sent = ['Y', 'Q', 'I']; + if ($markEqsl != NULL) { + $input_eqsl_qslsdate = $date = date("Y-m-d H:i:s", strtotime("now")); + } elseif (($record['eqsl_qslsdate'] ?? '') != '' && in_array(strtoupper($input_eqsl_qsl_sent), $valid_eqsl_sent)) { + if (validateADIFDate($record['eqsl_qslsdate']) == true) { + $input_eqsl_qslsdate = $record['eqsl_qslsdate']; + } else { + $input_eqsl_qslsdate = NULL; + } + } else { + $input_eqsl_qslsdate = NULL; + } + // Get active station_id from station profile if one hasn't been provided if ($station_id == "" || $station_id == "0") { $this->load->model('stations'); @@ -4779,28 +4820,6 @@ class Logbook_model extends CI_Model { $input_qrzcom_qso_upload_status = (!empty($record['qrzcom_qso_upload_status'])) ? $record['qrzcom_qso_upload_status'] : ''; } - if ($markEqsl != null) { - $input_eqsl_qso_upload_status = 'Y'; - $input_eqsl_qso_upload_date = $date = date("Y-m-d H:i:s", strtotime("now")); - } else { - if (validateADIFDate($record['eqsl_qslsdate'] ?? '') == false) { - $input_eqsl_qso_upload_date = null; - $my_error .= "Error QSO: Date: " . $time_on . " Callsign: " . $record['call'] . " ".__("the eqsl_qslsdate is invalid (YYYYMMDD)").": " . ($record['eqsl_qslsdate'] ?? '') . "
"; - } else { - $input_eqsl_qso_upload_date = (!empty($record['eqsl_qslsdate'])) ? $record['eqsl_qslsdate'] : null; - } - $input_eqsl_qso_upload_status = (!empty($record['eqsl_qsl_sent'])) ? $record['eqsl_qsl_sent'] : ''; - } - - if (validateADIFDate($record['eqsl_qslrdate'] ?? '') == false) { - $input_eqsl_qslrdate = null; - $my_error .= "Error QSO: Date: " . $time_on . " Callsign: " . $record['call'] . " ".__("the eqsl_qslrdate is invalid (YYYYMMDD)").": " . ($record['eqsl_qslrdate'] ?? '') . "
"; - } else { - $input_eqsl_qslrdate = (!empty($record['eqsl_qslrdate'])) ? $record['eqsl_qslrdate'] : null; - } - - - if ($markDcl != null) { $input_dcl_qso_upload_status = 'Y'; $input_dcl_qso_upload_date = $date = date("Y-m-d H:i:s", strtotime("now")); @@ -4853,10 +4872,10 @@ class Logbook_model extends CI_Model { 'COL_DXCC' => $dxcc[0], 'COL_EMAIL' => (!empty($record['email'])) ? $record['email'] : '', 'COL_EQ_CALL' => (!empty($record['eq_call'])) ? $record['eq_call'] : '', - 'COL_EQSL_QSL_RCVD' => (!empty($record['eqsl_qsl_rcvd'])) ? $record['eqsl_qsl_rcvd'] : null, - 'COL_EQSL_QSL_SENT' => $input_eqsl_qso_upload_status, + 'COL_EQSL_QSL_RCVD' => $input_eqsl_qsl_rcvd, + 'COL_EQSL_QSL_SENT' => $input_eqsl_qsl_sent, 'COL_EQSL_QSLRDATE' => $input_eqsl_qslrdate, - 'COL_EQSL_QSLSDATE' => $input_eqsl_qso_upload_date, + 'COL_EQSL_QSLSDATE' => $input_eqsl_qslsdate, 'COL_EQSL_STATUS' => (!empty($record['eqsl_status'])) ? $record['eqsl_status'] : '', 'COL_EQSL_AG' => (!empty($record['eqsl_ag'])) ? $record['eqsl_ag'] : '', 'COL_FISTS' => (!empty($record['fists'])) ? $record['fists'] : null, From ed75916f890feb50932c802cd9d065692361bc62 Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Sat, 22 Nov 2025 13:41:37 +0100 Subject: [PATCH 4/5] Fix a null passing to strtoupper --- application/models/Logbook_model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index 85d079972..43f55192a 100644 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -4780,7 +4780,7 @@ class Logbook_model extends CI_Model { $valid_eqsl_sent = ['Y', 'Q', 'I']; if ($markEqsl != NULL) { $input_eqsl_qslsdate = $date = date("Y-m-d H:i:s", strtotime("now")); - } elseif (($record['eqsl_qslsdate'] ?? '') != '' && in_array(strtoupper($input_eqsl_qsl_sent), $valid_eqsl_sent)) { + } elseif (($record['eqsl_qslsdate'] ?? '') != '' && in_array(strtoupper($input_eqsl_qsl_sent ?? ''), $valid_eqsl_sent)) { if (validateADIFDate($record['eqsl_qslsdate']) == true) { $input_eqsl_qslsdate = $record['eqsl_qslsdate']; } else { From 817f6b822e509e4d4b19e85a32c1a5f683434f77 Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Sat, 22 Nov 2025 14:02:41 +0100 Subject: [PATCH 5/5] Added more info to the log message --- application/models/Logbook_model.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index 43f55192a..edd409386 100644 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -4298,7 +4298,7 @@ class Logbook_model extends CI_Model { $my_error = ""; if (validateADIFDate($record['qso_date']) != true) { - log_message("Error", "Trying to import QSO with invalid date: " . $record['qso_date']."."); + log_message("Error", "Trying to import QSO with invalid date: " . $record['qso_date']. " for station_id " . $station_id . ". Call: " . ($record['call'] ?? '') . " Mode: " . ($record['mode'] ?? '') . " Band: " . ($record['band'] ?? '')); $returner['error']=__("QSO on")." ".$record['qso_date'].": ".__("You tried to import a QSO without valid date. This QSO wasn't imported. It's invalid") . "
"; return($returner); } @@ -4357,7 +4357,7 @@ class Logbook_model extends CI_Model { if (($band ?? '') == '') { log_message("Error", "Trying to import QSO without Band for station_id " . $station_id . ". QSO Date/Time: " . $time_on . " at ".($record['freq'] ?? 'N/A')." Mode: " . ($record['mode'] ?? '') . " Call: " . ($record['call'] ?? '')); - $returner['error']=sprintf(__("QSO on %s: You tried to import a QSO without any given Band. This QSO wasn't imported. It's invalid"),$time_on); + $returner['error']=sprintf(__("QSO on %s: You tried to import a QSO without any given Band. This QSO wasn't imported. It's invalid"), $time_on); return($returner); }