diff --git a/application/controllers/Adif.php b/application/controllers/Adif.php index f97713634..b1bb25194 100644 --- a/application/controllers/Adif.php +++ b/application/controllers/Adif.php @@ -4,13 +4,75 @@ class adif extends CI_Controller { /* Controls ADIF Import/Export Functions */ - function __construct() - { + private $allowed_tabs = []; + + private $tab_method_mapping = [ + 'import' => ['import'], + 'export' => ['export_custom', 'exportall', 'exportsat', 'exportsatlotw'], + 'lotw' => ['lotw', 'mark_lotw', 'export_lotw'], + 'dcl' => ['dcl'], + 'pota' => ['pota'], + 'cbr' => [] + ]; + + function __construct() { parent::__construct(); $this->load->helper(array('form', 'url')); $this->load->model('user_model'); - if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); } + if(!$this->user_model->authorize(2) || (!clubaccess_check(6) && !clubaccess_check(9))) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); } + + $this->determine_allowed_tabs(); + $this->check_tab_access(); + } + + private function determine_allowed_tabs() { + if (clubaccess_check(6) && !clubaccess_check(9)) { + // Only ClubMember ADIF and NOT ClubOfficer + $this->allowed_tabs = ['import', 'export']; + } else { + // Default: show all tabs (backward compatible) + $this->allowed_tabs = ['import', 'export', 'lotw', 'dcl', 'pota', 'cbr']; + } + + } + + private function check_tab_access() { + // Get current method using CI's built-in method + $current_method = $this->router->method; + + // Skip access check for some common methods + $skip_methods = ['index', '__construct', 'determine_allowed_tabs', 'check_tab_access', 'get_allowed_tabs', 'test']; + if (in_array($current_method, $skip_methods)) { + return; + } + + // Find which tab(s) this method belongs to + $required_tabs = []; + foreach ($this->tab_method_mapping as $tab => $methods) { + if (in_array($current_method, $methods)) { + $required_tabs[] = $tab; + } + } + + // Check if user has access to required tabs + foreach ($required_tabs as $tab) { + if (!in_array($tab, $this->allowed_tabs)) { + $this->session->set_flashdata('error', __("You're not allowed to access this functionality!")); + redirect('adif'); + } + } + } + + private function get_allowed_tabs() { + return $this->allowed_tabs; + } + + private function require_tab_access($required_tab) { + if (!in_array($required_tab, $this->allowed_tabs)) { + $this->session->set_flashdata('error', __("You're not allowed to access this functionality!")); + redirect('adif'); + } } public function test() { @@ -24,9 +86,9 @@ class adif extends CI_Controller { } // Export all QSO Data in ASC Order of Date. - public function exportall() - { + public function exportall() { // Set memory limit to unlimited to allow heavy usage + $this->require_tab_access('export'); ini_set('memory_limit', '-1'); $this->load->model('adif_data'); @@ -38,32 +100,47 @@ class adif extends CI_Controller { // Export all QSO Data in ASC Order of Date. - public function exportsat() - { + public function exportsat() { // Set memory limit to unlimited to allow heavy usage + $this->require_tab_access('export'); ini_set('memory_limit', '-1'); $this->load->model('adif_data'); - $data['qsos'] = $this->adif_data->sat_all(); + if (clubaccess_check(6) && !clubaccess_check(9)) { + $onlyop=($this->session->userdata('operator_callsign') ?? ''); + } else { + $onlyop=null; + } + + $data['qsos'] = $this->adif_data->sat_all($onlyop); $this->load->view('adif/data/exportsat', $data); } // Export all QSO Data in ASC Order of Date. - public function exportsatlotw() - { + public function exportsatlotw() { // Set memory limit to unlimited to allow heavy usage + $this->require_tab_access('export'); ini_set('memory_limit', '-1'); + if (clubaccess_check(6) && !clubaccess_check(9)) { + $onlyop=($this->session->userdata('operator_callsign') ?? ''); + } else { + $onlyop=null; + } + $this->load->model('adif_data'); - $data['qsos'] = $this->adif_data->satellte_lotw(); + $data['qsos'] = $this->adif_data->satellte_lotw($onlyop); $this->load->view('adif/data/exportsat', $data); } public function export_custom() { + // Check if user has access to export tab + $this->require_tab_access('export'); + // Set memory limit to unlimited to allow heavy usage ini_set('memory_limit', '-1'); @@ -78,20 +155,28 @@ class adif extends CI_Controller { $exportLotw = false; } - $data['qsos'] = $this->adif_data->export_custom($this->input->post('from'), $this->input->post('to'), $station_id, $exportLotw); + if (clubaccess_check(6) && !clubaccess_check(9)) { + $onlyop=($this->session->userdata('operator_callsign') ?? ''); + } else { + $onlyop=null; + } + + $data['qsos'] = $this->adif_data->export_custom($this->input->post('from'), $this->input->post('to'), $station_id, $exportLotw, $onlyop); $this->load->view('adif/data/exportall', $data); - if ($this->input->post('markLotw') == 1) { - foreach ($data['qsos']->result() as $qso) - { + if ((clubaccess_check(9)) && ($this->input->post('markLotw') == 1)) { // Only allow marking if clubofficer or regular user! + foreach ($data['qsos']->result() as $qso) { $this->adif_data->mark_lotw_sent($qso->COL_PRIMARY_KEY); } } } public function mark_lotw() { + // Check if user has access to lotw tab + $this->require_tab_access('lotw'); + // Set memory limit to unlimited to allow heavy usage ini_set('memory_limit', '-1'); @@ -108,8 +193,10 @@ class adif extends CI_Controller { $this->load->view('adif/mark_lotw', $data); } - public function export_lotw() - { + public function export_lotw() { + // Check if user has access to lotw tab + $this->require_tab_access('lotw'); + // Set memory limit to unlimited to allow heavy usage ini_set('memory_limit', '-1'); @@ -119,8 +206,7 @@ class adif extends CI_Controller { $this->load->view('adif/data/exportall', $data); - foreach ($data['qsos']->result() as $qso) - { + foreach ($data['qsos']->result() as $qso) { $this->adif_data->mark_lotw_sent($qso->COL_PRIMARY_KEY); } } @@ -133,6 +219,7 @@ class adif extends CI_Controller { $data['page_title'] = __("ADIF Import / Export"); $data['max_upload'] = ini_get('upload_max_filesize'); + $data['cd_p_level'] = ($this->session->userdata('cd_p_level') ?? 0); if ($this->config->item('special_callsign') && clubaccess_check(9) && $this->session->userdata('clubstation') == 1) { $this->load->model('club_model'); @@ -148,12 +235,18 @@ class adif extends CI_Controller { $data['active_station_info'] = $station_profile->row(); $data['active_station_id'] = $active_station_id; + // Pass allowed tabs to view + $data['allowed_tabs'] = $this->get_allowed_tabs(); + $this->load->view('interface_assets/header', $data); - $this->load->view('adif/import'); + $this->load->view('adif/import', $data); $this->load->view('interface_assets/footer'); } public function import() { + // Check if user has access to import tab + $this->require_tab_access('import'); + $this->load->model('stations'); $data['station_profile'] = $this->stations->all_of_user(); @@ -165,6 +258,9 @@ class adif extends CI_Controller { $data['page_title'] = __("ADIF Import"); $data['tab'] = "adif"; + // Pass allowed tabs to view + $data['allowed_tabs'] = $this->get_allowed_tabs(); + $config['upload_path'] = './uploads/'; $config['allowed_types'] = 'adi|ADI|adif|ADIF|zip'; @@ -242,10 +338,18 @@ class adif extends CI_Controller { $record['contest_id'] = $contest; } - //handle club operator - if ($club_operator != '') { - $record['operator'] = strtoupper($club_operator); + //handle club operator based on permission level + $user_permission_level = $this->session->userdata('cd_p_level'); + if ($user_permission_level >= 9) { + // Club Officer: Allow operator override + if ($club_operator != '') { + $record['operator'] = strtoupper($club_operator); + } + } elseif ($user_permission_level == 6) { + // ClubMemberADIF: Force operator to current user, ignore input + $record['operator'] = strtoupper($this->session->userdata('operator_callsign')); } + // Note: Regular Club Member (Level 3) should not reach here due to constructor permission check //check if contest_id exists in record and extract all found contest_ids if(array_key_exists('contest_id', $record)){ @@ -305,12 +409,18 @@ class adif extends CI_Controller { } public function dcl() { + // Check if user has access to dcl tab + $this->require_tab_access('dcl'); + $this->load->model('stations'); $data['station_profile'] = $this->stations->all_of_user(); $data['page_title'] = __("DCL Import"); $data['tab'] = "dcl"; + // Pass allowed tabs to view + $data['allowed_tabs'] = $this->get_allowed_tabs(); + $config['upload_path'] = './uploads/'; $config['allowed_types'] = 'adi|ADI|adif|ADIF'; @@ -374,12 +484,18 @@ class adif extends CI_Controller { } public function pota() { + // Check if user has access to pota tab + $this->require_tab_access('pota'); + $this->load->model('stations'); $data['station_profile'] = $this->stations->all_of_user(); $data['page_title'] = __("POTA Import"); $data['tab'] = "potab"; + // Pass allowed tabs to view + $data['allowed_tabs'] = $this->get_allowed_tabs(); + $config['upload_path'] = './uploads/'; $config['allowed_types'] = 'adi|ADI|adif|ADIF'; diff --git a/application/controllers/Club.php b/application/controllers/Club.php index 78fec7681..eb8daf0e6 100644 --- a/application/controllers/Club.php +++ b/application/controllers/Club.php @@ -21,6 +21,7 @@ class Club extends CI_Controller $this->permissions = [ 9 => __("Club Officer"), + 6 => __("Club Member ADIF"), 3 => __("Club Member"), ]; } @@ -118,9 +119,9 @@ class Club extends CI_Controller $this->session->set_flashdata('error', __("Invalid Club ID!")); redirect('dashboard'); } - if(!$this->user_model->authorize(99) && !$this->club_model->club_authorize(9, $club_id)) { - $this->session->set_flashdata('error', __("You're not allowed to do that!")); - redirect('dashboard'); + if(!$this->user_model->authorize(99) && !$this->club_model->club_authorize(9, $club_id) && !$this->club_model->club_authorize(6, $club_id)) { + $this->session->set_flashdata('error', __("You're not allowed to do that!")); + redirect('dashboard'); } $this->club_model->alter_member($club_id, $user_id, $p_level); @@ -147,9 +148,9 @@ class Club extends CI_Controller $this->session->set_flashdata('error', __("Invalid Club ID!")); redirect('dashboard'); } - if(!$this->user_model->authorize(99) && !$this->club_model->club_authorize(9, $club_id)) { - $this->session->set_flashdata('error', __("You're not allowed to do that!")); - redirect('dashboard'); + if(!$this->user_model->authorize(99) && !$this->club_model->club_authorize(9, $club_id) && !$this->club_model->club_authorize(6, $club_id)) { + $this->session->set_flashdata('error', __("You're not allowed to do that!")); + redirect('dashboard'); } if ($this->club_model->delete_member($club_id, $user_id)) { diff --git a/application/helpers/club_helper.php b/application/helpers/club_helper.php index 780800b98..859fe7674 100644 --- a/application/helpers/club_helper.php +++ b/application/helpers/club_helper.php @@ -30,9 +30,18 @@ if (!function_exists('clubaccess_check')) { // check if the QSO belongs to the user $CI->load->model('logbook_model'); $qso = $CI->logbook_model->get_qso($qso_id)->row(); - if ($qso->COL_OPERATOR == $CI->session->userdata('operator_callsign') || $CI->session->userdata('cd_p_level') >= 9) { + $user_level = $CI->session->userdata('cd_p_level'); + $operator_callsign = $CI->session->userdata('operator_callsign'); + + // Enhanced logic for ClubMemberADIF (Level 6) + if ($user_level >= 9) { + // Officers can access any QSO return true; + } elseif ($user_level >= 6) { + // ClubMemberADIF and regular members can only access their own QSOs + return $qso->COL_OPERATOR == $operator_callsign; } else { + // Lower levels (shouldn't reach here for ADIF access) return false; } } else { @@ -46,4 +55,4 @@ if (!function_exists('clubaccess_check')) { return true; } } -} \ No newline at end of file +} diff --git a/application/models/Adif_data.php b/application/models/Adif_data.php index 6dc710c60..e34845546 100644 --- a/application/models/Adif_data.php +++ b/application/models/Adif_data.php @@ -2,7 +2,7 @@ class adif_data extends CI_Model { - function export_all($api_key = null,$from = null, $to = null, $exportLotw = false) { + function export_all($api_key = null,$from = null, $to = null, $exportLotw = false, $onlyop = null) { $this->load->model('logbooks_model'); if ($api_key != null) { $this->load->model('api_model'); @@ -25,6 +25,9 @@ class adif_data extends CI_Model { if ($to) { $this->db->where("date(".$this->config->item('table_name').".COL_TIME_ON) <= ",$to); } + if ($onlyop) { + $this->db->where("upper(".$this->config->item('table_name').".col_operator)",$onlyop); + } if ($exportLotw) { $this->db->group_start(); $this->db->where($this->config->item('table_name').".COL_LOTW_QSL_SENT != 'Y'"); @@ -76,7 +79,7 @@ class adif_data extends CI_Model { return $query; } - function sat_all() { + function sat_all($onlyop = null) { $this->load->model('stations'); $active_station_id = $this->stations->find_active(); @@ -85,6 +88,10 @@ class adif_data extends CI_Model { $this->db->where($this->config->item('table_name').'.station_id', $active_station_id); $this->db->where($this->config->item('table_name').'.COL_PROP_MODE', 'SAT'); + if ($onlyop) { + $this->db->where("upper(".$this->config->item('table_name').".col_operator)",$onlyop); + } + $this->db->order_by($this->config->item('table_name').".COL_TIME_ON", "ASC"); $this->db->join('station_profile', 'station_profile.station_id = '.$this->config->item('table_name').'.station_id'); @@ -93,7 +100,7 @@ class adif_data extends CI_Model { return $this->db->get(); } - function satellte_lotw() { + function satellte_lotw($onlyop = null) { $this->load->model('stations'); $active_station_id = $this->stations->find_active(); @@ -102,6 +109,10 @@ class adif_data extends CI_Model { $this->db->where($this->config->item('table_name').'.station_id', $active_station_id); $this->db->where($this->config->item('table_name').'.COL_PROP_MODE', 'SAT'); + if ($onlyop) { + $this->db->where("upper(".$this->config->item('table_name').".col_operator)",$onlyop); + } + $where = $this->config->item('table_name').".COL_LOTW_QSLRDATE IS NOT NULL"; $this->db->where($where); @@ -114,7 +125,7 @@ class adif_data extends CI_Model { return $this->db->get(); } - function export_custom($from, $to, $station_id, $exportLotw = false) { + function export_custom($from, $to, $station_id, $exportLotw = false, $onlyop = null) { // be sure that station belongs to user $this->load->model('Stations'); if ($station_id == 0) { @@ -135,6 +146,9 @@ class adif_data extends CI_Model { if ($to) { $this->db->where("date(".$this->config->item('table_name').".COL_TIME_ON) <= ",$to); } + if ($onlyop) { + $this->db->where("upper(".$this->config->item('table_name').".col_operator)",$onlyop); + } if ($exportLotw) { $this->db->group_start(); $this->db->where($this->config->item('table_name').".COL_LOTW_QSL_SENT != 'Y'"); @@ -151,7 +165,7 @@ class adif_data extends CI_Model { } } - function export_past_id($station_id, $fetchfromid, $limit) { + function export_past_id($station_id, $fetchfromid, $limit, $onlyop = null) { //create query $this->db->select(''.$this->config->item('table_name').'.*, station_profile.*, dxcc_entities.name as station_country'); $this->db->from($this->config->item('table_name')); @@ -160,6 +174,9 @@ class adif_data extends CI_Model { $this->db->order_by($this->config->item('table_name').".COL_TIME_ON", "ASC"); $this->db->join('station_profile', 'station_profile.station_id = '.$this->config->item('table_name').'.station_id'); $this->db->join('dxcc_entities', 'station_profile.station_dxcc = dxcc_entities.adif', 'left outer'); + if ($onlyop) { + $this->db->where("upper(".$this->config->item('table_name').".col_operator)",$onlyop); + } $this->db->order_by("COL_PRIMARY_KEY", "ASC"); if ($limit > -1) { @@ -170,7 +187,7 @@ class adif_data extends CI_Model { return $this->db->get(); } - function export_lotw() { + function export_lotw($onlyop = null) { $this->load->model('stations'); $active_station_id = $this->stations->find_active(); @@ -178,6 +195,9 @@ class adif_data extends CI_Model { $this->db->select(''.$this->config->item('table_name').'.*, station_profile.*, dxcc_entities.name as station_country'); $this->db->from($this->config->item('table_name')); $this->db->where($this->config->item('table_name').'.station_id', $active_station_id); + if ($onlyop) { + $this->db->where("upper(".$this->config->item('table_name').".col_operator)",$onlyop); + } $this->db->group_start(); $this->db->where($this->config->item('table_name').".COL_LOTW_QSL_SENT != 'Y'"); $this->db->or_where($this->config->item('table_name').".COL_LOTW_QSL_SENT", NULL); diff --git a/application/views/adif/import.php b/application/views/adif/import.php index 7f87c9a51..b9d0c81c8 100644 --- a/application/views/adif/import.php +++ b/application/views/adif/import.php @@ -11,58 +11,84 @@