diff --git a/application/config/migration.php b/application/config/migration.php index 180989269..68aae496b 100644 --- a/application/config/migration.php +++ b/application/config/migration.php @@ -22,7 +22,7 @@ | */ -$config['migration_version'] = 239; +$config['migration_version'] = 240; /* |-------------------------------------------------------------------------- diff --git a/application/controllers/Logbook.php b/application/controllers/Logbook.php index 2ed4684b2..3b5c7f98c 100644 --- a/application/controllers/Logbook.php +++ b/application/controllers/Logbook.php @@ -614,6 +614,12 @@ function view($id) $this->load->model('logbook_model'); $data['query'] = $this->logbook_model->get_qso($id); + // Guard against inaccessible or missing QSO to avoid calling result() on null + if (!$data['query'] || $data['query']->num_rows() === 0) { + $this->session->set_flashdata('notice', "You're not allowed to do that!"); + redirect('dashboard'); + return; + } $data['dxccFlag'] = $this->dxccflag->get($data['query']->result()[0]->COL_DXCC); if ($this->session->userdata('user_measurement_base') == NULL) { @@ -851,7 +857,9 @@ function partial($id) if (isset($callsign['callsign']['dxcc'])) { $this->load->model('logbook_model'); $entity = $this->logbook_model->get_entity($callsign['callsign']['dxcc']); - $callsign['callsign']['dxcc_name'] = $entity['name']; + if (is_array($entity) && isset($entity['name'])) { + $callsign['callsign']['dxcc_name'] = $entity['name']; + } } } elseif ($this->session->userdata('callbook_type') == "HamQTH") { // Load the HamQTH library @@ -884,7 +892,9 @@ function partial($id) if (isset($callsign['callsign']['dxcc'])) { $this->load->model('logbook_model'); $entity = $this->logbook_model->get_entity($callsign['callsign']['dxcc']); - $callsign['callsign']['dxcc_name'] = $entity['name']; + if (is_array($entity) && isset($entity['name'])) { + $callsign['callsign']['dxcc_name'] = $entity['name']; + } } if (isset($callsign['callsign']['error'])) { $callsign['error'] = $callsign['callsign']['error']; @@ -968,7 +978,9 @@ function search_result($id = "", $id2 = "") if (isset($data['callsign']['dxcc'])) { $this->load->model('logbook_model'); $entity = $this->logbook_model->get_entity($data['callsign']['dxcc']); - $data['callsign']['dxcc_name'] = $entity['name']; + if (is_array($entity) && isset($entity['name'])) { + $data['callsign']['dxcc_name'] = $entity['name']; + } } if (isset($data['callsign']['gridsquare'])) { $this->load->model('logbook_model'); @@ -1005,7 +1017,9 @@ function search_result($id = "", $id2 = "") if (isset($data['callsign']['dxcc'])) { $this->load->model('logbook_model'); $entity = $this->logbook_model->get_entity($data['callsign']['dxcc']); - $data['callsign']['dxcc_name'] = $entity['name']; + if (is_array($entity) && isset($entity['name'])) { + $data['callsign']['dxcc_name'] = $entity['name']; + } } if (isset($data['callsign']['error'])) { $data['error'] = $data['callsign']['error']; diff --git a/application/controllers/Logbooks.php b/application/controllers/Logbooks.php index 48156a4ba..ca422bedd 100644 --- a/application/controllers/Logbooks.php +++ b/application/controllers/Logbooks.php @@ -132,7 +132,7 @@ public function delete_relationship($logbook_id, $station_id) { } // Get station location details - $station = $this->stations->profile($station_id); + $station = $this->stations->profile_clean($station_id); if ($station) { $is_owner = $this->logbooks_model->is_logbook_owner($logbook_id); @@ -144,6 +144,8 @@ public function delete_relationship($logbook_id, $station_id) { } else { $this->session->set_flashdata('notice', 'You can only unlink your own station locations'); } + } else { + $this->session->set_flashdata('notice', 'Station location not found'); } redirect('logbooks/edit/'.$logbook_id); diff --git a/application/controllers/Qrz.php b/application/controllers/Qrz.php index 121cb299d..384edd376 100644 --- a/application/controllers/Qrz.php +++ b/application/controllers/Qrz.php @@ -536,10 +536,15 @@ private function loadFromFile($filepath) { } $call = str_replace("_","/",$record['call']); - $station_callsign = str_replace("_","/",$record['station_callsign']); + $station_callsign = str_replace("_","/",$record['station_callsign'] ?? ''); $band = $record['band'] ?? ''; // Ensure band exists $mode = $record['mode'] ?? ''; // Ensure mode exists + // Log if station_callsign is missing + if (!isset($record['station_callsign']) || $record['station_callsign'] === '') { + log_message('error', 'QRZ import: Missing station_callsign for QSO with callsign: ' . $call . ' on ' . $time_on); + } + // Add record data to batch $batch_data[] = [ 'time_on' => $time_on, diff --git a/application/migrations/240_tag_2_8_4.php b/application/migrations/240_tag_2_8_4.php new file mode 100644 index 000000000..580edf374 --- /dev/null +++ b/application/migrations/240_tag_2_8_4.php @@ -0,0 +1,30 @@ +db->where('option_name', 'version'); + $this->db->update('options', array('option_value' => '2.8.4')); + + // Trigger Version Info Dialog + $this->db->where('option_type', 'version_dialog'); + $this->db->where('option_name', 'confirmed'); + $this->db->update('user_options', array('option_value' => 'false')); + + } + + public function down() + { + $this->db->where('option_name', 'version'); + $this->db->update('options', array('option_value' => '2.8.3')); + } +} \ No newline at end of file diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index 897b958fe..be018dccd 100755 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -5026,15 +5026,39 @@ function wab_qso_details($wab) public function check_qso_is_accessible($id) { - // check if qso belongs to user + // Allow access if QSO belongs to current user OR + // if QSO's station is part of the user's active logbook (including shared permissions) + + // First: owner check (current behavior) $this->db->select($this->config->item('table_name') . '.COL_PRIMARY_KEY'); $this->db->join('station_profile', $this->config->item('table_name') . '.station_id = station_profile.station_id'); $this->db->where('station_profile.user_id', $this->session->userdata('user_id')); $this->db->where($this->config->item('table_name') . '.COL_PRIMARY_KEY', $id); - $query = $this->db->get($this->config->item('table_name')); - if ($query->num_rows() == 1) { + $ownerQuery = $this->db->get($this->config->item('table_name')); + if ($ownerQuery->num_rows() == 1) { return true; } + + // Second: shared-logbook check via active logbook relationships + $CI = &get_instance(); + $CI->load->model('logbooks_model'); + $activeLogbookId = $this->session->userdata('active_station_logbook'); + + // Ensure user has at least read access to the active logbook + if ($activeLogbookId && $CI->logbooks_model->check_logbook_is_accessible($activeLogbookId, 'read')) { + $logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($activeLogbookId); + + if (!empty($logbooks_locations_array)) { + $this->db->select($this->config->item('table_name') . '.COL_PRIMARY_KEY'); + $this->db->where_in($this->config->item('table_name') . '.station_id', $logbooks_locations_array); + $this->db->where($this->config->item('table_name') . '.COL_PRIMARY_KEY', $id); + $sharedQuery = $this->db->get($this->config->item('table_name')); + if ($sharedQuery->num_rows() == 1) { + return true; + } + } + } + return false; } diff --git a/application/models/Setup_model.php b/application/models/Setup_model.php index eae2abd90..61fd8790b 100644 --- a/application/models/Setup_model.php +++ b/application/models/Setup_model.php @@ -11,7 +11,12 @@ function getCountryCount() { function getLogbookCount() { $userid = xss_clean($this->session->userdata('user_id')); - $sql = 'select count(*) as count from station_logbooks where user_id =' . $userid; + // Count logbooks the user owns OR has been granted permissions to + $sql = "SELECT COUNT(DISTINCT sl.logbook_id) AS count + FROM station_logbooks sl + LEFT JOIN station_logbooks_permissions slp + ON slp.logbook_id = sl.logbook_id AND slp.user_id = {$userid} + WHERE sl.user_id = {$userid} OR slp.user_id = {$userid}"; $query = $this->db->query($sql); return $query->row()->count; @@ -31,7 +36,10 @@ function getAllSetupCounts() { $sql = "SELECT (SELECT COUNT(*) FROM dxcc_entities) as country_count, - (SELECT COUNT(*) FROM station_logbooks WHERE user_id = {$userid}) as logbook_count, + (SELECT COUNT(DISTINCT sl.logbook_id) FROM station_logbooks sl + LEFT JOIN station_logbooks_permissions slp + ON slp.logbook_id = sl.logbook_id AND slp.user_id = {$userid} + WHERE sl.user_id = {$userid} OR slp.user_id = {$userid}) as logbook_count, (SELECT COUNT(*) FROM station_profile WHERE user_id = {$userid}) as location_count"; $query = $this->db->query($sql); diff --git a/application/views/logbooks/index.php b/application/views/logbooks/index.php index 119f863fd..82fbffbc3 100644 --- a/application/views/logbooks/index.php +++ b/application/views/logbooks/index.php @@ -122,6 +122,15 @@ class="btn btn-primary btn-sm" title="logbook_name;?>"> + public_slug != '') { ?> + + user_id == $this->session->userdata('user_id') || (isset($row->access_level) && $row->access_level == 'admin')) { ?> logbook_id; ?>" class="btn btn-info btn-sm" @@ -167,3 +176,68 @@ class="btn btn-danger btn-sm" + + + + + diff --git a/application/views/widgets/qsos.php b/application/views/widgets/qsos.php index 7bb4b02f5..5377cbb0d 100644 --- a/application/views/widgets/qsos.php +++ b/application/views/widgets/qsos.php @@ -51,6 +51,9 @@ +
+ Powered by Cloudlog +