include contest info export while adif importing

This commit is contained in:
DB4SCW
2025-01-02 15:05:48 +00:00
282 changed files with 102373 additions and 50241 deletions

View File

@@ -14,7 +14,7 @@
<img alt="Translation Status" src="https://translate.wavelog.org/widget/wavelog/main-translation/svg-badge.svg">
</a>
<a href="https://github.com/wavelog/wavelog/graphs/contributors" >
<img alt="Commit Activity" src="https://img.shields.io/github/commit-activity/m/wavelog/wavelog">
<img alt="Commit Activity" src="https://img.shields.io/github/commit-activity/m/wavelog/wavelog/dev">
</a>
</h1>
@@ -68,11 +68,11 @@ Wavelog-support can be reached by creating an issue here at github. If you've an
Special thanks to our contributors, who are part of Wavelog by improving code!
[F4ANS](https://github.com/abarrau), [DG0TM](https://github.com/dg0tm), [DG9VH](https://github.com/dg9vh), [DJ3CE](https://github.com/dj3ce), [R1BLH](https://github.com/r1blh), [BG2ELG](https://github.com/violarulan), [DF1ASH](https://github.com/derFogel), [DB4SCW](https://github.com/DB4SCW), [VE2HEW](https://github.com/anthonydiiorio), [OK1GOD](https://github.com/filipmelik), [DJ1PW](https://github.com/winnieXY), [toseppo](https://github.com/toseppo), [N7DSB](https://github.com/desertblade), [BA7LAC](https://github.com/imlonghao)
[F4ANS](https://github.com/abarrau), [DG0TM](https://github.com/dg0tm), [DG9VH](https://github.com/dg9vh), [DJ3CE](https://github.com/dj3ce), [R1BLH](https://github.com/r1blh), [BG2ELG](https://github.com/violarulan), [DF1ASH](https://github.com/derFogel), [DB4SCW](https://github.com/DB4SCW), [VE2HEW](https://github.com/anthonydiiorio), [OK1GOD](https://github.com/filipmelik), [DJ1PW](https://github.com/winnieXY), [toseppo](https://github.com/toseppo), [N7DSB](https://github.com/desertblade), [BA7LAC](https://github.com/imlonghao), [Ethan C. Edwards](https://github.com/ethancedwards8)
Translators:
[Ondřej Koloničný (OK1CDJ)](https://translate.wavelog.org/user/ok1cdj/), [Michael Skolsky (R1BLH)](https://translate.wavelog.org/user/R1BLH/), [Karuru (BG2ELG)](https://translate.wavelog.org/user/viola/), [Byt3](https://translate.wavelog.org/user/205er/), [BG6HJE](https://translate.wavelog.org/user/BG6HJE/), [Francisco (F4VSE)](https://translate.wavelog.org/user/kikosgc/), [Kim (DG9VH)](https://translate.wavelog.org/user/dg9vh/), [Casper van Lieburg (PA7DX)](https://translate.wavelog.org/user/pa7dx/), [Halil AYYILDIZ (TA2LG)](https://translate.wavelog.org/user/TA2LG/), [Michal Šiman](https://translate.wavelog.org/user/michalsiman/), [DN4BS](https://github.com/dn4bs), [Luca (IU2FRL)](https://translate.wavelog.org/user/iu2frl/), [Dragan Đorđević (4O4A)](https://translate.wavelog.org/user/4o4a/), [Dren Imeraj (Z63DRI)](https://translate.wavelog.org/user/Dren/), [Filip Melik (OK1GOD)](https://translate.wavelog.org/user/filipmelik/), [Petr (OK1PTR)](https://translate.wavelog.org/user/OK1PTR/), [Stefan (DB4SCW)](https://translate.wavelog.org/user/DB4SCW/), [F4JSU](https://translate.wavelog.org/user/F4JSU/), [Maciej](https://translate.wavelog.org/user/maciejla/), [imlonghao](https://translate.wavelog.org/user/imlonghao/), [Reiner Herrmann](https://translate.wavelog.org/user/reinerh/), [Jian ke (BG8IXZ)](https://translate.wavelog.org/user/bg8ixz/), [Fabian Franz](https://translate.wavelog.org/user/fabianfrz/), [Fatih Önder](https://translate.wavelog.org/user/cektor/), [Qing He(BD8DHF)](https://translate.wavelog.org/user/BD8DHF), [hellofinch](https://translate.wavelog.org/user/hellofinch/), [tviitkar (ES5TVI )](https://translate.wavelog.org/user/tviitkar/), [utkuyalcin](https://translate.wavelog.org/user/utkuyalcin/), [Plamen Panteleev (LZ1PPL)](https://translate.wavelog.org/user/lz1ppl/), [Bartek](https://translate.wavelog.org/user/atimias/), [Samir (DL4DCO)](https://translate.wavelog.org/user/DL4DCO/)
[Ondřej Koloničný (OK1CDJ)](https://translate.wavelog.org/user/ok1cdj/), [Michael Skolsky (R1BLH)](https://translate.wavelog.org/user/R1BLH/), [Karuru (BG2ELG)](https://translate.wavelog.org/user/viola/), [Byt3](https://translate.wavelog.org/user/205er/), [BG6HJE](https://translate.wavelog.org/user/BG6HJE/), [Francisco (F4VSE)](https://translate.wavelog.org/user/kikosgc/), [Kim (DG9VH)](https://translate.wavelog.org/user/dg9vh/), [Casper van Lieburg (PA7DX)](https://translate.wavelog.org/user/pa7dx/), [Halil AYYILDIZ (TA2LG)](https://translate.wavelog.org/user/TA2LG/), [Michal Šiman](https://translate.wavelog.org/user/michalsiman/), [DN4BS](https://github.com/dn4bs), [Luca (IU2FRL)](https://translate.wavelog.org/user/iu2frl/), [Dragan Đorđević (4O4A)](https://translate.wavelog.org/user/4o4a/), [Dren Imeraj (Z63DRI)](https://translate.wavelog.org/user/Dren/), [Filip Melik (OK1GOD)](https://translate.wavelog.org/user/filipmelik/), [Petr (OK1PTR)](https://translate.wavelog.org/user/OK1PTR/), [Stefan (DB4SCW)](https://translate.wavelog.org/user/DB4SCW/), [F4JSU](https://translate.wavelog.org/user/F4JSU/), [Maciej](https://translate.wavelog.org/user/maciejla/), [imlonghao](https://translate.wavelog.org/user/imlonghao/), [Reiner Herrmann](https://translate.wavelog.org/user/reinerh/), [Jian ke (BG8IXZ)](https://translate.wavelog.org/user/bg8ixz/), [Fabian Franz](https://translate.wavelog.org/user/fabianfrz/), [Fatih Önder](https://translate.wavelog.org/user/cektor/), [Qing He(BD8DHF)](https://translate.wavelog.org/user/BD8DHF), [hellofinch](https://translate.wavelog.org/user/hellofinch/), [tviitkar (ES5TVI )](https://translate.wavelog.org/user/tviitkar/), [utkuyalcin](https://translate.wavelog.org/user/utkuyalcin/), [Plamen Panteleev (LZ1PPL)](https://translate.wavelog.org/user/lz1ppl/), [Bartek](https://translate.wavelog.org/user/atimias/), [Samir (DL4DCO)](https://translate.wavelog.org/user/DL4DCO/), [Stanisław Korzeń (SP5CRO)](https://translate.wavelog.org/user/sp5cro/), [wxy (BA7NID)](https://translate.wavelog.org/user/ba7nid/), [David Quental (CT1DRB)](https://translate.wavelog.org/user/ct1drb/), [Sebastian K.](https://translate.wavelog.org/user/sebket/), [Limes](https://translate.wavelog.org/user/limes-github/), [Ethan C. Edwards](https://translate.wavelog.org/user/ethancedwards8/)
If you would like to contribute in any way to Wavelog, it is most appreciated. This has been developed in free time, help coding new features or writing documentation is always useful.

View File

@@ -64,7 +64,7 @@ $autoload['libraries'] = array('database', 'session', 'curl', 'OptionsLib', 'Pat
| $autoload['helper'] = array('url', 'file');
*/
$autoload['helper'] = array('url', 'security', 'language');
$autoload['helper'] = array('url', 'security', 'language', 'club');
/*

View File

@@ -14,7 +14,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
$config['app_name'] = 'Wavelog';
$config['directory'] = 'logbook';
$config['callbook'] = 'hamqth'; // Options are hamqth or qrz
$config['callbook'] = 'hamqth'; // Options are hamqth, qrz or qrzcq
$config['datadir'] = null; // default to install directory
@@ -57,6 +57,17 @@ $config['use_fullname'] = false;
$config['hamqth_username'] = '';
$config['hamqth_password'] = '';
/*
|--------------------------------------------------------------------------
| QRZcq Login Options
|--------------------------------------------------------------------------
|
| 'qrzcq_username' QRZcq.com user login
| 'qrzcq_password' QRZcq.com user password
*/
$config['qrzcq_username'] = '';
$config['qrzcq_password'] = '';
/*
|--------------------------------------------------------------------------
| Authentication
@@ -460,7 +471,7 @@ $config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
/*
/*
* To make sure we do not collect infinite session we set some garbage collection settings
* see https://www.php.net/manual/en/session.configuration.php#ini.session.gc-probability
* and https://www.php.net/manual/en/session.configuration.php#ini.session.gc-divisor
@@ -642,7 +653,7 @@ $config['disable_manual_qrz'] = false;
| Disables QSL-Image-Feature
|--------------------------------------------------------------------------
|
| This disabled the whole QSL image feature if you don't need it and want to hide it.
| This disabled the whole QSL image feature if you don't need it and want to hide it.
| Set to true will hide all QSL image related stuff in Wavelog
|
*/
@@ -654,7 +665,7 @@ $config['disable_qsl'] = false;
| Disables OQRS-Feature
|--------------------------------------------------------------------------
|
| This disabled the whole OQRS feature if you don't need it and want to hide it.
| This disabled the whole OQRS feature if you don't need it and want to hide it.
| Set to true will hide all OQRS related stuff in Wavelog
|
*/
@@ -663,25 +674,21 @@ $config['disable_oqrs'] = false;
/*
|--------------------------------------------------------------------------
| Special Callsign Feature
| Special Callsign Feature aka. Clubstations Support
|--------------------------------------------------------------------------
|
| This config switch is meant to use for Special Callsign operations in a dedicated Wavelog Installation
| If this switch is set to true it will enable a dialog which pops up for each operator after login
| to ask for his personal callsign. This causes the QSOs to get saved with the correct operator data.
| Example: Special Callsign: DL250CDF
| Operator: DF2TG
|
| It is recommend to enable also "Disable Syncing to 3rd party-Services at UI"
| More Information about this feature and how to use it, you can find here:
| https://github.com/wavelog/wavelog/wiki/Recommended-Setup-for-Special-Callsigns-and-Clubs
| This config switch is meant to use for Special Callsign operations or Clubstations.
| If this switch is set to true it enables a whole bunch of features to handle Special Callsigns and Club Callsigns.
| For more Information please visit the Wiki:
| https://github.com/wavelog/wavelog/wiki/Clubstations
|
| !!! Important !!!
| $config['disable_impersonate'] has to be set to false to use this feature.
|
*/
$config['special_callsign'] = false;
// hides the usermenu; takes action only if "special_callsign" is true
$config['sc_hide_usermenu'] = true;
/*
|--------------------------------------------------------------------------
@@ -689,11 +696,11 @@ $config['sc_hide_usermenu'] = true;
|--------------------------------------------------------------------------
|
| This config switch disables the impersonate feature. This feauture is used to impersonate another user.
| Impersonate is enabled by default. To disable it, set the value to false.
|
| Impersonate is enabled by default. To disable it, set the value to false. Also the special_callsign feature needs this to be false.
|
*/
$config['disable_impersonate'] = false;
$config['disable_impersonate'] = false;
/*
@@ -703,7 +710,7 @@ $config['disable_impersonate'] = false;
|
| The cronmanager needs http or https with a valid certificate to work.
| If you want to use it with https and a self-signed certificate, you need to set this to true.
|
|
*/
$config['cron_allow_insecure'] = false;
@@ -725,6 +732,10 @@ $config['disable_version_check'] = false;
| trx-control Configuration
|--------------------------------------------------------------------------
|
| ***
| No Features implemented yet, Nothing is going to happen if you set this.
| ***
|
| This defines server and port of your personal trx-control server.
| If you don't have a trx-control server, you can ignore this.
|
@@ -746,4 +757,15 @@ $config['disable_version_check'] = false;
// $config['trxd_server_port'] = '14290';
// $config['trxd_connection_type'] = 'ws';
// $config['trxd_ws_path'] = '/trx-control';
// $config['trxd_timeout'] = 5;
// $config['trxd_timeout'] = 5;
/*
|--------------------------------------------------------------------------
| eqsl.cc Massdownloa
|--------------------------------------------------------------------------
|
| The eqsl.cc mass download function is not threadsafe. So it is disabled by default.
| Please consider enabling this carefully. Not recommended for multi-user environments.
*/
$config['enable_eqsl_massdownload'] = false;

View File

@@ -300,6 +300,16 @@ $config['languages'] = array(
'direction' => 'ltr',
'code' => 'tr',
'flag' => 'tr',
),
'armenian' => array(
'name' => 'Հայերեն',
'name_en' => 'Armenian',
'folder' => 'armenian',
'locale' => 'hy',
'gettext' => 'hy',
'direction' => 'ltr',
'code' => 'hy',
'flag' => 'am',
)
);

View File

@@ -22,7 +22,7 @@ $config['migration_enabled'] = TRUE;
|
*/
$config['migration_version'] = 227;
$config['migration_version'] = 233;
/*
|--------------------------------------------------------------------------

View File

@@ -33,13 +33,18 @@ class Activated_gridmap extends CI_Controller {
$data['gridsquares_gridsquares_not_confirmed'] = __("Gridsquares not confirmed");
$data['gridsquares_gridsquares_total_activated'] = __("Total gridsquares activated");
$data['gridsquares_fields'] = __("Fields");
$data['gridsquares_fields_confirmed'] = __("Fields confirmed");
$data['gridsquares_fields_not_confirmed'] = __("Fields not confirmed");
$data['gridsquares_fields_total_worked'] = __("Total fields worked");
$footerData = [];
$footerData['scripts'] = [
'assets/js/leaflet/geocoding.js',
'assets/js/leaflet/L.MaidenheadColouredGridMap.js',
'assets/js/sections/gridmap.js?'
];
$this->load->view('interface_assets/header', $data);
$this->load->view('activated_gridmap/index');
$this->load->view('interface_assets/footer', $footerData);
@@ -87,16 +92,16 @@ class Activated_gridmap extends CI_Controller {
// Check if 2 Char is in array
if(!in_array($grid_2char_confirmed, $array_grid_2char_confirmed)){
array_push($array_grid_2char_confirmed, $grid_2char_confirmed);
array_push($array_grid_2char_confirmed, $grid_2char_confirmed);
}
if(!in_array($grid_4char_confirmed, $array_grid_4char_confirmed)){
array_push($array_grid_4char_confirmed, $grid_4char_confirmed);
array_push($array_grid_4char_confirmed, $grid_4char_confirmed);
}
if ($this->config->item('map_6digit_grids')) {
if(!in_array($grid_6char_confirmed, $array_grid_6char_confirmed)){
array_push($array_grid_6char_confirmed, $grid_6char_confirmed);
array_push($array_grid_6char_confirmed, $grid_6char_confirmed);
}
}
}
@@ -118,16 +123,16 @@ class Activated_gridmap extends CI_Controller {
// Check if 2 Char is in array
if(!in_array($grid_two, $array_grid_2char)){
array_push($array_grid_2char, $grid_two);
array_push($array_grid_2char, $grid_two);
}
if(!in_array($grid_four, $array_grid_4char)){
array_push($array_grid_4char, $grid_four);
array_push($array_grid_4char, $grid_four);
}
if ($this->config->item('map_6digit_grids')) {
if(!in_array($grid_six, $array_grid_6char)){
array_push($array_grid_6char, $grid_six);
array_push($array_grid_6char, $grid_six);
}
}
}
@@ -140,18 +145,18 @@ class Activated_gridmap extends CI_Controller {
$grids = explode(",", $row->COL_VUCC_GRIDS);
foreach($grids as $key) {
foreach($grids as $key) {
$grid_two = strtoupper(substr($key,0,2));
$grid_four = strtoupper(substr($key,0,4));
// Check if 2 Char is in array
if(!in_array($grid_two, $array_grid_2char)){
array_push($array_grid_2char, $grid_two);
array_push($array_grid_2char, $grid_two);
}
if(!in_array($grid_four, $array_grid_4char)){
array_push($array_grid_4char, $grid_four);
array_push($array_grid_4char, $grid_four);
}
}
}
@@ -165,18 +170,18 @@ class Activated_gridmap extends CI_Controller {
$grids = explode(",", $row->COL_VUCC_GRIDS);
foreach($grids as $key) {
foreach($grids as $key) {
$grid_2char_confirmed = strtoupper(substr($key,0,2));
$grid_4char_confirmed = strtoupper(substr($key,0,4));
// Check if 2 Char is in array
if(!in_array($grid_2char_confirmed, $array_grid_2char_confirmed)){
array_push($array_grid_2char_confirmed, $grid_2char_confirmed);
array_push($array_grid_2char_confirmed, $grid_2char_confirmed);
}
if(!in_array($grid_4char_confirmed, $array_grid_4char_confirmed)){
array_push($array_grid_4char_confirmed, $grid_4char_confirmed);
array_push($array_grid_4char_confirmed, $grid_4char_confirmed);
}
}
}

View File

@@ -10,7 +10,7 @@ class adif extends CI_Controller {
$this->load->helper(array('form', 'url'));
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
}
public function test() {
@@ -145,6 +145,13 @@ class adif extends CI_Controller {
$data['page_title'] = __("ADIF Import / Export");
$data['max_upload'] = ini_get('upload_max_filesize');
if ($this->config->item('special_callsign') && clubaccess_check(9) && $this->session->userdata('clubstation') == 1) {
$this->load->model('club_model');
$data['club_operators'] = $this->club_model->get_club_members($this->session->userdata('user_id'));
} else {
$data['club_operators'] = false;
}
$data['station_profile'] = $this->stations->all_of_user();
$active_station_id = $this->stations->find_active();
$station_profile = $this->stations->profile($active_station_id);
@@ -185,7 +192,8 @@ class adif extends CI_Controller {
$this->load->view('interface_assets/footer');
} else {
if ($this->stations->check_station_is_accessible($this->input->post('station_profile', TRUE))) {
$contest=$this->security->xss_clean($this->input->post('contest')) ?? '';
$contest=$this->input->post('contest', true) ?? '';
$club_operator=$this->input->post('club_operator', true) ?? '';
$stopnow=false;
$fdata = array('upload_data' => $this->upload->data());
ini_set('memory_limit', '-1');
@@ -232,6 +240,7 @@ class adif extends CI_Controller {
if ($contest != '') {
$record['contest_id'] = $contest;
}
<<<<<<< HEAD
//check if contest_id exists in record and extract all found contest_ids
if(array_key_exists('contest_id', $record)){
@@ -245,6 +254,11 @@ class adif extends CI_Controller {
}
}
=======
if ($club_operator != '') {
$record['operator']=strtoupper($club_operator);
}
>>>>>>> dev
if(count($record) == 0) {
break;
};
@@ -252,7 +266,7 @@ class adif extends CI_Controller {
};
$record=''; // free memory
try {
$custom_errors = $this->logbook_model->import_bulk($alladif, $this->input->post('station_profile', TRUE), $this->input->post('skipDuplicate'), $this->input->post('markClublog'),$this->input->post('markLotw'), $this->input->post('dxccAdif'), $this->input->post('markQrz'), $this->input->post('markEqsl'), $this->input->post('markHrd'), true, $this->input->post('operatorName'), false, $this->input->post('skipStationCheck'));
$custom_errors = $this->logbook_model->import_bulk($alladif, $this->input->post('station_profile', TRUE), $this->input->post('skipDuplicate'), $this->input->post('markClublog'),$this->input->post('markLotw'), $this->input->post('dxccAdif'), $this->input->post('markQrz'), $this->input->post('markEqsl'), $this->input->post('markHrd'), $this->input->post('markDcl'), true, $this->input->post('operatorName') ?? false, false, $this->input->post('skipStationCheck'));
} catch (Exception $e) {
log_message('error', 'Import error: '.$e->getMessage());
$data['page_title'] = __("ADIF Import failed!");
@@ -272,12 +286,6 @@ class adif extends CI_Controller {
$custom_errors=__("Station Profile not valid for User");
}
// Lets clean up static maps cache for this station
if (!$this->load->is_loaded('staticmap_model')) {
$this->load->model('staticmap_model');
}
$this->staticmap_model->remove_static_map_image($this->input->post('station_profile', TRUE));
log_message("Error","ADIF End");
$data['adif_errors'] = $custom_errors;
$data['skip_dupes'] = $this->input->post('skipDuplicate');

View File

@@ -2,44 +2,31 @@
class API extends CI_Controller {
// Do absolutely nothing
function index()
{
echo "nothing to see";
}
function help()
{
function index() {
$this->load->model('user_model');
// Check if users logged in
if($this->user_model->validate_session() == 0) {
// user is not logged in
redirect('user/login');
}
if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$this->load->model('api_model');
$this->load->library('form_validation');
$data['api_keys'] = $this->api_model->keys();
$data['clubmode'] = $this->session->userdata('clubstation') == 1 ? true : false;
$data['page_title'] = __("API");
$this->load->view('interface_assets/header', $data);
$this->load->view('api/help');
$this->load->view('api/index');
$this->load->view('interface_assets/footer');
}
// legacy
function help() {
redirect('api');
}
function edit($key) {
$this->load->model('user_model');
// Check if users logged in
if($this->user_model->validate_session() == 0) {
// user is not logged in
redirect('user/login');
}
if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$this->load->model('api_model');
@@ -68,38 +55,40 @@ class API extends CI_Controller {
$this->session->set_flashdata('notice', sprintf(__("API Key %s description has been updated."), "<b>".$this->input->post('api_key')."</b>"));
redirect('api/help');
redirect('api');
}
}
function generate($rights) {
$this->load->model('user_model');
if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
// Check if users logged in
if($this->user_model->validate_session() == 0) {
// user is not logged in
redirect('user/login');
if ($rights !== "r" && $rights !== "rw") {
$this->session->set_flashdata('error', __("Invalid API rights"));
redirect('api');
exit;
}
$this->load->model('api_model');
$data['api_keys'] = $this->api_model->generate_key($rights);
if ($this->session->userdata('clubstation') == 1 && $this->session->userdata('impersonate') == 1) {
$creator = $this->session->userdata('source_uid');
} else {
$creator = $this->session->userdata('user_id');
}
redirect('api/help');
if ($this->api_model->generate_key($rights, $creator)) {
$this->session->set_flashdata('success', __("API Key generated"));
} else {
$this->session->set_flashdata('error', __("API Key could not be generated"));
}
redirect('api');
}
function delete($key) {
$this->load->model('user_model');
// Check if users logged in
if($this->user_model->validate_session() == 0) {
// user is not logged in
redirect('user/login');
}
if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$this->load->model('api_model');
@@ -108,11 +97,11 @@ class API extends CI_Controller {
$this->session->set_flashdata('notice', sprintf(__("API Key %s has been deleted"), "<b>".$key."</b>" ));
redirect('api/help');
redirect('api');
}
// Example of authing
function auth($key) {
function auth($key = '') {
$this->load->model('api_model');
header("Content-type: text/xml");
if($this->api_model->access($key) == "No Key Found" || $this->api_model->access($key) == "Key Disabled") {
@@ -128,7 +117,7 @@ class API extends CI_Controller {
}
}
function station_info($key) {
function station_info($key = '') {
$this->load->model('api_model');
$this->load->model('stations');
header("Content-type: application/json");
@@ -168,6 +157,10 @@ class API extends CI_Controller {
$this->load->model('stations');
if (!$this->load->is_loaded('Qra')) {
$this->load->library('Qra');
}
$return_msg = array();
$return_count = 0;
@@ -187,6 +180,25 @@ class API extends CI_Controller {
}
$userid = $this->api_model->key_userid($obj['key']);
$created_by = $this->api_model->key_created_by($obj['key']);
/**
* As the API key user could use it also for clubstations we need to do an additional check here. Only if clubstations are enabled
*
* In Detail:
* If the user is not the creator of the API key, it's likely a clubstation. In this case the callsign of the clubstation
* can not be the same as the callsign of the user (operator call provided by the user). If this is the case, we need to use the callsign of the creator of the API key
*/
if ($this->config->item('special_callsign')) {
if ($userid != $created_by) {
$this->load->model('user_model');
$real_operator = $this->user_model->get_by_id($created_by)->row()->user_callsign;
// TODO: It would be possible to check here if operator is allowed to use the clubstation, but this can be added later if needed
} else {
$real_operator = null;
}
}
$this->api_model->update_last_used(($obj['key']));
if(!isset($obj['station_profile_id']) || $this->stations->check_station_against_user($obj['station_profile_id'], $userid) == false) {
@@ -194,6 +206,8 @@ class API extends CI_Controller {
echo json_encode(['status' => 'failed', 'reason' => "station id does not belong to the API key owner."]);
die();
}
$mystation=$this->stations->profile_clean($obj['station_profile_id']);
$mygrid=($mystation->station_gridsquare ?? '');
if($obj['type'] == "adif" && $obj['string'] != "") {
// Load the logbook model for adding QSO records
@@ -220,13 +234,22 @@ class API extends CI_Controller {
}
if(count($record) == 0) {
break;
};
}
// in case the provided op call is the same as the clubstation callsign, we need to use the creator of the API key as the operator
$recorded_operator = $record['operator'] ?? '';
if ($real_operator != null && ($record['operator'] == $record['station_callsign']) || ($recorded_operator == '')) {
$record['operator'] = $real_operator;
}
if ((key_exists('gridsquare',$record)) && (($mygrid ?? '') != '') && (($record['gridsquare'] ?? '') != '') && (!(key_exists('distance',$record)))) {
$record['distance'] = $this->qra->distance($mygrid, $record['gridsquare'], 'K');
}
array_push($alladif,$record);
$adif_count++;
};
$record=''; // free memory
gc_collect_cycles();
$custom_errors = $this->logbook_model->import_bulk($alladif, $obj['station_profile_id'], false, false, false, false, false, false, false, true, false, true, false);
$custom_errors = $this->logbook_model->import_bulk($alladif, $obj['station_profile_id'], false, false, false, false, false, false, false, false, true, false, true, false);
if ($custom_errors) {
$adif_errors++;
}
@@ -236,8 +259,15 @@ class API extends CI_Controller {
$return_msg[]='Dryrun works';
}
http_response_code(201);
echo json_encode(['status' => 'created', 'type' => $obj['type'], 'string' => $obj['string'], 'adif_count' => $adif_count, 'adif_errors' => $adif_errors, 'messages' => $return_msg ]);
if ($adif_errors == 0) {
http_response_code(201);
echo json_encode(['status' => 'created', 'type' => $obj['type'], 'string' => $obj['string'], 'adif_count' => $adif_count, 'adif_errors' => $adif_errors, 'messages' => $return_msg ]);
} else {
$return_msg[]=$custom_errors;
http_response_code(400);
echo json_encode(['status' => 'abort', 'type' => $obj['type'], 'string' => $obj['string'], 'adif_count' => $adif_count, 'adif_errors' => $adif_errors, 'messages' => $return_msg ]);
}
}
@@ -559,6 +589,14 @@ class API extends CI_Controller {
$this->api_model->update_last_used($obj['key']);
$user_id = $this->api_model->key_userid($obj['key']);
$created_by = $this->api_model->key_created_by($obj['key']);
// Clubmode needs an additional check for the operator
if ($user_id != $created_by) {
$operator = $created_by;
} else {
$operator = $user_id;
}
// Special Case: Yaesu Radio's use CW-U and CW-L which aren't official ADIF Modes. We override this here to CW
if (isset($obj['mode']) && (strtoupper($obj['mode']) == 'CW-U' || strtoupper($obj['mode']) == 'CW-L')) {
@@ -566,7 +604,7 @@ class API extends CI_Controller {
}
// Store Result to Database
$this->cat->update($obj, $user_id);
$this->cat->update($obj, $user_id, $operator);
// Return Message

View File

@@ -1917,4 +1917,82 @@ class Awards extends CI_Controller {
$this->load->view('interface_assets/footer');
}
public function wae () {
$this->load->model('wae');
$this->load->model('modes');
$this->load->model('bands');
$data['orbits'] = $this->bands->get_worked_orbits();
$data['sats_available'] = $this->bands->get_worked_sats();
$data['user_default_band'] = $this->session->userdata('user_default_band');
$data['worked_bands'] = $this->bands->get_worked_bands('dxcc'); // Used in the view for band select
$data['modes'] = $this->modes->active(); // Used in the view for mode select
if ($this->input->post('band') != NULL) { // Band is not set when page first loads.
if ($this->input->post('band') == 'All') { // Did the user specify a band? If not, use all bands
$bands = $data['worked_bands'];
} else {
$bands[] = $this->security->xss_clean($this->input->post('band'));
}
} else {
$bands = $data['worked_bands'];
}
$data['bands'] = $bands; // Used for displaying selected band(s) in the table in the view
if($this->input->method() === 'post') {
$postdata['qsl'] = $this->input->post('qsl') == 0 ? NULL: 1;
$postdata['lotw'] = $this->input->post('lotw') == 0 ? NULL: 1;
$postdata['eqsl'] = $this->input->post('eqsl') == 0 ? NULL: 1;
$postdata['qrz'] = $this->input->post('qrz') == 0 ? NULL: 1;
$postdata['clublog'] = $this->input->post('clublog') == 0 ? NULL: 1;
$postdata['worked'] = $this->input->post('worked') == 0 ? NULL: 1;
$postdata['confirmed'] = $this->input->post('confirmed') == 0 ? NULL: 1;
$postdata['notworked'] = $this->input->post('notworked') == 0 ? NULL: 1;
$postdata['includedeleted'] = $this->security->xss_clean($this->input->post('includedeleted'));
$postdata['Africa'] = $this->security->xss_clean($this->input->post('Africa'));
$postdata['Asia'] = $this->security->xss_clean($this->input->post('Asia'));
$postdata['Europe'] = $this->security->xss_clean($this->input->post('Europe'));
$postdata['NorthAmerica'] = $this->security->xss_clean($this->input->post('NorthAmerica'));
$postdata['SouthAmerica'] = $this->security->xss_clean($this->input->post('SouthAmerica'));
$postdata['Oceania'] = $this->security->xss_clean($this->input->post('Oceania'));
$postdata['Antarctica'] = $this->security->xss_clean($this->input->post('Antarctica'));
$postdata['band'] = $this->security->xss_clean($this->input->post('band'));
$postdata['mode'] = $this->security->xss_clean($this->input->post('mode'));
$postdata['sat'] = $this->security->xss_clean($this->input->post('sats'));
$postdata['orbit'] = $this->security->xss_clean($this->input->post('orbits'));
} else { // Setting default values at first load of page
$postdata['qsl'] = 1;
$postdata['lotw'] = 1;
$postdata['eqsl'] = 0;
$postdata['qrz'] = 0;
$postdata['worked'] = 1;
$postdata['confirmed'] = 1;
$postdata['notworked'] = 1;
$postdata['includedeleted'] = 0;
$postdata['Africa'] = 1;
$postdata['Asia'] = 1;
$postdata['Europe'] = 1;
$postdata['NorthAmerica'] = 1;
$postdata['SouthAmerica'] = 1;
$postdata['Oceania'] = 1;
$postdata['Antarctica'] = 1;
$postdata['band'] = 'All';
$postdata['mode'] = 'All';
$postdata['sat'] = 'All';
$postdata['orbit'] = 'All';
}
$data['wae_array'] = $this->wae->get_wae_array($bands, $postdata);
$data['wae_summary'] = $this->wae->get_wae_summary($bands, $postdata);
// Render Page
$data['page_title'] = sprintf(__("Awards - %s"), __("WAE"));
$this->load->view('interface_assets/header', $data);
$this->load->view('awards/wae/index');
$this->load->view('interface_assets/footer');
}
}

View File

@@ -12,7 +12,7 @@ class Band extends CI_Controller {
$this->load->helper(array('form', 'url'));
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
}
public function index()

View File

@@ -13,7 +13,7 @@ class Cabrillo extends CI_Controller {
parent::__construct();
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
}
public function index() {

View File

@@ -15,7 +15,7 @@ class Cfdexport extends CI_Controller {
$this->load->model('logbook_model');
$this->load->model('bands');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$data['page_title'] = __("CFD Export");

View File

@@ -0,0 +1,243 @@
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Club extends CI_Controller
{
/**
* Permission Levels:
* 9 - Officer
* 3 - Member
*
* These permission levels are independent of the codeigniter permission levels and managed in the club_permissions table!
* https://github.com/wavelog/wavelog/wiki/Clubstations
*/
/**
* @var array $permissions
*/
private $permissions;
function __construct() {
parent::__construct();
$this->permissions = [
9 => __("Club Officer"),
3 => __("Club Member"),
];
}
public function index()
{
// nothing to display
redirect('dashboard');
}
public function permissions($club_id) {
$this->load->model('user_model');
$this->load->model('club_model');
$this->load->library('form_validation');
$cid = $this->security->xss_clean($club_id);
$club = $this->user_model->get_by_id($cid)->row();
if (!is_numeric($cid)) {
$this->session->set_flashdata('error', __("Invalid User ID!"));
redirect('user');
}
if(!$this->user_model->authorize(99) && !$this->club_model->club_authorize(9, $cid)) {
$this->session->set_flashdata('error', __("You're not allowed to do that!"));
redirect('dashboard');
}
if ($club->clubstation != 1) {
$this->session->set_flashdata('error', __("This user is not a club station."));
redirect('user');
}
$data['page_title'] = __("Club Permissions");
$data['club'] = $club;
$data['club_members'] = $this->club_model->get_club_members($cid);
$data['users'] = $this->user_model->users();
$data['permissions'] = $this->permissions;
$footerData = [];
$footerData['scripts'] = [
'assets/js/sections/club_permissions.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/club_permissions.js")),
];
$this->load->view('interface_assets/header', $data);
$this->load->view('club/permissions');
$this->load->view('interface_assets/footer', $footerData);
}
public function get_users() {
if(!clubaccess_check(9)) {
$this->session->set_flashdata('error', __("You're not allowed to do that!"));
redirect('dashboard');
}
if (!$this->load->is_loaded('user_model')) {
$this->load->model('user_model');
}
$query = (string) $this->input->post('query', true) ?? '';
if (empty($query)) {
header('Content-Type: application/json');
echo json_encode([]);
return;
}
$users = $this->user_model->search_users($query);
$result = [];
if ($users != false) {
foreach ($users->result() as $user) {
$result[] = [
'user_id' => $user->user_id,
'user_callsign' => $user->user_callsign,
'user_firstname' => $user->user_firstname,
'user_lastname' => $user->user_lastname
];
}
}
header('Content-Type: application/json');
echo json_encode($result);
}
public function alter_member() {
$this->load->model('user_model');
$this->load->model('club_model');
$club_id = $this->input->post('club_id', true);
$user_id = $this->input->post('user_id', true);
$p_level = $this->input->post('permission', true);
if (!is_numeric($club_id)) {
$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');
}
$this->club_model->alter_member($club_id, $user_id, $p_level);
if ($this->input->post('notify_user', true) == 'on') {
if (!$this->notification($user_id, $club_id, $this->input->post('notify_message', true))) {
$this->session->set_flashdata('error', __("User could not be notified. Please check your email settings."));
}
}
$this->session->set_flashdata('success', __("Club member permissions have been updated."));
redirect('club/permissions/'.$club_id);
}
public function delete_member() {
$this->load->model('user_model');
$this->load->model('club_model');
$club_id = $this->input->post('club_id', true);
$user_id = $this->input->post('user_id', true);
if (!is_numeric($club_id)) {
$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->club_model->delete_member($club_id, $user_id)) {
$this->session->set_flashdata('success', __("User removed from club."));
} else {
$this->session->set_flashdata('error', __("User could not be removed from club."));
}
redirect('club/permissions/'.$club_id);
}
public function switch_modal() {
$this->load->model('user_model');
$this->load->model('club_model');
$this->load->library('encryption');
$cid = $this->input->post('club_id', true);
$data['club_callsign'] = $this->input->post('club_callsign', true);
$user_id = $this->session->userdata('user_id');
if (!is_numeric($cid)) {
$this->session->set_flashdata('error', __("Invalid Club ID!"));
redirect('dashboard');
}
if(!$this->club_model->club_authorize(3, $cid)) {
$this->session->set_flashdata('error', __("You're not allowed to do that!"));
redirect('dashboard');
}
$data['impersonate_hash'] = $this->encryption->encrypt($user_id . '/' . $cid . '/' . time());
$this->load->view('club/clubswitch_modal', $data);
}
private function notification($user_id, $club_id, $message) {
$this->load->library('email');
$this->load->model('club_model');
switch ($message) {
case 'new_member':
$view = 'email/club/new_member';
break;
case 'modified_member':
$view = 'email/club/modified_member';
break;
default:
log_message('error', "Club Notification; Can't notify user - Invalid message type.");
$this->session->set_flashdata('error', __("Invalid message type."));
redirect('club/permissions/'.$club_id);
}
if($this->optionslib->get_option('emailProtocol') == "smtp") {
$config = [
'protocol' => $this->optionslib->get_option('emailProtocol'),
'smtp_crypto' => $this->optionslib->get_option('smtpEncryption'),
'smtp_host' => $this->optionslib->get_option('smtpHost'),
'smtp_port' => $this->optionslib->get_option('smtpPort'),
'smtp_user' => $this->optionslib->get_option('smtpUsername'),
'smtp_pass' => $this->optionslib->get_option('smtpPassword'),
'crlf' => "\r\n",
'newline' => "\r\n"
];
$this->email->initialize($config);
} else {
log_message('error', "Club Notification; Can't notify user - Email settings not configured.");
$this->session->set_flashdata('error', __("Email settings not configured."));
redirect('club/permissions/'.$club_id);
}
$user = $this->user_model->get_by_id($user_id)->row();
$club = $this->user_model->get_by_id($club_id)->row();
$permission = $this->club_model->get_permission($club_id, $user_id);
$permission_level = $this->permissions[$permission] ?? __("Unknown");
$mail_data['user_callsign'] = $user->user_callsign;
$mail_data['club_callsign'] = $club->user_callsign;
$mail_data['permission_level'] = $permission_level;
$message = $this->email->load($view, $mail_data, $user->user_language);
$this->email->from($this->optionslib->get_option('emailAddress'), $this->optionslib->get_option('emailSenderName'));
$this->email->to($user->user_email);
$this->email->subject($message['subject']);
$this->email->message($message['body']);
return $this->email->send();
}
}

View File

@@ -11,7 +11,7 @@ class Contesting extends CI_Controller {
parent::__construct();
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(99)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
}
public function index() {

View File

@@ -87,7 +87,7 @@ class cron extends CI_Controller {
if ($isdue == true) {
$isdue_result = 'true';
// TODO Add log_message level debug here to have logging for the cron manager
log_message('debug', 'CRON: ' . $cron->id . ' is due and will be executed.');
echo "CRON: " . $cron->id . " -> is due: " . $isdue_result . "\n";
echo "CRON: " . $cron->id . " -> RUNNING...\n";

View File

@@ -5,7 +5,7 @@ class Csv extends CI_Controller {
public function index() {
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$this->load->model('modes');
$this->load->model('logbook_model');

View File

@@ -3,39 +3,114 @@ defined('BASEPATH') OR exit('No direct script access allowed');
class Dayswithqso extends CI_Controller {
function __construct()
{
parent::__construct();
function __construct()
{
parent::__construct();
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
}
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
}
public function index()
{
$this->load->model('dayswithqso_model');
// Render Page
$data['page_title'] = __("Number of days with QSOs each year");
public function index() {
$this->load->model('dayswithqso_model');
// Render Page
$data['page_title'] = __("Days with QSOs");
$data['result'] = $this->dayswithqso_model->getDaysWithQso();
$data['streaks'] = $this->dayswithqso_model->getLongestStreak();
$data['currentstreak'] = $this->dayswithqso_model->getCurrentStreak();
$data['almostcurrentstreak'] = $this->dayswithqso_model->getAlmostCurrentStreak();
$data['result'] = $this->dayswithqso_model->getDaysWithQso();
$data['streaks'] = $this->dayswithqso_model->getLongestStreak();
$data['currentstreak'] = $this->dayswithqso_model->getCurrentStreak();
$data['almostcurrentstreak'] = $this->dayswithqso_model->getAlmostCurrentStreak();
$data['daysofweek'] = $this->dayswithqso_model->getDaysOfWeek();
$data['years'] = $this->get_years();
$this->load->view('interface_assets/header', $data);
$this->load->view('dayswithqso/index');
$this->load->view('interface_assets/footer');
}
$footerData = [];
$footerData['scripts'] = ['assets/js/jquery.glanceyear.js'];
public function get_days(){
$this->load->view('interface_assets/header', $data);
$this->load->view('dayswithqso/index');
$this->load->view('interface_assets/footer',$footerData);
}
//load model
$this->load->model('dayswithqso_model');
function get_years() {
$this->load->model('logbook_model');
$totals_year = $this->logbook_model->totals_year();
$years=[];
if ($totals_year) {
foreach($totals_year->result() as $years_obj) {
$years[] = $years_obj->year;
}
}
return $years;
}
// get data
$data = $this->dayswithqso_model->getDaysWithQso();
header('Content-Type: application/json');
echo json_encode($data);
}
public function get_punchvals($yr = null) {
$punchvals=[];
if (($yr ?? '') != '') {
$this->load->model('dayswithqso_model');
$res_punchvals = $this->dayswithqso_model->getPunchvals($this->security->xss_clean($yr));
if ($res_punchvals) {
foreach($res_punchvals as $pobj) {
$col=0;
switch (true) {
case ($pobj->qsos == 0):
$col=0;
break;
case ($pobj->qsos <= 3):
$col=3;
break;
case ($pobj->qsos <= 6):
$col=6;
break;
case ($pobj->qsos <= 12):
$col=12;
break;
case ($pobj->qsos <= 24):
$col=24;
break;
case ($pobj->qsos > 24):
$col=48;
break;
}
$punchvals[] = ['date' => $pobj->date, 'value' => $pobj->qsos, 'col' => $col];
}
}
} else {
$punchvals=[];
}
header('Content-Type: application/json');
echo json_encode($punchvals);
}
}
public function get_days(){
//load model
$this->load->model('dayswithqso_model');
// get data
$data = $this->dayswithqso_model->getDaysWithQso();
header('Content-Type: application/json');
echo json_encode($data);
}
public function get_weekdays() {
//load model
$this->load->model('dayswithqso_model');
// get data
$data = $this->dayswithqso_model->getDaysOfWeek();
header('Content-Type: application/json');
echo json_encode($data);
}
public function get_months() {
//load model
$this->load->model('dayswithqso_model');
// get data
$data = $this->dayswithqso_model->getMonthsOfYear();
header('Content-Type: application/json');
echo json_encode($data);
}
}

View File

@@ -27,6 +27,14 @@ class Debug extends CI_Controller
$footerData = [];
$footerData['scripts'] = ['assets/js/sections/debug.js'];
// Get Custom Date format
if ($this->session->userdata('user_date_format')) {
$custom_date_format = $this->session->userdata('user_date_format');
} else {
$custom_date_format = $this->config->item('qso_date_format');
}
$data['system_time'] = date($custom_date_format . " H:i:s", time());
$data['running_version'] = $this->optionslib->get_option('version');
$data['latest_release'] = $this->optionslib->get_option('latest_release');
@@ -102,6 +110,7 @@ class Debug extends CI_Controller
$data['scp_update'] = $this->cron_model->cron('update_update_clublog_scp')->row();
$data['sota_update'] = $this->cron_model->cron('update_update_sota')->row();
$data['wwff_update'] = $this->cron_model->cron('update_update_wwff')->row();
$data['tle_update'] = $this->cron_model->cron('update_update_tle')->row();
$data['page_title'] = __("Debug");
@@ -224,7 +233,7 @@ class Debug extends CI_Controller
// Show success message
$this->session->set_flashdata('success', __("Wavelog was updated successfully!"));
} catch (\Throwable $th) {
log_message("Error","Error at selfupdating");
}

View File

@@ -4,7 +4,7 @@ class Dxatlas extends CI_Controller {
public function index() {
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$this->load->model('modes');
$this->load->model('logbook_model');

View File

@@ -43,7 +43,7 @@ class eqsl extends CI_Controller {
public function import() {
$this->load->model('user_model');
if (!$this->user_model->authorize(2)) {
if (!$this->user_model->authorize(2) || !clubaccess_check(9)) {
$this->session->set_flashdata('error', __("You're not allowed to do that!"));
redirect('dashboard');
}
@@ -447,7 +447,7 @@ class eqsl extends CI_Controller {
$errors = 0;
$this->load->library('electronicqsl');
if ($this->input->post('eqsldownload') == 'download') {
if ($this->input->post('eqsldownload') == 'download' && $this->config->item('enable_eqsl_massdownload')) {
$i = 0;
$this->load->model('eqslmethods_model');
$qslsnotdownloaded = $this->eqslmethods_model->eqsl_not_yet_downloaded();

View File

@@ -33,6 +33,11 @@ class Gridmap extends CI_Controller {
$data['gridsquares_gridsquares_not_confirmed'] = __("Gridsquares not confirmed");
$data['gridsquares_gridsquares_total_worked'] = __("Total gridsquares worked");
$data['gridsquares_fields'] = __("Fields");
$data['gridsquares_fields_confirmed'] = __("Fields confirmed");
$data['gridsquares_fields_not_confirmed'] = __("Fields not confirmed");
$data['gridsquares_fields_total_worked'] = __("Total fields worked");
$footerData = [];
$footerData['scripts'] = [
'assets/js/leaflet/geocoding.js',

View File

@@ -32,6 +32,9 @@ class Hrdlog extends CI_Controller {
* Used for displaying the uid for manually selecting log for upload to hrdlog
*/
public function export() {
$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'); }
$this->load->model('stations');
$data['page_title'] = "HRDlog.net Logbook";

View File

@@ -15,7 +15,7 @@ class Kmlexport extends CI_Controller {
$this->load->model('logbook_model');
$this->load->model('bands');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$data['worked_bands'] = $this->bands->get_worked_bands(); // Used in the view for band select
$data['modes'] = $this->modes->active(); // Used in the view for mode select

View File

@@ -23,7 +23,7 @@ class Labels extends CI_Controller {
$this->load->helper(array('form', 'url', 'psr4_autoloader'));
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
}

View File

@@ -97,7 +97,8 @@ class Logbook extends CI_Controller {
// Check Database for all other data
$this->load->model('logbook_model');
$lotw_days=$this->logbook_model->check_last_lotw($callsign);
$lotw_days = $this->logbook_model->check_last_lotw($callsign);
if ($lotw_days != null) {
$lotw_member="active";
} else {
@@ -127,12 +128,12 @@ class Logbook extends CI_Controller {
$return['dxcc'] = $this->dxcheck($callsign,$date);
$lookupcall=$this->logbook_model->get_plaincall($callsign);
$return['partial'] = $this->partial($lookupcall, $band);
$lookupcall = $this->logbook_model->get_plaincall($callsign);
$callbook = $this->logbook_model->loadCallBook($callsign, $this->config->item('use_fullname'));
$return['partial'] = $this->partial($lookupcall, $callbook, $callsign, $return['dxcc'], $lotw_days, $band);
if ($this->session->userdata('user_measurement_base') == NULL) {
$measurement_base = $this->config->item('measurement_base');
} else {
@@ -144,6 +145,7 @@ class Logbook extends CI_Controller {
$return['callsign_distance'] = $this->distance($return['callsign_qra'], $station_id);
$return['callsign_qth'] = $this->nval($callbook['city'] ?? '', $this->logbook_model->call_qth($callsign));
$return['callsign_iota'] = $this->nval($callbook['iota'] ?? '', $this->logbook_model->call_iota($callsign));
$return['callsign_email'] = $this->nval($callbook['email'] ?? '', $this->logbook_model->call_email($callsign));
$return['qsl_manager'] = $this->nval($callbook['qslmgr'] ?? '', $this->logbook_model->call_qslvia($callsign));
$return['callsign_state'] = $this->nval($callbook['state'] ?? '', $this->logbook_model->call_state($callsign));
$return['callsign_us_county'] = $this->nval($callbook['us_county'] ?? '', $this->logbook_model->call_us_county($callsign));
@@ -613,7 +615,7 @@ class Logbook extends CI_Controller {
$this->load->view('interface_assets/footer');
}
function partial($id, $band = null) {
function partial($lookupcall, $callbook, $callsign, $dxcc, $lotw_days, $band = null) {
$this->load->model('user_model');
if(!$this->user_model->authorize($this->config->item('auth_mode'))) { return; }
@@ -623,17 +625,18 @@ class Logbook extends CI_Controller {
$html = "";
if(!empty($logbooks_locations_array)) {
$this->db->select(''.$this->config->item('table_name').'.COL_CALL, '.$this->config->item('table_name').'.COL_BAND, '.$this->config->item('table_name').'.COL_FREQ, '.$this->config->item('table_name').'.COL_TIME_ON, '.$this->config->item('table_name').'.COL_RST_RCVD, '.$this->config->item('table_name').'.COL_RST_SENT, '.$this->config->item('table_name').'.COL_MODE, '.$this->config->item('table_name').'.COL_SUBMODE, '.$this->config->item('table_name').'.COL_PRIMARY_KEY, '.$this->config->item('table_name').'.COL_SAT_NAME, '.$this->config->item('table_name').'.COL_GRIDSQUARE, '.$this->config->item('table_name').'.COL_QSL_RCVD, '.$this->config->item('table_name').'.COL_EQSL_QSL_RCVD, '.$this->config->item('table_name').'.COL_EQSL_QSL_SENT, '.$this->config->item('table_name').'.COL_QSL_SENT, '.$this->config->item('table_name').'.COL_STX, '.$this->config->item('table_name').'.COL_STX_STRING, '.$this->config->item('table_name').'.COL_SRX, '.$this->config->item('table_name').'.COL_SRX_STRING, '.$this->config->item('table_name').'.COL_LOTW_QSL_SENT, '.$this->config->item('table_name').'.COL_LOTW_QSL_RCVD, '.$this->config->item('table_name').'.COL_VUCC_GRIDS, '.$this->config->item('table_name').'.COL_MY_GRIDSQUARE, '.$this->config->item('table_name').'.COL_CONTEST_ID, '.$this->config->item('table_name').'.COL_STATE, '.$this->config->item('table_name').'.COL_QRZCOM_QSO_UPLOAD_STATUS, '.$this->config->item('table_name').'.COL_QRZCOM_QSO_DOWNLOAD_STATUS, '.$this->config->item('table_name').'.COL_CLUBLOG_QSO_UPLOAD_STATUS, '.$this->config->item('table_name').'.COL_CLUBLOG_QSO_DOWNLOAD_STATUS, '.$this->config->item('table_name').'.COL_POTA_REF, '.$this->config->item('table_name').'.COL_IOTA, '.$this->config->item('table_name').'.COL_SOTA_REF, '.$this->config->item('table_name').'.COL_WWFF_REF, '.$this->config->item('table_name').'.COL_OPERATOR, '.$this->config->item('table_name').'.COL_COUNTRY, station_profile.*');
$this->db->select(''.$this->config->item('table_name').'.COL_CALL, '.$this->config->item('table_name').'.COL_BAND, '.$this->config->item('table_name').'.COL_FREQ, '.$this->config->item('table_name').'.COL_TIME_ON, '.$this->config->item('table_name').'.COL_RST_RCVD, '.$this->config->item('table_name').'.COL_RST_SENT, '.$this->config->item('table_name').'.COL_MODE, '.$this->config->item('table_name').'.COL_SUBMODE, '.$this->config->item('table_name').'.COL_PRIMARY_KEY, '.$this->config->item('table_name').'.COL_SAT_NAME, '.$this->config->item('table_name').'.COL_GRIDSQUARE, '.$this->config->item('table_name').'.COL_QSL_RCVD, '.$this->config->item('table_name').'.COL_EQSL_QSL_RCVD, '.$this->config->item('table_name').'.COL_EQSL_QSL_SENT, '.$this->config->item('table_name').'.COL_QSL_SENT, '.$this->config->item('table_name').'.COL_STX, '.$this->config->item('table_name').'.COL_STX_STRING, '.$this->config->item('table_name').'.COL_SRX, '.$this->config->item('table_name').'.COL_SRX_STRING, '.$this->config->item('table_name').'.COL_LOTW_QSL_SENT, '.$this->config->item('table_name').'.COL_LOTW_QSL_RCVD, '.$this->config->item('table_name').'.COL_VUCC_GRIDS, '.$this->config->item('table_name').'.COL_MY_GRIDSQUARE, '.$this->config->item('table_name').'.COL_CONTEST_ID, '.$this->config->item('table_name').'.COL_STATE, '.$this->config->item('table_name').'.COL_QRZCOM_QSO_UPLOAD_STATUS, '.$this->config->item('table_name').'.COL_QRZCOM_QSO_DOWNLOAD_STATUS, '.$this->config->item('table_name').'.COL_CLUBLOG_QSO_UPLOAD_STATUS, '.$this->config->item('table_name').'.COL_CLUBLOG_QSO_DOWNLOAD_STATUS, '.$this->config->item('table_name').'.COL_POTA_REF, '.$this->config->item('table_name').'.COL_IOTA, '.$this->config->item('table_name').'.COL_SOTA_REF, '.$this->config->item('table_name').'.COL_WWFF_REF, '.$this->config->item('table_name').'.COL_OPERATOR, '.$this->config->item('table_name').'.COL_COUNTRY, station_profile.*, satellite.displayname AS sat_displayname');
$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('satellite', 'satellite.name = '.$this->config->item('table_name').'.COL_SAT_NAME', 'left outer');
$this->db->where_in('station_profile.station_id', $logbooks_locations_array);
$this->db->group_start();
$this->db->where($this->config->item('table_name').'.COL_CALL', $id);
$this->db->or_like($this->config->item('table_name').'.COL_CALL', '/'.$id,'before');
$this->db->or_like($this->config->item('table_name').'.COL_CALL', $id.'/','after');
$this->db->or_like($this->config->item('table_name').'.COL_CALL', '/'.$id.'/');
$this->db->where($this->config->item('table_name').'.COL_CALL', $lookupcall);
$this->db->or_like($this->config->item('table_name').'.COL_CALL', '/'.$lookupcall,'before');
$this->db->or_like($this->config->item('table_name').'.COL_CALL', $lookupcall.'/','after');
$this->db->or_like($this->config->item('table_name').'.COL_CALL', '/'.$lookupcall.'/');
$this->db->group_end();
$this->db->order_by($this->config->item('table_name').".COL_TIME_ON", "desc");
@@ -824,82 +827,28 @@ class Logbook extends CI_Controller {
$html .= "</div>";
return $html;
} else {
if ($this->config->item('callbook') == "qrz" && $this->config->item('qrz_username') != null && $this->config->item('qrz_password') != null) {
// Lookup using QRZ
$this->load->library('qrz');
$callsigninfo['callsign'] = $callbook;
if(!$this->session->userdata('qrz_session_key')) {
$qrz_session_key = $this->qrz->session($this->config->item('qrz_username'), $this->config->item('qrz_password'));
$this->session->set_userdata('qrz_session_key', $qrz_session_key);
}
$callsign['callsign'] = $this->qrz->search($id, $this->session->userdata('qrz_session_key'), $this->config->item('use_fullname'));
if ($dxcc['adif'] !== 0) {
$this->load->model('logbook_model');
$callsigninfo['callsign']['dxcc_name'] = $dxcc['entity'];
$callsigninfo['dxcc_worked'] = $this->logbook_model->check_if_dxcc_worked_in_logbook($dxcc['adif'], null, $this->session->userdata('user_default_band'));
$callsigninfo['dxcc_confirmed'] = $this->logbook_model->check_if_dxcc_cnfmd_in_logbook($dxcc['adif'], null, $this->session->userdata('user_default_band'));
}
if (empty($callsign['callsign']['callsign'])) {
$qrz_session_key = $this->qrz->session($this->config->item('qrz_username'), $this->config->item('qrz_password'));
$this->session->set_userdata('qrz_session_key', $qrz_session_key);
$callsign['callsign'] = $this->qrz->search($id, $this->session->userdata('qrz_session_key'), $this->config->item('use_fullname'));
}
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'];
$callsign['dxcc_worked'] = $this->logbook_model->check_if_dxcc_worked_in_logbook($callsign['callsign']['dxcc'], null, $this->session->userdata('user_default_band'));
$callsign['dxcc_confirmed'] = $this->logbook_model->check_if_dxcc_cnfmd_in_logbook($callsign['callsign']['dxcc'], null, $this->session->userdata('user_default_band'));
}
} else if ($this->config->item('callbook') == "hamqth" && $this->config->item('hamqth_username') != null && $this->config->item('hamqth_password') != null) {
// Load the HamQTH library
$this->load->library('hamqth');
if (isset($callsigninfo['callsign']['gridsquare'])) {
$this->load->model('logbook_model');
$callsigninfo['grid_worked'] = $this->logbook_model->check_if_grid_worked_in_logbook(strtoupper(substr($callsigninfo['callsign']['gridsquare'],0,4)), null, $band)->num_rows();
}
if(!$this->session->userdata('hamqth_session_key')) {
$hamqth_session_key = $this->hamqth->session($this->config->item('hamqth_username'), $this->config->item('hamqth_password'));
$this->session->set_userdata('hamqth_session_key', $hamqth_session_key);
}
if (isset($callsigninfo['callsign']['error'])) {
$callsigninfo['error'] = $callsigninfo['callsign']['error'];
}
$callsign['callsign'] = $this->hamqth->search($id, $this->session->userdata('hamqth_session_key'));
// If HamQTH session has expired, start a new session and retry the search.
if($callsign['callsign']['error'] == "Session does not exist or expired") {
$hamqth_session_key = $this->hamqth->session($this->config->item('hamqth_username'), $this->config->item('hamqth_password'));
$this->session->set_userdata('hamqth_session_key', $hamqth_session_key);
$callsign['callsign'] = $this->hamqth->search($id, $this->session->userdata('hamqth_session_key'));
}
if (isset($data['callsign']['gridsquare'])) {
$this->load->model('logbook_model');
$callsign['grid_worked'] = $this->logbook_model->check_if_grid_worked_in_logbook(strtoupper(substr($data['callsign']['gridsquare'],0,4)), null, $this->session->userdata('user_default_band'))->num_rows();
}
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'];
$callsign['dxcc_worked'] = $this->logbook_model->check_if_dxcc_worked_in_logbook($callsign['callsign']['dxcc'], null, $this->session->userdata('user_default_band'));
$callsign['dxcc_confirmed'] = $this->logbook_model->check_if_dxcc_cnfmd_in_logbook($callsign['callsign']['dxcc'], null, $this->session->userdata('user_default_band'));
}
if (isset($callsign['callsign']['error'])) {
$callsign['error'] = $callsign['callsign']['error'];
}
} else {
$callsign['error'] = 'Lookup not configured. Please review configuration.';
}
// There's no hamli integration? Disabled for now.
/*else {
// Lookup using hamli
$this->load->library('hamli');
$callsign['callsign'] = $this->hamli->callsign($id);
}*/
if (isset($callsign['callsign']['gridsquare'])) {
$this->load->model('logbook_model');
$callsign['grid_worked'] = $this->logbook_model->check_if_grid_worked_in_logbook(strtoupper(substr($callsign['callsign']['gridsquare'],0,4)), null, $band)->num_rows();
}
if (isset($callsign['callsign']['error'])) {
$callsign['error'] = $callsign['callsign']['error'];
}
$callsign['id'] = strtoupper($id);
$callsign['lotw_lastupload'] = $this->logbook_model->check_last_lotw($id);
return $this->load->view('search/result', $callsign, true);
$callsigninfo['lookupcall'] = strtoupper($lookupcall);
$callsigninfo['realcall'] = strtoupper($callsign);
$callsigninfo['lotw_lastupload'] = $lotw_days;
return $this->load->view('search/result', $callsigninfo, true);
}
}
@@ -909,6 +858,8 @@ class Logbook extends CI_Controller {
if(!$this->user_model->authorize($this->config->item('auth_mode'))) { return; }
$id = str_replace('Ø', "0", $id);
$id2 = str_replace('Ø', "0", $id2);
$fixedid = $id;
if ($id2 != "") {
@@ -936,67 +887,27 @@ class Logbook extends CI_Controller {
$data['results'] = $iota_search;
$this->load->view('view_log/partial/log_ajax.php', $data);
} else {
if ($this->config->item('callbook') == "qrz" && $this->config->item('qrz_username') != null && $this->config->item('qrz_password') != null) {
// Lookup using QRZ
$this->load->library('qrz');
if (!$this->load->is_loaded('callbook')) {
$this->load->library('callbook');
}
if(!$this->session->userdata('qrz_session_key')) {
$qrz_session_key = $this->qrz->session($this->config->item('qrz_username'), $this->config->item('qrz_password'));
$this->session->set_userdata('qrz_session_key', $qrz_session_key);
}
$data['callsign'] = $this->callbook->getCallbookData($id);
$data['callsign'] = $this->qrz->search($id, $this->session->userdata('qrz_session_key'), $this->config->item('use_fullname'));
if (isset($data['callsign']['gridsquare'])) {
$data['grid_worked'] = $this->logbook_model->check_if_grid_worked_in_logbook(strtoupper(substr($data['callsign']['gridsquare'],0,4)), null, $this->session->userdata('user_default_band'))->num_rows();
}
if (isset($data['callsign']['dxcc'])) {
$entity = $this->logbook_model->get_entity($data['callsign']['dxcc']);
$data['callsign']['dxcc_name'] = $entity['name'];
$data['dxcc_worked'] = $this->logbook_model->check_if_dxcc_worked_in_logbook($data['callsign']['dxcc'], null, $this->session->userdata('user_default_band'));
$data['dxcc_confirmed'] = $this->logbook_model->check_if_dxcc_cnfmd_in_logbook($data['callsign']['dxcc'], null, $this->session->userdata('user_default_band'));
}
if (isset($data['callsign']['error'])) {
$data['error'] = $data['callsign']['error'];
}
} else if ($this->config->item('callbook') == "hamqth" && $this->config->item('hamqth_username') != null && $this->config->item('hamqth_password') != null) {
// Load the HamQTH library
$this->load->library('hamqth');
if (isset($data['callsign']['gridsquare'])) {
$data['grid_worked'] = $this->logbook_model->check_if_grid_worked_in_logbook(strtoupper(substr($data['callsign']['gridsquare'],0,4)), null, $this->session->userdata('user_default_band'))->num_rows();
}
if (isset($data['callsign']['dxcc'])) {
$entity = $this->logbook_model->get_entity($data['callsign']['dxcc']);
$data['callsign']['dxcc_name'] = $entity['name'];
$data['dxcc_worked'] = $this->logbook_model->check_if_dxcc_worked_in_logbook($data['callsign']['dxcc'], null, $this->session->userdata('user_default_band'));
$data['dxcc_confirmed'] = $this->logbook_model->check_if_dxcc_cnfmd_in_logbook($data['callsign']['dxcc'], null, $this->session->userdata('user_default_band'));
}
if (isset($data['callsign']['error'])) {
$data['error'] = $data['callsign']['error'];
}
if(!$this->session->userdata('hamqth_session_key')) {
$hamqth_session_key = $this->hamqth->session($this->config->item('hamqth_username'), $this->config->item('hamqth_password'));
$this->session->set_userdata('hamqth_session_key', $hamqth_session_key);
}
$data['callsign'] = $this->hamqth->search($id, $this->session->userdata('hamqth_session_key'));
// If HamQTH session has expired, start a new session and retry the search.
if($data['callsign']['error'] == "Session does not exist or expired") {
$hamqth_session_key = $this->hamqth->session($this->config->item('hamqth_username'), $this->config->item('hamqth_password'));
$this->session->set_userdata('hamqth_session_key', $hamqth_session_key);
$data['callsign'] = $this->hamqth->search($id, $this->session->userdata('hamqth_session_key'));
}
if (isset($data['callsign']['gridsquare'])) {
$data['grid_worked'] = $this->logbook_model->check_if_grid_worked_in_logbook(strtoupper(substr($data['callsign']['gridsquare'],0,4)), null, $this->session->userdata('user_default_band'))->num_rows();
}
if (isset($data['callsign']['dxcc'])) {
$entity = $this->logbook_model->get_entity($data['callsign']['dxcc']);
$data['callsign']['dxcc_name'] = $entity['name'];
$data['dxcc_worked'] = $this->logbook_model->check_if_dxcc_worked_in_logbook($data['callsign']['dxcc'], null, $this->session->userdata('user_default_band'));
$data['dxcc_confirmed'] = $this->logbook_model->check_if_dxcc_cnfmd_in_logbook($data['callsign']['dxcc'], null, $this->session->userdata('user_default_band'));
}
if (isset($data['callsign']['error'])) {
$data['error'] = $data['callsign']['error'];
}
} else {
$data['error'] = 'Lookup not configured. Please review configuration.';
} /*else {
// Lookup using hamli
$this->load->library('hamli');
$data['callsign'] = $this->hamli->callsign($id);
}*/
$data['id'] = strtoupper($id);
$data['lookupcall'] = strtoupper($id);
$data['realcall'] = strtoupper($id);
$data['lotw_lastupload'] = $this->logbook_model->check_last_lotw($id);
$this->load->view('search/result', $data);
@@ -1009,10 +920,22 @@ class Logbook extends CI_Controller {
}
function querydb($id) {
$this->db->select('dxcc_entities.adif, lotw_users.callsign, COL_BAND, COL_CALL, COL_CLUBLOG_QSO_DOWNLOAD_DATE,
COL_CLUBLOG_QSO_DOWNLOAD_STATUS, COL_CLUBLOG_QSO_UPLOAD_DATE, COL_CLUBLOG_QSO_UPLOAD_STATUS,
COL_CONTEST_ID, COL_DISTANCE, COL_EQSL_QSL_RCVD, COL_EQSL_QSLRDATE, COL_EQSL_QSLSDATE, COL_EQSL_QSL_SENT,
COL_FREQ, COL_GRIDSQUARE, COL_IOTA, COL_LOTW_QSL_RCVD, COL_LOTW_QSLRDATE, COL_LOTW_QSLSDATE,
COL_LOTW_QSL_SENT, COL_MODE, COL_NAME, COL_OPERATOR, COL_POTA_REF, COL_PRIMARY_KEY,
COL_QRZCOM_QSO_DOWNLOAD_DATE, COL_QRZCOM_QSO_DOWNLOAD_STATUS, COL_QRZCOM_QSO_UPLOAD_DATE,
COL_QRZCOM_QSO_UPLOAD_STATUS, COL_QSL_RCVD, COL_QSL_RCVD_VIA, COL_QSLRDATE, COL_QSLSDATE, COL_QSL_SENT,
COL_QSL_SENT_VIA, COL_QSL_VIA, COL_RST_RCVD, COL_RST_SENT, COL_SAT_NAME, COL_SOTA_REF, COL_SRX,
COL_SRX_STRING, COL_STATE, COL_STX, COL_STX_STRING, COL_SUBMODE, COL_TIME_ON, COL_VUCC_GRIDS, COL_WWFF_REF,
dxcc_entities.end, lotw_users.lastupload, satellite.displayname AS sat_displayname, station_profile.station_callsign,
station_profile.station_gridsquare, station_profile.station_profile_name, dxcc_entities.name');
$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', 'left outer');
$this->db->join('lotw_users', 'lotw_users.callsign = '.$this->config->item('table_name').'.col_call', 'left outer');
$this->db->join('satellite', 'satellite.name = '.$this->config->item('table_name').'.COL_SAT_NAME', 'left outer');
$this->db->group_start();
$this->db->like(''.$this->config->item('table_name').'.COL_CALL', $id);
$this->db->or_like(''.$this->config->item('table_name').'.COL_GRIDSQUARE', $id);
@@ -1184,6 +1107,7 @@ class Logbook extends CI_Controller {
/* return station bearing */
function searchbearing() {
$locator = xss_clean($this->input->post('grid'));
$ant_path = xss_clean($this->input->post('ant_path')) == '' ? NULL : xss_clean($this->input->post('ant_path'));
$station_id = xss_clean($this->input->post('stationProfile'));
if(!$this->load->is_loaded('Qra')) {
$this->load->library('Qra');
@@ -1215,7 +1139,7 @@ class Logbook extends CI_Controller {
$measurement_base = $this->session->userdata('user_measurement_base');
}
$bearing = $this->qra->bearing($mylocator, $locator, $measurement_base);
$bearing = $this->qra->bearing($mylocator, $locator, $measurement_base, $ant_path);
echo $bearing;
}
@@ -1225,6 +1149,7 @@ class Logbook extends CI_Controller {
/* return distance */
function searchdistance() {
$locator = xss_clean($this->input->post('grid'));
$ant_path = xss_clean($this->input->post('ant_path')) == '' ? NULL : xss_clean($this->input->post('ant_path'));
$station_id = xss_clean($this->input->post('stationProfile'));
if(!$this->load->is_loaded('Qra')) {
$this->load->library('Qra');
@@ -1249,7 +1174,7 @@ class Logbook extends CI_Controller {
$mylocator = $this->config->item('locator');
}
$distance = $this->qra->distance($mylocator, $locator, 'K');
$distance = $this->qra->distance($mylocator, $locator, 'K', $ant_path);
echo $distance;
}
@@ -1257,7 +1182,7 @@ class Logbook extends CI_Controller {
}
/* return station bearing */
function bearing($locator, $unit = 'M', $station_id = null) {
function bearing($locator, $unit = 'M', $station_id = null, $ant_path = null) {
if(!$this->load->is_loaded('Qra')) {
$this->load->library('Qra');
}
@@ -1281,7 +1206,7 @@ class Logbook extends CI_Controller {
$mylocator = $this->config->item('locator');
}
$bearing = $this->qra->bearing($mylocator, $locator, $unit);
$bearing = $this->qra->bearing($mylocator, $locator, $unit, $ant_path);
return $bearing;
}
@@ -1289,7 +1214,7 @@ class Logbook extends CI_Controller {
}
/* return distance */
function distance($locator, $station_id = null) {
function distance($locator, $station_id = null, $ant_path = null) {
$distance = 0;
if(!$this->load->is_loaded('Qra')) {
$this->load->library('Qra');
@@ -1314,7 +1239,7 @@ class Logbook extends CI_Controller {
$mylocator = $this->config->item('locator');
}
$distance = $this->qra->distance($mylocator, $locator, 'K');
$distance = $this->qra->distance($mylocator, $locator, 'K', $ant_path);
}
return $distance;
@@ -1394,8 +1319,8 @@ class Logbook extends CI_Controller {
case 'POTA': $ret.= '<td>' . ($row->COL_POTA_REF) . '</td>'; break;
case 'Grid': $ret.= '<td>' . $this->part_QrbCalcLink($row->COL_MY_GRIDSQUARE, $row->COL_VUCC_GRIDS, $row->COL_GRIDSQUARE) . '</td>'; break;
case 'Distance': $ret.= '<td>' . (($row->COL_DISTANCE ?? '' != '') ? $row->COL_DISTANCE . '&nbsp;km' : '') . '</td>'; break;
case 'Band': $ret.= '<td>'; if($row->COL_SAT_NAME != null) { $ret.= '<a href="https://db.satnogs.org/search/?q='.$row->COL_SAT_NAME.'" target="_blank">'.$row->COL_SAT_NAME.'</a></td>'; } else { $ret.= strtolower($row->COL_BAND); } $ret.= '</td>'; break;
case 'Frequency': $ret.= '<td>'; if($row->COL_SAT_NAME != null) { $ret.= '<a href="https://db.satnogs.org/search/?q='.$row->COL_SAT_NAME.'" target="_blank">'.$row->COL_SAT_NAME.'</a></td>'; } else { if($row->COL_FREQ != null) { $ret.= $this->frequency->qrg_conversion($row->COL_FREQ); } else { $ret.= strtolower($row->COL_BAND); } } $ret.= '</td>'; break;
case 'Band': $ret.= '<td>'; if($row->COL_SAT_NAME != null) { $ret.= '<a href="https://db.satnogs.org/search/?q='.$row->COL_SAT_NAME.'" target="_blank">'.($row->sat_displayname != null ? $row->sat_displayname." (".$row->COL_SAT_NAME.")" : $row->COL_SAT_NAME).'</a></td>'; } else { $ret.= strtolower($row->COL_BAND); } $ret.= '</td>'; break;
case 'Frequency': $ret.= '<td>'; if($row->COL_SAT_NAME != null) { $ret.= '<a href="https://db.satnogs.org/search/?q='.$row->COL_SAT_NAME.'" target="_blank">'.($row->sat_displayname != null ? $row->sat_displayname." (".$row->COL_SAT_NAME.")" : $row->COL_SAT_NAME).'</a></td>'; } else { if($row->COL_FREQ != null) { $ret.= $this->frequency->qrg_conversion($row->COL_FREQ); } else { $ret.= strtolower($row->COL_BAND); } } $ret.= '</td>'; break;
case 'State': $ret.= '<td>' . ($row->COL_STATE) . '</td>'; break;
case 'Operator': $ret.= '<td>' . ($row->COL_OPERATOR) . '</td>'; break;
}

View File

@@ -158,11 +158,13 @@ class Logbookadvanced extends CI_Controller {
}
public function updateFromCallbook() {
if(!clubaccess_check(9)) return;
$this->load->model('logbook_model');
$this->load->model('logbookadvanced_model');
$qsoID = xss_clean($this->input->post('qsoID'));
$qso = $this->logbook_model->qso_info($qsoID)->row_array();
$qsoID[] = xss_clean($this->input->post('qsoID'));
$qso = $this->logbookadvanced_model->getQsosForAdif(json_encode($qsoID), $this->session->userdata('user_id'))->row_array();
if ($qso === null) {
header("Content-Type: application/json");
echo json_encode([]);
@@ -172,8 +174,8 @@ class Logbookadvanced extends CI_Controller {
$callbook = $this->logbook_model->loadCallBook($qso['COL_CALL'], $this->config->item('use_fullname'));
if ($callbook['callsign'] ?? "" !== "") {
$this->logbookadvanced_model->updateQsoWithCallbookInfo($qsoID, $qso, $callbook);
$qso = $this->logbook_model->qso_info($qsoID)->row_array();
$this->logbookadvanced_model->updateQsoWithCallbookInfo($qso['COL_PRIMARY_KEY'], $qso, $callbook);
$qso = $this->logbookadvanced_model->getQsosForAdif(json_encode($qsoID), $this->session->userdata('user_id'))->row_array();
}
$qsoObj = new QSO($qso);
@@ -183,6 +185,8 @@ class Logbookadvanced extends CI_Controller {
}
function export_to_adif() {
if(!clubaccess_check(9)) return;
ini_set('memory_limit', '-1');
set_time_limit(0);
$this->load->model('logbookadvanced_model');
@@ -197,6 +201,8 @@ class Logbookadvanced extends CI_Controller {
}
function export_to_adif_params() {
if(!clubaccess_check(9)) return;
ini_set('memory_limit', '-1');
set_time_limit(0);
$this->load->model('logbookadvanced_model');
@@ -211,6 +217,8 @@ class Logbookadvanced extends CI_Controller {
}
function update_qsl() {
if(!clubaccess_check(9)) return;
$this->load->model('logbookadvanced_model');
$ids = xss_clean($this->input->post('id'));
@@ -239,6 +247,8 @@ class Logbookadvanced extends CI_Controller {
}
function update_qsl_received() {
if(!clubaccess_check(9)) return;
$this->load->model('logbookadvanced_model');
$ids = xss_clean($this->input->post('id'));
@@ -285,7 +295,7 @@ class Logbookadvanced extends CI_Controller {
'dateFrom' => '',
'dateTo' => '',
'de' => $this->input->post('de'),
'dx' => '',
'dx' => '*',
'mode' => '',
'band' => '',
'qslSent' => '',
@@ -295,8 +305,8 @@ class Logbookadvanced extends CI_Controller {
'iota' => '',
'dxcc' => '',
'propmode' => '',
'gridsquare' => '',
'state' => '',
'gridsquare' => '*',
'state' => '*',
'cqzone' => '',
'ituzone' => '',
'qsoresults' => count($this->input->post('ids')),
@@ -308,13 +318,13 @@ class Logbookadvanced extends CI_Controller {
'eqslReceived' => '',
'clublogSent' => '',
'clublogReceived' => '',
'qslvia' => '',
'sota' => '',
'pota' => '',
'wwff' => '',
'qslvia' => '*',
'sota' => '*',
'pota' => '*',
'wwff' => '*',
'qslimages' => '',
'operator' => '',
'contest' => '',
'operator' => '*',
'contest' => '*',
'continent' => '',
'ids' => xss_clean($this->input->post('ids'))
);
@@ -448,8 +458,8 @@ class Logbookadvanced extends CI_Controller {
}
$this->load->model('logbook_model');
$data['distance'] = $this->qra->distance($locator1, $locator2, $measurement_base) . $var_dist;
$data['bearing'] = $this->qra->get_bearing($locator1, $locator2) . "&#186;";
$data['distance'] = $this->qra->distance($locator1, $locator2, $measurement_base, $qso['COL_ANT_PATH']) . $var_dist;
$data['bearing'] = $this->qra->get_bearing($locator1, $locator2, $qso['COL_ANT_PATH']) . "&#186;";
$latlng1 = $this->qra->qra2latlong($locator1);
$latlng2 = $this->qra->qra2latlong($locator2);
$latlng1[0] = number_format((float)$latlng1[0], 3, '.', '');;
@@ -504,6 +514,8 @@ class Logbookadvanced extends CI_Controller {
}
public function userOptions() {
if(!clubaccess_check(9)) return;
$this->load->model('user_options_model');
$userOptions = $this->user_options_model->get_options('LogbookAdvanced')->result();
if (isset($userOptions[0])) {
@@ -524,6 +536,8 @@ class Logbookadvanced extends CI_Controller {
}
public function setUserOptions() {
if(!clubaccess_check(9)) return;
$json_string['datetime']['show'] = $this->input->post('datetime');
$json_string['de']['show'] = $this->input->post('de');
$json_string['dx']['show'] = $this->input->post('dx');
@@ -559,6 +573,7 @@ class Logbookadvanced extends CI_Controller {
$json_string['profilename']['show'] = $this->input->post('profilename');
$json_string['stationpower']['show'] = $this->input->post('stationpower');
$json_string['distance']['show'] = $this->input->post('distance');
$json_string['region']['show'] = $this->input->post('region');
$obj['column_settings']= json_encode($json_string);
@@ -574,6 +589,8 @@ class Logbookadvanced extends CI_Controller {
}
public function editDialog() {
if(!clubaccess_check(9)) return;
$this->load->model('bands');
$this->load->model('modes');
$this->load->model('logbookadvanced_model');
@@ -588,6 +605,8 @@ class Logbookadvanced extends CI_Controller {
}
public function saveBatchEditQsos() {
if(!clubaccess_check(9)) return;
$ids = xss_clean($this->input->post('ids'));
$column = xss_clean($this->input->post('column'));
$value = xss_clean($this->input->post('value'));
@@ -624,6 +643,8 @@ class Logbookadvanced extends CI_Controller {
}
public function batchDeleteQsos() {
if(!clubaccess_check(9)) return;
$ids = xss_clean($this->input->post('ids'));
$this->load->model('logbookadvanced_model');

View File

@@ -41,7 +41,7 @@ class Lotw extends CI_Controller {
public function index() {
$this->load->library('Permissions');
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
// Load required models for page generation
$this->load->model('Lotw_model');
@@ -99,8 +99,7 @@ class Lotw extends CI_Controller {
| and processing of p12 files and storing the data into mysql
|
*/
public function do_cert_upload()
{
public function do_cert_upload() {
$this->load->model('user_model');
$this->load->model('dxcc');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
@@ -115,8 +114,7 @@ class Lotw extends CI_Controller {
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload('userfile'))
{
if ( ! $this->upload->do_upload('userfile')) {
// Upload of P12 Failed
$error = array('error' => $this->upload->display_errors());
@@ -130,9 +128,7 @@ class Lotw extends CI_Controller {
$this->load->view('interface_assets/header', $data);
$this->load->view('lotw_views/upload_cert', $error);
$this->load->view('interface_assets/footer');
}
else
{
} else {
// Load database queries
$this->load->model('Lotw_model');
@@ -473,7 +469,7 @@ class Lotw extends CI_Controller {
private function loadFromFile($filepath, $station_ids, $display_view = "TRUE") {
// Figure out how we should be marking QSLs confirmed via LoTW
$query = $query = $this->db->query('SELECT lotw_rcvd_mark FROM config');
$query = $this->db->query('SELECT lotw_rcvd_mark FROM config');
$q = $query->row();
$config['lotw_rcvd_mark'] = $q->lotw_rcvd_mark;
@@ -545,6 +541,8 @@ class Lotw extends CI_Controller {
}
}
$ant_path = $status[3] ?? '';
if (isset($record['vucc_grids'])) {
$qsl_vucc_grids = $record['vucc_grids'];
} else {
@@ -575,7 +573,13 @@ 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, $qsl_vucc_grids, $iota, $cnty, $cqz, $ituz, $record['station_callsign'],$qso_id4lotw, $station_ids);
if (isset($record['dxcc'])) {
$dxcc = $record['dxcc'];
} else {
$dxcc = "";
}
$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'],$qso_id4lotw, $station_ids, $dxcc, $ant_path);
$table .= "<tr>";
$table .= "<td>".$record['station_callsign']."</td>";
@@ -659,6 +663,7 @@ class Lotw extends CI_Controller {
foreach ($query->result() as $user) {
if ( ($sync_user_id != null) && ($sync_user_id != $user->user_id) ) { continue; }
$station_ids=$this->Stations->all_station_ids_of_user($user->user_id);
if ($station_ids == '') { continue; } // User has no Station-ID! next one
// Validate that LoTW credentials are not empty
// TODO: We don't actually see the error message
@@ -668,14 +673,14 @@ class Lotw extends CI_Controller {
}
$config['upload_path'] = './uploads/';
$file = $config['upload_path'] . 'lotwreport_download.adi';
$file = $config['upload_path'] . 'lotwreport_download_'.$user->user_id.'_auto.adi';
if (file_exists($file) && ! is_writable($file)) {
$result = "Temporary download file ".$file." is not writable. Aborting!";
continue;
}
// Get credentials for LoTW
$data['user_lotw_name'] = urlencode($user->user_lotw_name);
$data['user_lotw_name'] = urlencode($user->user_lotw_name);
$data['user_lotw_password'] = urlencode($user->user_lotw_password);
$lotw_last_qsl_date = date('Y-m-d', strtotime($this->logbook_model->lotw_last_qsl_date($user->user_id)));
@@ -698,12 +703,16 @@ class Lotw extends CI_Controller {
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
$content = curl_exec($ch);
if(curl_errno($ch)){
if(curl_errno($ch)) {
$result = "LoTW download failed for user ".$data['user_lotw_name'].": ".curl_strerror(curl_errno($ch))." (".curl_errno($ch).").";
if (curl_errno($ch) == 28) { // break on timeout
$result .= "<br>Timeout reached. Stopping subsequent downloads.";
break;
}
continue;
} else if(str_contains($content,"Username/password incorrect</I>")) {
$result = "LoTW download failed for user ".$data['user_lotw_name'].": Username/password incorrect";
continue;
}
file_put_contents($file, $content);
if (file_get_contents($file, false, null, 0, 39) != "ARRL Logbook of the World Status Report") {
@@ -720,6 +729,89 @@ class Lotw extends CI_Controller {
}
}
public function check_lotw_credentials () {
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) {
$this->session->set_flashdata('error', __("You're not allowed to do that!"));
redirect('dashboard');
exit();
}
$ret=[];
$ret['status']='';
$raw = file_get_contents("php://input");
try {
$obj = json_decode($raw,true);
} catch (Exception $e) {
$ret['status']='failed_wrongcall';
log_message("Error",$ret['status']);
} finally {
$lotw_user=$obj['lotw_user'] ?? '';
$lotw_pass=$obj['lotw_pass'] ?? '';
}
$raw='';
$pw_placeholder = '**********';
if ($lotw_pass == $pw_placeholder) { // User comes with unaltered credentials - take them from database
$query = $this->user_model->get_by_id($this->session->userdata('user_id'));
$q = $query->row();
$data['user_lotw_name'] = urlencode($q->user_lotw_name ?? '');
$data['user_lotw_password'] = urlencode($q->user_lotw_password ?? '');
} else {
$data['user_lotw_name'] = urlencode($lotw_user ?? '');
$data['user_lotw_password'] = urlencode($lotw_pass ?? '');
}
if ((($data['user_lotw_name'] ?? '') != '') && (($data['user_lotw_password'] ?? '') != '') && ($ret['status'] != 'failed_wrongcall')) {
// Get URL for downloading LoTW
$query = $query = $this->db->query('SELECT lotw_login_url FROM config');
$q = $query->row();
$lotw_url = $q->lotw_login_url;
// Validate that LoTW credentials are not empty
// TODO: We don't actually see the error message
if ($data['user_lotw_name'] == '' || $data['user_lotw_password'] == '') {
$ret='No Creds set';
}
// Build URL for LoTW report file
$lotw_url .= "?";
$lotw_url .= "login=" . $data['user_lotw_name'];
$lotw_url .= "&password=" . $data['user_lotw_password'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $lotw_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
$content = curl_exec($ch);
if ($content) {
if(curl_errno($ch)) {
$ret['status']='failed';
$ret['details']== sprintf(__("LoTW login failed for user %s: %s."), $data['user_lotw_name'], curl_strerror(curl_errno($ch))." (".curl_errno($ch).")");
} else if (str_contains($content,"Username/password incorrect</I>")) {
$ret['status']='failed_wrong_creds';
$ret['details']= sprintf(__("LoTW login failed for user %s: %s."), $data['user_lotw_name'], __("Username/password incorrect"));
} else {
$ret['status']='OK';
$ret['details']= __("LoTW login OK!");
}
} else {
$ret['status']='failed_na';
$ret['details']= __("LoTW currently not available. Try again later.");
}
} else {
if (($ret['status'] ?? '') == '') {
$ret['status']='failed_nocred';
$ret['details']= __("No LoTW credentials provided.");
}
}
header("Content-type: application/json");
echo json_encode($ret);
return $ret;
}
public function import() { // Is only called via frontend. Cron uses "upload". within download the download is called
$this->load->model('user_model');
$this->load->model('Stations');
@@ -730,107 +822,100 @@ class Lotw extends CI_Controller {
}
$station_ids=$this->Stations->all_station_ids_of_user($this->session->userdata['user_id']);
if (!($this->config->item('disable_manual_lotw'))) {
$data['page_title'] = __("LoTW ADIF Import");
$data['page_title'] = __("LoTW ADIF Import");
$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'adi|ADI';
$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'adi|ADI';
$this->load->library('upload', $config);
$this->load->library('upload', $config);
$this->load->model('logbook_model');
$this->load->model('logbook_model');
if ($this->input->post('lotwimport') == 'fetch') {
$file = $config['upload_path'] . 'lotwreport_download.adi';
if (($this->input->post('lotwimport') == 'fetch') && (!($this->config->item('disable_manual_lotw')))) {
$file = $config['upload_path'] . 'lotwreport_download_'.$this->session->userdata('user_id').'.adi';
// Get credentials for LoTW
$query = $this->user_model->get_by_id($this->session->userdata('user_id'));
$q = $query->row();
$data['user_lotw_name'] = urlencode($q->user_lotw_name ?? '');
$data['user_lotw_password'] = urlencode($q->user_lotw_password ?? '');
// Get credentials for LoTW
$query = $this->user_model->get_by_id($this->session->userdata('user_id'));
$q = $query->row();
$data['user_lotw_name'] = urlencode($q->user_lotw_name ?? '');
$data['user_lotw_password'] = urlencode($q->user_lotw_password ?? '');
// Get URL for downloading LoTW
$query = $query = $this->db->query('SELECT lotw_download_url FROM config');
$q = $query->row();
$lotw_url = $q->lotw_download_url;
// Get URL for downloading LoTW
$query = $query = $this->db->query('SELECT lotw_download_url FROM config');
$q = $query->row();
$lotw_url = $q->lotw_download_url;
// Validate that LoTW credentials are not empty
// TODO: We don't actually see the error message
if ($data['user_lotw_name'] == '' || $data['user_lotw_password'] == '')
{
$this->session->set_flashdata('warning', __("You have not defined your ARRL LoTW credentials!")); redirect('lotw/import');
}
// Validate that LoTW credentials are not empty
// TODO: We don't actually see the error message
if ($data['user_lotw_name'] == '' || $data['user_lotw_password'] == '') {
$this->session->set_flashdata('warning', __("You have not defined your ARRL LoTW credentials!")); redirect('lotw/import');
}
$customDate = $this->input->post('from');
$customDate = $this->input->post('from');
if ($customDate != NULL) {
$lotw_last_qsl_date = date($customDate);
if ($customDate != NULL) {
$lotw_last_qsl_date = date($customDate);
} 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($this->session->userdata['user_id'])));
}
// Build URL for LoTW report file
$lotw_url .= "?";
$lotw_url .= "login=" . $data['user_lotw_name'];
$lotw_url .= "&password=" . $data['user_lotw_password'];
$lotw_url .= "&qso_query=1&qso_qsl='yes'&qso_qsldetail='yes'&qso_mydetail='yes'";
$lotw_url .= "&qso_qslsince=";
$lotw_url .= "$lotw_last_qsl_date";
if ($this->input->post('callsign') != '0') {
$lotw_url .= "&qso_owncall=".$this->input->post('callsign');
}
if (is_writable(dirname($file)) && (!file_exists($file) || is_writable($file))) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $lotw_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
$content = curl_exec($ch);
if(curl_errno($ch)) {
print "LoTW download failed for user ".$data['user_lotw_name'].": ".curl_strerror(curl_errno($ch))." (".curl_errno($ch).").";
} else if (str_contains($content,"Username/password incorrect</I>")) {
print "LoTW download failed for user ".$data['user_lotw_name'].": Username/password incorrect";
} 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($this->session->userdata['user_id'])));
}
// Build URL for LoTW report file
$lotw_url .= "?";
$lotw_url .= "login=" . $data['user_lotw_name'];
$lotw_url .= "&password=" . $data['user_lotw_password'];
$lotw_url .= "&qso_query=1&qso_qsl='yes'&qso_qsldetail='yes'&qso_mydetail='yes'";
$lotw_url .= "&qso_qslsince=";
$lotw_url .= "$lotw_last_qsl_date";
if ($this->input->post('callsign') != '0') {
$lotw_url .= "&qso_owncall=".$this->input->post('callsign');
}
if (is_writable(dirname($file)) && (!file_exists($file) || is_writable($file))) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $lotw_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
$content = curl_exec($ch);
if(!curl_errno($ch)){
file_put_contents($file, $content);
ini_set('memory_limit', '-1');
$this->loadFromFile($file, $station_ids);
} else {
print "LoTW download failed for user ".$data['user_lotw_name'].": ".curl_strerror(curl_errno($ch))." (".curl_errno($ch).").";
}
} else {
if (!is_writable(dirname($file))) {
$data['errormsg'] = 'Directory '.dirname($file).' is not writable!';
} else if (!is_writable($file)) {
$data['errormsg'] = 'File '.$file.' is not writable!';
}
$this->load->model('Stations');
$data['callsigns'] = $this->Stations->callsigns_of_user($this->session->userdata('user_id'));
$this->load->view('interface_assets/header', $data);
$this->load->view('lotw/import', $data);
$this->load->view('interface_assets/footer');
file_put_contents($file, $content);
ini_set('memory_limit', '-1');
$this->loadFromFile($file, $station_ids);
}
} else {
if ( ! $this->upload->do_upload())
{
$data['error'] = $this->upload->display_errors();
$this->load->model('Stations');
$data['callsigns'] = $this->Stations->callsigns_of_user($this->session->userdata('user_id'));
$this->load->view('interface_assets/header', $data);
$this->load->view('lotw/import', $data);
$this->load->view('interface_assets/footer');
} else {
$data = array('upload_data' => $this->upload->data());
$this->loadFromFile('./uploads/'.$data['upload_data']['file_name'], $station_ids);
if (!is_writable(dirname($file))) {
$data['errormsg'] = 'Directory '.dirname($file).' is not writable!';
} else if (!is_writable($file)) {
$data['errormsg'] = 'File '.$file.' is not writable!';
}
$this->load->model('Stations');
$data['callsigns'] = $this->Stations->callsigns_of_user($this->session->userdata('user_id'));
$this->load->view('interface_assets/header', $data);
$this->load->view('lotw/import', $data);
$this->load->view('interface_assets/footer');
}
} else {
$this->session->set_flashdata('error', __("You're not allowed to do that!"));
redirect('dashboard');
exit();
if (!$this->upload->do_upload()) {
$data['error'] = $this->upload->display_errors();
$this->load->model('Stations');
$data['callsigns'] = $this->Stations->callsigns_of_user($this->session->userdata('user_id'));
$this->load->view('interface_assets/header', $data);
$this->load->view('lotw/import', $data);
$this->load->view('interface_assets/footer');
} else {
$data = array('upload_data' => $this->upload->data());
$this->loadFromFile('./uploads/'.$data['upload_data']['file_name'], $station_ids);
}
}
} // end function
@@ -999,38 +1084,6 @@ class Lotw extends CI_Controller {
}
/*
| Function: lotw_satellite_map
| Requires: OSCAR Satellite name $satname
|
| Outputs if LoTW uses a different satellite name
|
*/
function lotw_satellite_map($satname) {
$arr = array(
"ARISS" => "ISS",
"UKUBE1" => "UKUBE-1",
"KEDR" => "ARISSAT-1",
"TO-108" => "CAS-6",
"TAURUS" => "TAURUS-1",
"AISAT1" => "AISAT-1",
'UVSQ' => "UVSQ-SAT",
'CAS-3H' => "LILACSAT-2",
'IO-117' => "GREENCUBE",
"TEVEL1" => "TEVEL-1",
"TEVEL2" => "TEVEL-2",
"TEVEL3" => "TEVEL-3",
"TEVEL4" => "TEVEL-4",
"TEVEL5" => "TEVEL-5",
"TEVEL6" => "TEVEL-6",
"TEVEL7" => "TEVEL-7",
"TEVEL8" => "TEVEL-8",
"INSPR7" => "INSPIRE-SAT 7",
);
return array_search(strtoupper($satname),$arr,true);
}
/*
| Function: lotw_ca_province_map
| Requires: candian province map $ca_province

View File

@@ -389,6 +389,100 @@ class Options extends CI_Controller {
redirect('/options/email');
}
// function used to display the /maptiles url in global options
function maptiles() {
$data['page_title'] = __("Wavelog Options");
$data['sub_heading'] = __("Maptiles Server");
$data['maptile_server_url'] = $this->optionslib->get_option('map_tile_server') ?? 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
$data['maptile_server_url_dark'] = $this->optionslib->get_option('map_tile_server_dark') ?? 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png';
$data['subdomain_system'] = $this->optionslib->get_option('map_tile_subdomains') ?? 'abc';
$map_tile_server_copyright = $this->optionslib->get_option('map_tile_server_copyright') ?? 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a>';
preg_match('/<a href="([^"]+)">([^<]+)<\/a>/', $map_tile_server_copyright, $matches);
$data['copyright_url'] = $matches[1] ?? 'https://www.openstreetmap.org/';
$data['copyright_text'] = $matches[2] ?? 'OpenStreetMap';
$this->load->view('interface_assets/header', $data);
$this->load->view('options/maptiles');
$this->load->view('interface_assets/footer');
}
// Handles saving the Maptiles options to the options system.
function maptiles_save() {
$data['page_title'] = __("Wavelog Options");
$data['sub_heading'] = __("Maptiles Server");
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('maptile_server_url', 'URL of Maptile Server', 'required');
$this->form_validation->set_rules('maptile_server_url_dark', 'URL of Dark Maptile Server', 'required');
$this->form_validation->set_rules('subdomain_system', 'Subdomains for Loadbalancing', 'required');
$this->form_validation->set_rules('copyright_url', 'URL for Copyright', 'required');
$this->form_validation->set_rules('copyright_text', 'Text for Copyright', 'required');
if ($this->form_validation->run() == FALSE) {
$this->maptiles();
} else {
$saved = false;
if ($this->input->post('reset_defaults') == '1') {
$map_tile_server_copyright = 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a>';
$saved = $this->optionslib->update('map_tile_server', 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 'yes');
$saved = $this->optionslib->update('map_tile_server_dark', 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', 'yes');
$saved = $this->optionslib->update('map_tile_subdomains', 'abc', 'yes');
} else {
$map_tile_server_copyright = 'Map data &copy; <a href="' . $this->input->post('copyright_url', true) . '">' . $this->input->post('copyright_text', true) . '</a>';
$saved = $this->optionslib->update('map_tile_server', $this->input->post('maptile_server_url', true), 'yes');
$saved = $this->optionslib->update('map_tile_server_dark', $this->input->post('maptile_server_url_dark', true), 'yes');
$saved = $this->optionslib->update('map_tile_subdomains', $this->input->post('subdomain_system', true), 'yes');
}
$saved = $this->optionslib->update('map_tile_server_copyright', $map_tile_server_copyright, 'yes');
// Also clean up static map images
if (!$this->load->is_loaded('staticmap_model')) {
$this->load->model('staticmap_model');
}
if (!$this->load->is_loaded('stations')) {
$this->load->model('stations');
}
$station_ids = explode(',',$this->stations->all_station_ids_of_user());
foreach ($station_ids as $station_id) {
$this->staticmap_model->remove_static_map_image($station_id);
log_message('debug', 'Removed static map image for station ID ' . $station_id);
}
// also remove the tilecache
$cachepath = $this->config->item('cache_path') == '' ? APPPATH . 'cache/' : $this->config->item('cache_path');
$cacheDir = $cachepath . "tilecache/";
$tilecache_warning = false;
if (function_usable('exec')) {
try {
if (is_dir($cacheDir)) {
exec('rm -rf ' . $cacheDir);
}
} catch (\Throwable $th) {
$tilecache_warning = true;
}
} else {
$tilecache_warning = true;
}
if ($tilecache_warning) {
$this->session->set_flashdata('warning', sprintf(__("Maptile cache could not be removed. Delete the folder manually. Path: %s"), str_replace(FCPATH, '', $cacheDir)));
log_message('debug', 'Maptile cache could not be removed. Delete the folder manually. Path: ' . str_replace(FCPATH, '', $cacheDir));
}
if($saved == true) {
$this->session->set_flashdata('success', __("Maptile Options saved!"));
} else {
$this->session->set_flashdata('error', __("Maptile Options could not be saved!"));
log_message('error', 'Maptile Options could not be saved!');
}
redirect('/options/maptiles');
}
}
// function used to display the /version_dialog url
function version_dialog() {

View File

@@ -132,6 +132,8 @@ class Oqrs extends CI_Controller {
public function requests() {
$data['page_title'] = __("OQRS Requests");
$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'); }
$this->load->model('logbooks_model');
$logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));

View File

@@ -152,6 +152,11 @@ class Qrz extends CI_Controller {
$this->markqso($qso->COL_PRIMARY_KEY,'I');
$result['status'] = 'Error';
$errormessages[] = $result['message'] . ' Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON;
} elseif ( ($result['status']=='error') && (str_contains($result['message'],'required field missing mode')) ) {
log_message('error', 'QRZ upload failed for qso for Station_ID '.$station_id.' // Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON . ' // Message: '.$result['message']);
$this->markqso($qso->COL_PRIMARY_KEY,'I');
$result['status'] = 'Error';
$errormessages[] = $result['message'] . ' Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON;
} elseif ( ($result['status']=='error') && (substr($result['message'],0,11) == 'STATUS=AUTH')) {
log_message('error', 'QRZ upload failed for qso for Station_ID '.$station_id.' // Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON . ' // Message: '.$result['message']);
$errormessages[] = $result['message'] . ' Call: ' . $qso->COL_CALL . ' Band: ' . $qso->COL_BAND . ' Mode: ' . $qso->COL_MODE . ' Time: ' . $qso->COL_TIME_ON;
@@ -191,6 +196,9 @@ class Qrz extends CI_Controller {
* Used for displaying the uid for manually selecting log for upload to qrz
*/
public function export() {
$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'); }
$this->load->model('stations');
$data['page_title'] = __("QRZ Logbook");
@@ -345,7 +353,7 @@ class Qrz extends CI_Controller {
function mass_download_qsos($qrz_api_key = '', $lastqrz = '1900-01-01', $station_ids = '', $trusted = false) {
$config['upload_path'] = './uploads/';
$file = $config['upload_path'] . 'qrzcom_download_report.adi';
$file = $config['upload_path'] . 'qrzcom_download_report_'.md5($qrz_api_key).'.adi';
if (file_exists($file) && ! is_writable($file)) {
$result = "Temporary download file ".$file." is not writable. Aborting!";
return false;
@@ -365,11 +373,11 @@ class Qrz extends CI_Controller {
curl_setopt( $ch, CURLOPT_USERAGENT, 'Wavelog/'.$this->optionslib->get_option('version'));
$content = htmlspecialchars_decode(curl_exec($ch));
file_put_contents($file, $content);
if (strlen(file_get_contents($file, false, null, 0, 100))!=100) {
if (strlen($content)<100) {
$result = "QRZ downloading failed, either due to it being down or incorrect logins.";
return "false";
}
file_put_contents($file, $content);
ini_set('memory_limit', '-1');
$result = $this->loadFromFile($file, $station_ids);

View File

@@ -19,25 +19,23 @@ class QSLPrint extends CI_Controller {
public function index($station_id = 'All')
{
$this->load->model('user_model');
// Check if users logged in
$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->validate_session() == 0) {
// user is not logged in
redirect('user/login');
}
$this->load->model('stations');
$data['station_id'] = $this->security->xss_clean($station_id);
$data['station_profile'] = $this->stations->all_of_user();
$this->load->model('qslprint_model');
if ( ($station_id != 'All') && ($this->stations->check_station_is_accessible($station_id)) ) {
$data['qsos'] = $this->qslprint_model->get_qsos_for_print($station_id);
$qsos = $this->qslprint_model->get_qsos_for_print($station_id);
} else {
$data['qsos'] = $this->qslprint_model->get_qsos_for_print();
$qsos = $this->qslprint_model->get_qsos_for_print();
}
$data['qsos'] = $qsos;
$footerData = [];
$footerData['scripts'] = [
'assets/js/sections/qslprint.js',
@@ -195,6 +193,16 @@ class QSLPrint extends CI_Controller {
$this->load->view('oqrs/showoqrs', $data);
}
public function get_previous_qsl() {
$id = $this->security->xss_clean($this->input->post('id'));
$this->load->model('qslprint_model');
$number_qsls = $this->qslprint_model->get_previous_qsls($id);
header('Content-Type: application/json');
echo json_encode($number_qsls);
}
}
/* End of file Qslprint.php */

View File

@@ -32,7 +32,7 @@ class QSO extends CI_Controller {
$data['notice'] = false;
$data['stations'] = $this->stations->all_of_user();
$data['radios'] = $this->cat->radios();
$data['radios'] = $this->cat->radios(true);
$data['radio_last_updated'] = $this->cat->last_updated()->row();
$data['query'] = $this->logbook_model->last_custom('5');
$data['dxcc'] = $this->logbook_model->fetchDxcc();
@@ -130,7 +130,7 @@ class QSO extends CI_Controller {
'prop_mode' => $this->input->post('prop_mode', TRUE),
'radio' => $this->input->post('radio', TRUE),
'station_profile_id' => $this->input->post('station_profile', TRUE),
'operator_callsign' => $this->input->post('operator_callsign', TRUE),
'operator_callsign' => $this->input->post('operator_callsign', TRUE) ?? $this->session->userdata('operator_callsign'),
'transmit_power' => $this->input->post('transmit_power', TRUE)
);
// ];
@@ -675,4 +675,20 @@ class QSO extends CI_Controller {
redirect('dashboard');
}
}
/**
* Easy modal Loader
* Used for Share Modal in QSO Details view
*/
function getShareModal() {
$data['qso'] = $this->input->post('qso_data', TRUE);
if (empty($data['qso'])) {
echo "No QSO data provided.";
return;
}
$this->load->view('qso/components/share_modal', $data, false);
}
}

View File

@@ -28,15 +28,9 @@ class Radio extends CI_Controller {
function status() {
// Check Auth
$this->load->model('user_model');
if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
// Check if users logged in
if ($this->user_model->validate_session() == 0) {
// user is not logged in
redirect('user/login');
}
session_write_close();
$this->load->model('cat');
@@ -45,10 +39,13 @@ class Radio extends CI_Controller {
if ($query->num_rows() > 0) {
echo "<thead><tr>";
echo "<th>" . __("Radio") . "</th>";
if ($this->session->userdata('clubstation') == 1 && clubaccess_check(9)) {
echo "<th>" . __("Operator") . "</th>";
}
echo "<th>" . __("Frequency") . "</th>";
echo "<th>" . __("Mode") . "</th>";
echo "<th>" . __("Timestamp") . "</th>";
echo "<th></th>";
echo "<th> </th>";
echo "<th>" . __("Options") . "</th>";
echo "<th>" . __("Settings") . "</th>";
echo "<th></th>";
@@ -57,6 +54,16 @@ class Radio extends CI_Controller {
echo "<tr>";
echo "<td>" . $row->radio . "</td>";
$this->load->model('user_model');
if ($this->session->userdata('clubstation') == 1 && clubaccess_check(9)) {
$operator = $this->user_model->get_by_id($row->operator)->row();
if ($operator) {
echo "<td>" . $operator->user_callsign . "</td>";
} else {
echo "<td>" . __("UNKNOWN") . "</td>";
}
}
if (empty($row->frequency) || $row->frequency == "0") {
echo "<td>- / -</td>";
} elseif (empty($row->frequency_rx) || $row->frequency_rx == "0") {
@@ -93,14 +100,16 @@ class Radio extends CI_Controller {
echo '<td></td>';
}
$defaul_user_radio = $this->user_options_model->get_options('cat', array('option_name' => 'default_radio'))->row()->option_value ?? NULL;
if (!$defaul_user_radio) {
echo '<td><button id="default_radio_btn_' . $row->id . '" class="btn btn-sm btn-outline-primary ld-ext-right" onclick="set_default_radio(' . $row->id . ')">' . __("Set as default radio") . '<div class="ld ld-ring ld-spin"></div></button</td>';
} else {
if ($defaul_user_radio !== $row->id) {
if ($this->session->userdata('clubstation') != 1) {
$defaul_user_radio = $this->user_options_model->get_options('cat', array('option_name' => 'default_radio'))->row()->option_value ?? NULL;
if (!$defaul_user_radio) {
echo '<td><button id="default_radio_btn_' . $row->id . '" class="btn btn-sm btn-outline-primary ld-ext-right" onclick="set_default_radio(' . $row->id . ')">' . __("Set as default radio") . '<div class="ld ld-ring ld-spin"></div></button</td>';
} else {
echo '<td><button id="default_radio_btn_' . $row->id . '" class="btn btn-sm btn-primary ld-ext-right" onclick="release_default_radio(' . $row->id . ')">' . __("Default (click to release)") . '<div class="ld ld-ring ld-spin"></div></button</td>';
if ($defaul_user_radio !== $row->id) {
echo '<td><button id="default_radio_btn_' . $row->id . '" class="btn btn-sm btn-outline-primary ld-ext-right" onclick="set_default_radio(' . $row->id . ')">' . __("Set as default radio") . '<div class="ld ld-ring ld-spin"></div></button</td>';
} else {
echo '<td><button id="default_radio_btn_' . $row->id . '" class="btn btn-sm btn-primary ld-ext-right" onclick="release_default_radio(' . $row->id . ')">' . __("Default (click to release)") . '<div class="ld ld-ring ld-spin"></div></button</td>';
}
}
}
echo "<td><button id='edit_cat_settings_".$row->id."' \" class=\"editCatSettings btn btn-sm btn-primary\"> " . __("Edit") . "</button></td>";
@@ -238,7 +247,7 @@ class Radio extends CI_Controller {
if (isset($cat_url) && ($cat_url != null)) {
$a_ret['cat_url'] = $cat_url;
}
$a_ret['update_minutes_ago'] = $updated_at;
$a_ret['updated_minutes_ago'] = $updated_at;
echo json_encode($a_ret, JSON_PRETTY_PRINT);
}
}

View File

@@ -14,10 +14,7 @@ class Reg1test extends CI_Controller {
// do authorization check
$this->load->model('user_model');
if (!$this->user_model->authorize(2)) {
$this->session->set_flashdata('error', __("You're not allowed to do that!"));
redirect('dashboard');
}
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
}
public function index() {

View File

@@ -21,6 +21,16 @@ class Satellite extends CI_Controller {
$pageData['satellites'] = $this->satellite_model->get_all_satellites();
if($this->session->userdata('user_date_format')) {
// If Logged in and session exists
$custom_date_format = $this->session->userdata('user_date_format');
} else {
// Get Default date format from /config/wavelog.php
$custom_date_format = $this->config->item('qso_date_format');
}
$pageData['custom_date_format'] = $custom_date_format;
$footerData = [];
$footerData['scripts'] = [
'assets/js/sections/satellite.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/satellite.js")),
@@ -75,12 +85,17 @@ class Satellite extends CI_Controller {
$id = $this->security->xss_clean($this->input->post('id', true));
$satellite['name'] = $this->security->xss_clean($this->input->post('name'));
$satellite['exportname'] = $this->security->xss_clean($this->input->post('exportname'));
$satellite['displayname'] = $this->security->xss_clean($this->input->post('displayname'));
$satellite['orbit'] = $this->security->xss_clean($this->input->post('orbit'));
if ($this->security->xss_clean($this->input->post('lotw')) == 'Y') {
$satellite['lotw'] = 'Y';
} else {;
$satellite['lotw'] = 'N';
}
$this->satellite_model->saveupdatedsatellite($id, $satellite);
$this->satellite_model->saveupdatedsatellite($id, $satellite);
echo json_encode(array('message' => 'OK'));
return;
return;
}
public function delete() {
@@ -219,12 +234,32 @@ class Satellite extends CI_Controller {
$this->load->view('interface_assets/footer', $footerData);
}
public function searchpasses() {
public function searchPasses() {
if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
try {
$result = $this->get_tle_for_predict();
$this->calcpass($result);
$tle = $this->get_tle_for_predict();
$yourgrid = $this->security->xss_clean($this->input->post('yourgrid'));
$altitude = $this->security->xss_clean($this->input->post('altitude'));
$date = $this->security->xss_clean($this->input->post('date'));
$minelevation = $this->security->xss_clean($this->input->post('minelevation'));
$timezone = $this->security->xss_clean($this->input->post('timezone'));
$data = $this->calcPass($tle, $yourgrid, $altitude, $date, $minelevation, $timezone);
$this->load->view('satellite/passtable', $data);
}
catch (Exception $e) {
header("Content-type: application/json");
echo json_encode(['ok' => 'Error', 'message' => $e->getMessage() . $e->getCode()]);
}
}
public function searchSkedPasses() {
if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
try {
$tle = $this->get_tle_for_predict();
$this->calcSkedPass($tle);
}
catch (Exception $e) {
header("Content-type: application/json");
@@ -240,7 +275,7 @@ class Satellite extends CI_Controller {
return $this->satellite_model->get_tle($sat);
}
function calcpass($sat_tle) {
function calcPass($sat_tle, $yourgrid, $altitude, $date, $minelevation, $timezone) {
if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
require_once "./src/predict/Predict.php";
@@ -252,9 +287,9 @@ class Satellite extends CI_Controller {
// The observer or groundstation is called QTH in ham radio terms
$predict = new Predict();
$qth = new Predict_QTH();
$qth->alt = $this->security->xss_clean($this->input->post('altitude')); // Altitude in meters
$qth->alt = $altitude; // Altitude in meters
$strQRA = $this->security->xss_clean($this->input->post('yourgrid'));
$strQRA = $yourgrid;
if ((strlen($strQRA) % 2 == 0) && (strlen($strQRA) <= 10)) { // Check if QRA is EVEN (the % 2 does that) and smaller/equal 8
$strQRA = strtoupper($strQRA);
@@ -270,7 +305,7 @@ class Satellite extends CI_Controller {
if(!$this->load->is_loaded('Qra')) {
$this->load->library('Qra');
}
$homecoordinates = $this->qra->qra2latlong($this->security->xss_clean($this->input->post('yourgrid')));
$homecoordinates = $this->qra->qra2latlong($yourgrid);
$qth->lat = $homecoordinates[0];
$qth->lon = $homecoordinates[1];
@@ -280,11 +315,11 @@ class Satellite extends CI_Controller {
$tle = new Predict_TLE($sat_tle->satellite, $temp[0], $temp[1]); // Instantiate it
$sat = new Predict_Sat($tle); // Load up the satellite data
$now = Predict_Time::get_current_daynum(); // get the current time as Julian Date (daynum)
$now = $this->get_daynum_from_date($date); // get the current time as Julian Date (daynum)
// You can modify some preferences in Predict(), the defaults are below
//
$predict->minEle = intval($this->security->xss_clean($this->input->post('minelevation'))); // Minimum elevation for a pass
$predict->minEle = intval($minelevation); // Minimum elevation for a pass
$predict->timeRes = 1; // Pass details: time resolution in seconds
$predict->numEntries = 20; // Pass details: number of entries per pass
// $predict->threshold = -6; // Twilight threshold (sun must be at this lat or lower)
@@ -293,8 +328,6 @@ class Satellite extends CI_Controller {
$results = $predict->get_passes($sat, $qth, $now, 1);
$filtered = $predict->filterVisiblePasses($results);
$zone = $this->security->xss_clean($this->input->post('timezone'));
// Get Date format
if ($this->session->userdata('user_date_format')) {
// If Logged in and session exists
@@ -304,11 +337,87 @@ class Satellite extends CI_Controller {
$custom_date_format = $this->config->item('qso_date_format');
}
$format = $custom_date_format . ' H:i:s';
$data['format'] = $custom_date_format . ' H:i:s';
$data['filtered'] = $filtered;
$data['zone'] = $zone;
$data['format'] = $format;
$this->load->view('satellite/passtable', $data);
$data['zone'] = $timezone;
return $data;
}
function calcSkedPass($tle) {
if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$yourgrid = $this->security->xss_clean($this->input->post('yourgrid'));
$altitude = $this->security->xss_clean($this->input->post('altitude'));
$date = $this->security->xss_clean($this->input->post('date'));
$minelevation = $this->security->xss_clean($this->input->post('minelevation'));
$timezone = $this->security->xss_clean($this->input->post('timezone'));
$homePass = $this->calcPass($tle, $yourgrid, $altitude, $date, $minelevation, $timezone);
$skedgrid = $this->security->xss_clean($this->input->post('skedgrid'));
$minskedelevation = $this->security->xss_clean($this->input->post('minskedelevation'));
$skedPass = $this->calcPass($tle, $skedgrid, 0, $date, $minskedelevation, $timezone);
// Get Date format
if ($this->session->userdata('user_date_format')) {
// If Logged in and session exists
$custom_date_format = $this->session->userdata('user_date_format');
} else {
// Get Default date format from /config/wavelog.php
$custom_date_format = $this->config->item('qso_date_format');
}
$data['format'] = $custom_date_format . ' H:i:s';
$data['overlaps'] = $this->findOverlaps($homePass, $skedPass);
$data['zone'] = $timezone;
$data['yourgrid'] = $yourgrid;
$data['skedgrid'] = $skedgrid;
$data['date'] = $date;
$data['custom_date_format'] = $custom_date_format;
$this->load->view('satellite/skedtable', $data);
}
function findOverlaps($homePass, $skedPass) {
$overlaps = []; // Store overlapping passes
foreach ($homePass['filtered'] as $pass1) {
foreach ($skedPass['filtered'] as $pass2) {
if ($this->checkOverlap($pass1, $pass2)) {
$overlaps[] = [
'grid1' => $pass1,
'grid2' => $pass2
];
}
}
}
return $overlaps;
}
function checkOverlap($pass1, $pass2) {
// Calculate the overlap condition
$start = max($pass1->visible_aos, $pass2->visible_aos); // Latest start time
$end = min($pass1->visible_los, $pass2->visible_los); // Earliest end time
return $start <= $end; // True if intervals overlap
}
public static function get_daynum_from_date($date) {
// Convert a Y-m-d date to a day number
// Convert date to Unix timestamp
$timestamp = strtotime($date);
if ($timestamp === false) {
throw new Exception("Invalid date format. Expected Y-m-d.");
}
// Calculate the day number
return Predict_Time::unix2daynum($timestamp, 0);
}
}

View File

@@ -98,7 +98,8 @@ class Search extends CI_Controller {
}
function search_result() {
$data['results'] = $this->fetchQueryResult(($this->input->post('search', TRUE) ?? ''), FALSE);
$sstring = str_replace('Ø', "0", $this->input->post("method", TRUE) ?? '');
$data['results'] = $this->fetchQueryResult($sstring, FALSE);
$this->load->view('search/search_result_ajax', $data);
}

View File

@@ -82,22 +82,18 @@ class SimpleFLE extends CI_Controller {
$this->load->model('logbook_model');
$qsos = json_decode($qsos, true);
$result = [];
foreach ($qsos as $qso) {
$one_result = $this->logbook_model->import($qso, $qso['station_id']);
$station_id = $qsos[0]['station_id']; // we can trust this value
// if the returner is not empty we have an error and should log it
if ($result != '' && strpos(json_encode($one_result), 'Duplicate for') == false) {
log_message('error', 'SimpleFLE, save_qsos(); For QSO: ' . $qso['call'] . ' on ' . $qso['qso_date'] . ' Error: ' . json_encode($result));
}
if (strpos(json_encode($one_result), 'Duplicate for') !== false) {
log_message('debug', 'SimpleFLE, save_qsos(); For QSO: ' . $qso['call'] . ' on ' . $qso['qso_date'] . ' Warning: ' . json_encode($result));
}
$bulk_result = $this->logbook_model->import_bulk($qsos, $station_id);
if ($one_result != '') {
$result[] = $one_result;
}
$clean_result = str_replace(['<br><br/>'], "\n", $bulk_result);
log_message('debug', "SimpleFLE, save_qsos(); Bulk Result: \n" . $clean_result);
// Also clean up static map images
if (!$this->load->is_loaded('staticmap_model')) {
$this->load->model('staticmap_model');
}
$this->staticmap_model->remove_static_map_image($station_id);
if (empty($result)) {
echo "success";

View File

@@ -80,6 +80,12 @@ class Staticmap extends CI_Controller {
$ituzones = $r == 'true' ? true : false;
}
// Watermark
$watermark = $this->input->get('wm', TRUE) ?? '';
if ($watermark == '' || ($watermark != 1 && $watermark != 0)) {
$watermark = true;
}
// handling the theme mode
$this->load->model('themes_model');
if ($thememode == null || $thememode == '' || ($thememode != 'dark' && $thememode != 'light')) {
@@ -97,8 +103,24 @@ class Staticmap extends CI_Controller {
// we need the realpath later for validation
$cacheDir = realpath($cachepath . "staticmap_images/");
// create a unique filename for the cache
$filenameRaw = $uid . $logbook_id . $qsocount . $band . $thememode . $continent . $hide_home . ($night_shadow == false ? 0 : 1) . ($pathlines == false ? 0 : 1) . ($cqzones == false ? 0 : 1) . ($ituzones == false ? 0 : 1) . $orbit . $contest . $start_date . $end_date;
// create a unique filename for the cacheund e
$filenameRaw = $uid
. $logbook_id
. $qsocount
. $band
. $thememode
. $continent
. $hide_home
. ($night_shadow == false ? 0 : 1)
. ($pathlines == false ? 0 : 1)
. ($cqzones == false ? 0 : 1)
. ($ituzones == false ? 0 : 1)
. $orbit
. $contest
. $start_date
. $end_date
. $watermark;
$filename = crc32('staticmap_' . $slug) . '_' . substr(md5($filenameRaw), 0, 12) . '.png';
$filepath = $cacheDir . '/' . $filename;
@@ -163,7 +185,7 @@ class Staticmap extends CI_Controller {
$end_date == 'noEnd' ? '' : $end_date
);
$image = $this->staticmap_model->render_static_map($qsos, $uid, $centerMap, $coordinates, $filepath, $continent, $thememode, $hide_home, $night_shadow, $pathlines, $cqzones, $ituzones);
$image = $this->staticmap_model->render_static_map($qsos, $uid, $centerMap, $coordinates, $filepath, $continent, $thememode, $hide_home, $night_shadow, $pathlines, $cqzones, $ituzones, $watermark);
header('Content-Type: image/png');

View File

@@ -60,7 +60,7 @@ class Station extends CI_Controller
if ($this->stations->edit()) {
$data['notice'] = __("Station Location") . $this->security->xss_clean($this->input->post('station_profile_name', true)) . " Updated";
}
// Also clean up static map images first
// Also clean up static map images
if (!$this->load->is_loaded('staticmap_model')) {
$this->load->model('staticmap_model');
}

View File

@@ -12,7 +12,7 @@ class Stationsetup extends CI_Controller {
$this->load->helper(array('form', 'url'));
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
if(!$this->user_model->authorize(2) || !clubaccess_check(9)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
}
public function index() {

View File

@@ -8,24 +8,24 @@ class Statistics extends CI_Controller {
}
public function index()
{
$this->load->model('user_model');
$this->load->model('bands');
public function index() {
$this->load->model('user_model');
$this->load->model('bands');
if(!$this->user_model->authorize($this->config->item('auth_mode'))) {
if($this->user_model->validate_session()) {
$this->user_model->clear_session();
show_error('Access denied<p>Click <a href="'.site_url('user/login').'">here</a> to log in as another user', 403);
} else {
redirect('user/login');
}
}
if(!$this->user_model->authorize($this->config->item('auth_mode'))) {
if($this->user_model->validate_session()) {
$this->user_model->clear_session();
show_error('Access denied<p>Click <a href="'.site_url('user/login').'">here</a> to log in as another user', 403);
} else {
redirect('user/login');
}
}
// Render User Interface
// Set Page Title
$data['page_title'] = __("Statistics");
$data['sat_active'] = array_search("SAT", $this->bands->get_user_bands(), true);
$data['years'] = $this->get_years();
// Load Views
$this->load->view('interface_assets/header', $data);
@@ -77,6 +77,18 @@ class Statistics extends CI_Controller {
}
function get_years() {
$this->load->model('logbook_model');
$totals_year = $this->logbook_model->totals_year();
$years=[];
if ($totals_year) {
foreach($totals_year->result() as $years_obj) {
$years[] = $years_obj->year;
}
}
return $years;
}
public function get_year() {
$this->load->model('logbook_model');
@@ -99,18 +111,21 @@ class Statistics extends CI_Controller {
public function get_mode() {
$this->load->model('logbook_model');
$yr = xss_clean($this->input->post('yr')) ?? 'All';
$modestats = array();
$i = 0;
$modestats[$i]['mode'] = 'ssb';
$modestats[$i++]['total'] = $this->logbook_model->total_ssb();
$modestats[$i++]['total'] = $this->logbook_model->total_ssb($yr);
$modestats[$i]['mode'] = 'cw';
$modestats[$i++]['total'] = $this->logbook_model->total_cw();
$modestats[$i++]['total'] = $this->logbook_model->total_cw($yr);
$modestats[$i]['mode'] = 'fm';
$modestats[$i++]['total'] = $this->logbook_model->total_fm();
$modestats[$i++]['total'] = $this->logbook_model->total_fm($yr);
$modestats[$i]['mode'] = 'am';
$modestats[$i++]['total'] = $this->logbook_model->total_am($yr);
$modestats[$i]['mode'] = 'digi';
$modestats[$i]['total'] = $this->logbook_model->total_digi();
$modestats[$i]['total'] = $this->logbook_model->total_digi($yr);
usort($modestats, fn($a, $b) => $b['total'] <=> $a['total']);
header('Content-Type: application/json');
@@ -123,7 +138,8 @@ class Statistics extends CI_Controller {
$bandstats = array();
$total_bands = $this->logbook_model->total_bands();
$yr = xss_clean($this->input->post('yr')) ?? 'All';
$total_bands = $this->logbook_model->total_bands($yr);
$i = 0;
@@ -143,7 +159,8 @@ class Statistics extends CI_Controller {
$satstats = array();
$total_sat = $this->logbook_model->total_sat();
$yr = xss_clean($this->input->post('yr')) ?? 'All';
$total_sat = $this->logbook_model->total_sat($yr);
$i = 0;
if ($total_sat) {
@@ -162,13 +179,14 @@ class Statistics extends CI_Controller {
$total_qsos = array();
$result = $this->stats->unique_sat_callsigns();
$yr = xss_clean($this->input->post('yr')) ?? 'All';
$result = $this->stats->unique_sat_callsigns($yr);
$total_qsos['qsoarray'] = $result['qsoView'];
$total_qsos['satunique'] = $result['satunique'];
$total_qsos['modeunique'] = $result['modeunique'];
$total_qsos['total'] = $result['total'];
$total_qsos['sats'] = $this->stats->get_sats();
$total_qsos['modes'] = $this->stats->get_sat_modes();
$total_qsos['sats'] = $this->stats->get_sats($yr);
$total_qsos['modes'] = $this->stats->get_sat_modes($yr);
$this->load->view('statistics/satuniquetable', $total_qsos);
}
@@ -178,12 +196,13 @@ class Statistics extends CI_Controller {
$total_qsos = array();
$result = $this->stats->unique_callsigns();
$yr = xss_clean($this->input->post('yr')) ?? 'All';
$result = $this->stats->unique_callsigns($yr);
$total_qsos['qsoarray'] = $result['qsoView'];
$total_qsos['bandunique'] = $result['bandunique'];
$total_qsos['modeunique'] = $result['modeunique'];
$total_qsos['total'] = $result['total'];
$total_qsos['bands'] = $this->stats->get_bands();
$total_qsos['bands'] = $this->stats->get_bands($yr);
$this->load->view('statistics/uniquetable', $total_qsos);
}
@@ -193,12 +212,13 @@ class Statistics extends CI_Controller {
$total_qsos = array();
$result = $this->stats->total_sat_qsos();
$yr = xss_clean($this->input->post('yr')) ?? 'All';
$result = $this->stats->total_sat_qsos($yr);
$total_qsos['qsoarray'] = $result['qsoView'];
$total_qsos['sattotal'] = $result['sattotal'];
$total_qsos['modetotal'] = $result['modetotal'];
$total_qsos['modes'] = $result['modes'];
$total_qsos['sats'] = $this->stats->get_sats();
$total_qsos['sats'] = $this->stats->get_sats($yr);
$this->load->view('statistics/satqsotable', $total_qsos);
}
@@ -208,11 +228,12 @@ class Statistics extends CI_Controller {
$total_qsos = array();
$result = $this->stats->total_qsos();
$yr = xss_clean($this->input->post('yr')) ?? 'All';
$result = $this->stats->total_qsos($yr);
$total_qsos['qsoarray'] = $result['qsoView'];
$total_qsos['bandtotal'] = $result['bandtotal'];
$total_qsos['modetotal'] = $result['modetotal'];
$total_qsos['bands'] = $this->stats->get_bands();
$total_qsos['bands'] = $this->stats->get_bands($yr);
$this->load->view('statistics/qsotable', $total_qsos);
}
@@ -236,4 +257,55 @@ class Statistics extends CI_Controller {
$this->load->view('statistics/qsltable', $total_qsos);
$this->load->view('interface_assets/footer');
}
public function antennaanalytics() {
$this->load->model('stats');
$this->load->model('logbookadvanced_model');
$this->load->model('bands');
$data = array();
$headerData['page_title'] = __("Antenna Analytics");
$data['satellites'] = $this->stats->get_sats();
$data['bands'] = $this->bands->get_worked_bands();
$data['modes'] = $this->logbookadvanced_model->get_modes();
$data['sats'] = $this->bands->get_worked_sats();
$data['orbits'] = $this->bands->get_worked_orbits();
$footerData = [];
$footerData['scripts'] = [
'assets/js/chart.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/chart.js")),
'assets/js/sections/antennastats.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/antennestats.js")),
];
// Load Views
$this->load->view('interface_assets/header', $headerData);
$this->load->view('statistics/antennaanalytics', $data);
$this->load->view('interface_assets/footer', $footerData);
}
public function get_azimuth_data() {
$band = xss_clean($this->input->post('band'));
$mode = xss_clean($this->input->post('mode'));
$sat = xss_clean($this->input->post('sat'));
$orbit = xss_clean($this->input->post('orbit'));
$this->load->model('stats');
$azimutharray = $this->stats->azimuthdata($band, $mode, $sat, $orbit);
header('Content-Type: application/json');
echo json_encode($azimutharray);
}
public function get_elevation_data() {
$sat = xss_clean($this->input->post('sat'));
$orbit = xss_clean($this->input->post('orbit'));
$this->load->model('stats');
$elevationarray = $this->stats->elevationdata($sat, $orbit);
header('Content-Type: application/json');
echo json_encode($elevationarray);
}
}

View File

@@ -44,6 +44,12 @@ class Timeline extends CI_Controller {
$award = 'dxcc';
}
if ($this->input->post('year') != NULL) {
$year = $this->security->xss_clean($this->input->post('year'));
} else {
$year = 'All';
}
if ($this->input->post('qsl') != NULL) {
$qsl = $this->security->xss_clean($this->input->post('qsl'));
} else {
@@ -68,17 +74,32 @@ class Timeline extends CI_Controller {
$eqsl = '0';
}
if ($this->input->post('qrz') != NULL) {
$qrz = $this->security->xss_clean($this->input->post('qrz'));
} else {
$qrz = '0';
}
if ($this->input->post('onlynew') != NULL) {
$onlynew = $this->security->xss_clean($this->input->post('onlynew'));
} else {
$onlynew = '0';
}
$this->load->model('modes');
$this->load->model('bands');
$data['modes'] = $this->modes->active();
$data['timeline_array'] = $this->Timeline_model->get_timeline($band, $mode, $propmode, $award, $qsl, $lotw, $eqsl, $clublog);
$data['timeline_array'] = $this->Timeline_model->get_timeline($band, $mode, $propmode, $award, $qsl, $lotw, $eqsl, $clublog, $year, $qrz, $onlynew);
$data['worked_bands'] = $this->bands->get_worked_bands();
$data['bandselect'] = $band;
$data['modeselect'] = $mode;
$data['propmode'] = $propmode;
$data['user_default_band'] = $this->session->userdata('user_default_band');
$data['years'] = $this->Timeline_model->get_years();
$data['onlynew'] = $onlynew;
$data['selectedyear'] = $year;
$footerData['scripts'] = [ 'assets/js/sections/timeline.js?' ];
$this->load->view('interface_assets/header', $data);

View File

@@ -211,7 +211,7 @@ class Update extends CI_Controller {
$gz = gzopen($url, 'r');
if ($gz === FALSE) {
$this->update_status("FAILED: Could not download from clublog.org");
log_message('error', 'FAILED: Could not download exceptions from clublog.org');
log_message('error', 'FAILED: Could not download data from clublog.org');
exit();
}
@@ -223,6 +223,7 @@ class Update extends CI_Controller {
if (file_put_contents($this->paths->make_update_path("cty.xml"), $data) === FALSE) {
$this->update_status("FAILED: Could not write to cty.xml file");
log_message('error', 'DXCC UPDATE FAILED: Could not write to cty.xml file');
exit();
}
@@ -388,66 +389,26 @@ class Update extends CI_Controller {
}
public function update_tle() {
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;
public function update_tle() {
$this->load->model('Update_model');
$result = $this->Update_model->tle();
echo $result;
}
$url = 'https://www.amsat.org/tle/dailytle.txt';
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($curl);
$count = 0;
if ($response === false) {
echo 'Error: ' . curl_error($curl);
} else {
$this->db->empty_table("tle");
// Split the response into an array of lines
$lines = explode("\n", $response);
$satname = '';
$tleline1 = '';
$tleline2 = '';
// Process each line
for ($i = 0; $i < count($lines); $i += 3) {
$count++;
// Check if there are at least three lines remaining
if (isset($lines[$i], $lines[$i + 1], $lines[$i + 2])) {
// Get the three lines
$satname = $lines[$i];
$tleline1 = $lines[$i + 1];
$tleline2 = $lines[$i + 2];
$sql = "INSERT INTO tle (satelliteid, tle) select id, ? from satellite where name = ? or exportname = ?";
$this->db->query($sql,array($tleline1."\n".$tleline2,$satname,$satname));
}
}
}
curl_close($curl);
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = ($endtime - $starttime);
echo "This page was created in ".$totaltime." seconds <br />";
echo "Records inserted: " . $count . " <br/>";
$datetime = new DateTime("now", new DateTimeZone('UTC'));
$datetime = $datetime->format('Ymd h:i');
$this->optionslib->update('tle_update', $datetime , 'no');
}
public function update_lotw_sats() {
$this->load->model('Update_model');
$bodyData['satupdates'] = $this->Update_model->lotw_sats();
$data['page_title'] = __("LoTW SAT Update");
$this->load->view('interface_assets/header', $data);
$this->load->view('lotw/satupdate', $bodyData);
$this->load->view('interface_assets/footer');
}
function version_check() {
// set the last run in cron table for the correct cron id
$this->load->model('cron_model');
$this->cron_model->set_last_run($this->router->class . '_' . $this->router->method);
$this->load->model('Update_model');
$this->Update_model->update_check();
}

View File

@@ -5,6 +5,7 @@ class User extends CI_Controller {
public function index()
{
$this->load->model('user_model');
$this->load->library('form_validation');
if (!$this->load->is_loaded('encryption')) {
$this->load->library('encryption');
@@ -13,6 +14,8 @@ class User extends CI_Controller {
if(!$this->user_model->authorize(99)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$data['results'] = $this->user_model->users();
$data['clubs'] = $this->user_model->users('is_club');
$data['clubmode'] = $this->config->item('special_callsign');
$data['session_uid'] = $this->session->userdata('user_id');
// Check if impersonating is disabled in the config
@@ -33,11 +36,77 @@ class User extends CI_Controller {
$data['has_flossie'] = ($this->config->item('encryption_key') == 'flossie1234555541') ? true : false;
$footerData = [];
$footerData['scripts'] = [
'assets/js/sections/user.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/user.js")),
];
$data['page_title'] = __("User Accounts");
$this->load->view('interface_assets/header', $data);
$this->load->view('user/index');
$this->load->view('interface_assets/footer');
$this->load->view('interface_assets/footer', $footerData);
}
public function actions_modal() {
$this->load->model('user_model');
$this->load->library('encryption');
if(!$this->user_model->authorize(99)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$data['user_id'] = $this->input->post('user_id', true) ?? '';
$modal = $this->input->post('modal', true) ?? '';
if($this->session->userdata('user_date_format')) {
$custom_date_format = $this->session->userdata('user_date_format');
} else {
$custom_date_format = $this->config->item('qso_date_format');
}
if ($this->user_model->exists_by_id($data['user_id']) && $modal != '') {
$user = $this->user_model->get_by_id($data['user_id'])->row();
$gettext = new Gettext;
$data['user_name'] = $user->user_name;
$data['user_callsign'] = $user->user_callsign;
$data['user_email'] = $user->user_email;
$data['user_firstname'] = $user->user_firstname;
$data['user_lastname'] = $user->user_lastname;
$data['user_language'] = $gettext->find_by('folder', $user->user_language)['name_en'];
$data['is_clubstation'] = $user->clubstation == 1 ? true : false;
$data['last_seen'] = $user->last_seen;
$data['custom_date_format'] = $custom_date_format;
$data['has_flossie'] = ($this->config->item('encryption_key') == 'flossie1234555541') ? true : false;
$this->load->view('user/modals/'.$modal.'_modal', $data);
} else {
$this->session->set_flashdata('error', __("Invalid User ID or missing modal!"));
redirect('user');
}
}
public function convert() {
$this->load->model('user_model');
if(!$this->user_model->authorize(99)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$user_id = $this->input->post('user_id', true) ?? '';
$convert_to = $this->input->post('convert_to', true) ?? '';
if ($convert_to != '0' && $convert_to != '1') {
$this->session->set_flashdata('error', __("Invalid Parameter!"));
redirect('dashboard');
}
if ($this->user_model->exists_by_id($user_id)) {
if ($this->user_model->convert($user_id, $convert_to)) {
echo json_encode(true);
} else {
echo json_encode(false);
}
} else {
log_message('error', 'User Conversion - User ID not found: '.$user_id);
echo json_encode(false);
}
}
function add() {
@@ -54,8 +123,8 @@ class User extends CI_Controller {
$this->form_validation->set_rules('user_email', 'E-mail', 'required');
$this->form_validation->set_rules('user_password', 'Password', 'required');
$this->form_validation->set_rules('user_type', 'Type', 'required');
$this->form_validation->set_rules('user_firstname', 'First name', 'required');
$this->form_validation->set_rules('user_lastname', 'Last name', 'required');
// $this->form_validation->set_rules('user_firstname', 'First name', 'required');
// $this->form_validation->set_rules('user_lastname', 'Last name', 'required');
$this->form_validation->set_rules('user_callsign', 'Callsign', 'required');
$this->form_validation->set_rules('user_locator', 'Locator', 'required');
$this->form_validation->set_rules('user_locator', 'Locator', 'callback_check_locator');
@@ -65,9 +134,16 @@ class User extends CI_Controller {
$data['user_form_action'] = site_url('user/add');
$data['bands'] = $this->bands->get_user_bands();
$data['clubstation'] = ($this->input->get('club') ?? '') == '1' ? true : false;
// Get themes list
$data['themes'] = $this->user_model->getThemes();
$footerData = [];
$footerData['scripts'] = [
'assets/js/sections/user.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/user.js")),
];
// Get timezones
$data['timezones'] = $this->user_model->timezones();
$data['user_language'] = 'english';
@@ -81,9 +157,9 @@ class User extends CI_Controller {
$data['user_name'] = $this->input->post('user_name');
$data['user_email'] = $this->input->post('user_email');
$data['user_password'] = $this->input->post('user_password');
$data['user_type'] = $this->input->post('user_type');
$data['user_firstname'] = $this->input->post('user_firstname');
$data['user_lastname'] = $this->input->post('user_lastname');
$data['user_type'] = $data['clubstation'] == true ? '3' : $this->input->post('user_type');
$data['user_firstname'] = $this->input->post('user_firstname') ?? '';
$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_timezone'] = $this->input->post('user_timezone');
@@ -121,14 +197,14 @@ class User extends CI_Controller {
} else {
$this->load->view('user/edit', $data);
}
$this->load->view('interface_assets/footer');
$this->load->view('interface_assets/footer', $footerData);
} else {
switch($this->user_model->add($this->input->post('user_name'),
$this->input->post('user_password'),
$this->input->post('user_email'),
$this->input->post('user_type'),
$this->input->post('user_firstname'),
$this->input->post('user_lastname'),
$this->input->post('user_firstname') ?? '',
$this->input->post('user_lastname') ?? '',
$this->input->post('user_callsign'),
$this->input->post('user_locator'),
$this->input->post('user_timezone'),
@@ -169,21 +245,22 @@ class User extends CI_Controller {
$this->input->post('user_eqsl_password'),
$this->input->post('user_clublog_name'),
$this->input->post('user_clublog_password'),
$this->input->post('user_winkey')
$this->input->post('user_winkey'),
$this->input->post('clubstation') == '1' ? true : false
)) {
// Check for errors
case EUSERNAMEEXISTS:
$data['username_error'] = 'Username <b>'.$this->input->post('user_name').'</b> already in use!';
$data['username_error'] = sprintf(__("Username %s already in use!"), '<b>' . $this->input->post('user_name') . '</b>');
break;
case EEMAILEXISTS:
$data['email_error'] = 'E-mail address <b>'.$this->input->post('user_email').'</b> already in use!';
$data['email_error'] = sprintf(__("E-mail %s already in use!"), '<b>' . $this->input->post('user_email') . '</b>');
break;
case EPASSWORDINVALID:
$data['password_error'] = 'Invalid password!';
$data['password_error'] = __("Invalid Password!");
break;
// All okay, return to user screen
case OK:
$this->session->set_flashdata('notice', 'User '.$this->input->post('user_name').' added');
$this->session->set_flashdata('notice', sprintf(__("User %s added!"), '<b>' . $this->input->post('user_name') . '</b>'));
redirect('user');
return;
}
@@ -194,8 +271,8 @@ class User extends CI_Controller {
$data['user_email'] = $this->input->post('user_email');
$data['user_password'] = $this->input->post('user_password');
$data['user_type'] = $this->input->post('user_type');
$data['user_firstname'] = $this->input->post('user_firstname');
$data['user_lastname'] = $this->input->post('user_lastname');
$data['user_firstname'] = $this->input->post('user_firstname') ?? '';
$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');
@@ -221,7 +298,7 @@ class User extends CI_Controller {
$data['user_quicklog_enter'] = $this->input->post('user_quicklog_enter');
$data['user_language'] = $this->input->post('user_language');
$this->load->view('user/edit', $data);
$this->load->view('interface_assets/footer');
$this->load->view('interface_assets/footer', $footerData);
}
}
@@ -250,12 +327,18 @@ 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['user_form_action'] = site_url('user/edit')."/".$this->uri->segment(3);;
$data['user_form_action'] = site_url('user/edit')."/".$this->uri->segment(3);
$data['clubstation'] = ($query->row()->clubstation == 1) ? true : false;
$data['bands'] = $this->bands->get_user_bands();
// Get themes list
$data['themes'] = $this->user_model->getThemes();
$footerData = [];
$footerData['scripts'] = [
'assets/js/sections/user.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/user.js")),
];
// Get timezones
$data['timezones'] = $this->user_model->timezones();
@@ -640,7 +723,7 @@ class User extends CI_Controller {
$this->load->view('interface_assets/header', $data);
$this->load->view('user/edit', $data);
$this->load->view('interface_assets/footer');
$this->load->view('interface_assets/footer', $footerData);
} else {
unset($data);
switch($this->user_model->edit($this->input->post())) {
@@ -686,10 +769,10 @@ class User extends CI_Controller {
}
$this->user_options_model->set_option('header_menu', 'locations_quickswitch', array('boolean'=>xss_clean($this->input->post('user_locations_quickswitch', true))));
$this->user_options_model->set_option('header_menu', 'utc_headermenu', array('boolean'=>xss_clean($this->input->post('user_utc_headermenu', true))));
$this->session->set_flashdata('success', __("User").' '.$this->input->post('user_name', true).' '.__("edited"));
$this->session->set_flashdata('success', sprintf(__("User %s edited"), $this->input->post('user_name', true)));
redirect('user/edit/'.$this->uri->segment(3));
} else {
$this->session->set_flashdata('success', __("User").' '.$this->input->post('user_name', true).' '.__("edited"));
$this->session->set_flashdata('success', sprintf(__("User %s edited"), $this->input->post('user_name', true)));
redirect('user');
}
return;
@@ -790,6 +873,14 @@ class User extends CI_Controller {
}
function login($firstlogin = false) {
// Due the fact there was a new session generated, we need to get flash messages from a temporary cookie
$tmpdata = json_decode($this->input->cookie(config_item('cookie_prefix') . 'tmp_msg') ?? '') ?? false;
if ($tmpdata) {
$this->session->set_flashdata($tmpdata[0], $tmpdata[1]);
$this->input->set_cookie('tmp_msg', '', -3600, '');
}
// Check our version and run any migrations
if (!$this->load->is_loaded('Migration')) {
$this->load->library('Migration');
@@ -814,7 +905,7 @@ class User extends CI_Controller {
$data['user'] = $query->row();
// Read the cookie keep_login and allow the login
if ($this->input->cookie(config_item('cookie_prefix') . 'keep_login')) {
if ($this->input->cookie(config_item('cookie_prefix') . 'keep_login') || $this->input->cookie(config_item('cookie_prefix') . 're_login')) {
try {
@@ -823,7 +914,7 @@ class User extends CI_Controller {
}
// process the incoming string
$incoming_string = $this->input->cookie(config_item('cookie_prefix') . 'keep_login');
$incoming_string = $this->input->cookie(config_item('cookie_prefix') . 'keep_login') ?? $this->input->cookie(config_item('cookie_prefix') . 're_login');
$i_str_parts_a = explode(base64_encode($this->config->item('base_url')), $incoming_string);
$uid = base64_decode($i_str_parts_a[1]);
$a = $i_str_parts_a[0];
@@ -836,6 +927,13 @@ class User extends CI_Controller {
$user = $this->user_model->get_by_id($uid)->row();
$user_type = $user->user_type;
// direct login to clubstations are not allowed, especially not with a keeplogin cookie
if ($user->clubstation == 1) {
log_message('debug', "User ID: [$uid] Login rejected because of a external clubstation login attempt with a modified cookie. Attack?");
$this->session->set_flashdata('error', __("This is not allowed!"));
redirect('user/login');
}
// compare both strings the hard way and log in if they match
if ($this->user_model->check_keep_hash($a, $b)) {
@@ -845,7 +943,8 @@ class User extends CI_Controller {
// if everything is fine we can log in the user
$this->user_model->update_session($uid);
$this->user_model->set_last_seen($uid);
log_message('debug', "User ID: [$uid] logged in successfully with 'Keep Login'.");
log_message('info', "User ID: [$uid] logged in successfully with 'Keep Login'.");
$this->input->set_cookie('re_login', '', -3600, ''); // delete re_login cookie in case this was a re-login from a clubstation or impersonated user
redirect('dashboard');
} else {
@@ -855,6 +954,7 @@ class User extends CI_Controller {
// Delete keep_login cookie
$this->input->set_cookie('keep_login', '', -3600, '');
$this->input->set_cookie('re_login', '', -3600, '');
redirect('user/login');
}
@@ -864,6 +964,7 @@ class User extends CI_Controller {
// Delete keep_login cookie
$this->input->set_cookie('keep_login', '', -3600, '');
$this->input->set_cookie('re_login', '', -3600, '');
$this->session->set_flashdata('error', __("Login failed. Try again."));
redirect('user/login');
}
@@ -873,6 +974,7 @@ class User extends CI_Controller {
// Delete keep_login cookie
$this->input->set_cookie('keep_login', '', -3600, '');
$this->input->set_cookie('re_login', '', -3600, '');
$this->session->set_flashdata('error', __("Login failed. Try again."));
redirect('user/login');
@@ -888,7 +990,8 @@ class User extends CI_Controller {
$this->load->view('interface_assets/footer');
} else {
if($this->user_model->login() == 1) {
$login_attempt = $this->user_model->login();
if($login_attempt === 1) {
$this->user_model->update_session($data['user']->user_id);
$cookie= array(
@@ -916,7 +1019,10 @@ class User extends CI_Controller {
}
$this->user_model->set_last_seen($data['user']->user_id);
redirect('dashboard');
} else if ($login_attempt === 2) {
$this->session->set_flashdata('warning', __("You can't login to a clubstation directly. Use your personal account instead."));
redirect('user/login');
} else {
if(ENVIRONMENT == 'maintenance') {
$this->session->set_flashdata('notice', __("Sorry. This instance is currently in maintenance mode. If this message appears unexpectedly or keeps showing up, please contact an administrator. Only administrators are currently allowed to log in."));
@@ -929,17 +1035,25 @@ class User extends CI_Controller {
}
}
function logout() {
function logout($custom_message = null, $hard_logout = true) {
$this->load->model('user_model');
$user_name = $this->session->userdata('user_name');
// Delete keep_login cookie
$this->input->set_cookie('keep_login', '', -3600, '');
if ($hard_logout) {
$this->input->set_cookie('re_login', '', -3600, '');
$this->input->set_cookie('keep_login', '', -3600, '');
}
$this->user_model->clear_session();
$this->session->set_flashdata('notice', sprintf(__("User %s logged out."), $user_name));
if ($custom_message != null && is_array($custom_message)) {
$this->input->set_cookie('tmp_msg', json_encode([$custom_message[0], $custom_message[1]]), 10, '');
} else {
$this->input->set_cookie('tmp_msg', json_encode(['notice', sprintf(__("User %s logged out."), $user_name)]), 10, '');
}
redirect('user/login');
}
@@ -1185,13 +1299,15 @@ class User extends CI_Controller {
// Check if impersonating is disabled in the config
if ($this->config->item('disable_impersonate')) {
show_404();
$this->session->set_flashdata('error', sprintf(__("You currently can't impersonate another user. You need to set %s to %s in your config.php!"), "'disable_impersonate'", "'false'"));
redirect('dashboard');
}
// Load the encryption library
if (!$this->load->is_loaded('encryption')) {
$this->load->library('encryption');
}
// Load the user model
$this->load->model('user_model');
@@ -1241,13 +1357,38 @@ class User extends CI_Controller {
redirect('dashboard');
}
// before we can impersonate a user, we need to make sure the current user is an admin
// TODO: authorize from additional datatable 'impersonators' to allow other user types to impersonate
// before we can impersonate a user, we need to make sure the current user is allowed to do so
$clubswitch = $this->input->post('clubswitch', TRUE) ?? '';
$custom_sessiondata = [];
$source_user = $this->user_model->get_by_id($source_uid)->row();
if(!$source_user || !$this->user_model->authorize(99)) {
$this->session->set_flashdata('error', __("You're not allowed to do that!"));
redirect('dashboard');
if ($clubswitch == 1) {
$this->load->model('club_model');
if (!$this->club_model->club_authorize(3, $target_uid, $source_uid) || !$this->user_model->authorize(3)) {
$this->session->set_flashdata('error', __("You're not allowed to do that!"));
redirect('dashboard');
} else {
$targetclub = array_filter($this->session->userdata('available_clubstations'), function($club) use ($target_uid) {
return $club->user_id == $target_uid;
});
$p_level = !empty($targetclub) ? reset($targetclub)->p_level : null;
if ($p_level != null) {
$custom_sessiondata['p_level'] = $p_level;
} else {
$this->session->set_flashdata('error', __("Could not determine the correct permission level for the clubstation. Try again after re-login."));
redirect('dashboard');
}
}
} else {
if(!$source_user || !$this->user_model->authorize(99)) {
$this->session->set_flashdata('error', __("You're not allowed to do that!"));
redirect('dashboard');
} else {
$custom_sessiondata['p_level'] = 99; // if the user is an admin he also should have full rights in the clubstations
}
}
$custom_sessiondata['src_call'] = $source_user->user_callsign;
$custom_sessiondata['src_user_type'] = $source_user->user_type;
$custom_sessiondata['src_hash'] = $this->input->post('hash', TRUE) ?? '';
/**
* Impersonate the user
@@ -1255,9 +1396,87 @@ class User extends CI_Controller {
// Update the session with the new user_id
// TODO: Find a solution for sessiondata 'radio', so a user would be able to use e.g. his own radio while impersonating another user
// Due the fact that the user is now impersonating another user, he can't use his default radio anymore
$this->user_model->update_session($target_uid, null, $impersonate = true);
$this->session->set_userdata('source_uid', $source_uid);
$this->user_model->update_session($target_uid, null, true, $custom_sessiondata);
// Redirect to the dashboard, the user should now be logged in as the other user
redirect('dashboard');
}
public function stop_impersonate_modal() {
// Load the user model
$this->load->model('user_model');
if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
$this->load->view('user/modals/stop_impersonate_modal');
}
public function stop_impersonate() {
// Load the user model
$this->load->model('user_model');
// there is no source_uid, there is probably something fishy going on. So we clear the session at this point
$source_uid = $this->session->userdata('source_uid') ?? false;
$post_chk = $this->input->post('stopImpersonate', TRUE) ?? false;
if (!$source_uid || $post_chk != 1) {
$this->logout(['error', __("Ups.. Something went wrong. Try to log back in.")]);
exit;
}
// is the current user a clubstation we need to check if the source user was allowed to impersonate the clubstation
$club = $this->user_model->get_by_id($this->session->userdata('user_id'))->row();
$current_is_club = $club->clubstation == 1 ? true : false;
$source_user = $this->user_model->get_by_id($source_uid)->row();
if ($current_is_club) {
$this->load->model('club_model');
if (!$this->club_model->club_authorize(3, $this->session->userdata('user_id'), $source_uid)) {
$this->logout(['error', __("Ups.. Something went wrong. Try to log back in.")]);
exit;
}
} else {
// if the current user is not a clubstation, we need to check if the source user was allowed to impersonate the current user (has to be an admin)
if($source_user->user_type != 99) {
$this->logout(['error', __("Ups.. Something went wrong. Try to log back in.")]);
exit;
}
}
// Validate the impersonate hash
$this->load->library('encryption');
$raw_hash = $this->encryption->decrypt($this->session->userdata('cd_src_hash') ?? false);
if (!$raw_hash) {
$this->logout(['error', __("Ups.. Something went wrong. Try to log back in.")]);
exit;
}
$hash_parts = explode('/', $raw_hash);
$src_in_hash = $hash_parts[0];
$tgt_in_hash = $hash_parts[1];
$timestamp = $hash_parts[2];
if ($src_in_hash != $source_uid || $tgt_in_hash != $this->session->userdata('user_id')) {
$this->logout(['error', __("Ups.. Something went wrong. Try to log back in.")]);
exit;
}
// The timestamp can't be older then 2 hours
if (time() - $timestamp > 7200) {
$this->logout(['notice', __("The ability to return quickly has been disabled after the security hash expired. Please log in again.")]);
exit;
}
// Create a keep login cookie which will be used to log back in as the source user
$encrypted_string = $this->user_model->keep_cookie_hash($source_uid);
$cookie = array(
'name' => 're_login', // we use a different cookie name to avoid conflicts with the regular keep_login cookie
'value' => $encrypted_string,
'expire' => 20, // seconds should be enough
'secure' => FALSE,
'httponly' => TRUE
);
$this->input->set_cookie($cookie);
// log out on the regular way
$msg = ['notice', sprintf(__("You have been logged out of the clubstation %s. Welcome back, %s, to your personal account!"), $club->user_callsign, $source_user->user_callsign)];
$this->logout($msg, false);
}
}

View File

@@ -387,6 +387,11 @@ class Visitor extends CI_Controller {
$data['gridsquares_gridsquares_not_confirmed'] = __("Gridsquares not confirmed");
$data['gridsquares_gridsquares_total_worked'] = __("Total gridsquares worked");
$data['gridsquares_fields'] = __("Fields");
$data['gridsquares_fields_confirmed'] = __("Fields confirmed");
$data['gridsquares_fields_not_confirmed'] = __("Fields not confirmed");
$data['gridsquares_fields_total_worked'] = __("Total fields worked");
$data['visitor'] = true;
$this->load->view('visitor/layout/header', $data);

View File

@@ -87,6 +87,9 @@ class Webadif extends CI_Controller {
* Used for displaying the uid for manually selecting log for upload to webADIF consumer
*/
public function export() {
$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'); }
$this->load->model('stations');
$data['page_title'] = __("QO-100 Dx Club Upload");

View File

@@ -0,0 +1,49 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Small Helper functions for the Clubstations feature
*/
/**
* Access Check in the UI for impersonated clubstations
*
* To see available permission levels, check out 'application/controllers/Club.php'
*/
if (!function_exists('clubaccess_check')) {
function clubaccess_check($required_level, $qso_id = 0) {
$CI =& get_instance();
if (!$CI->load->is_loaded('session')) {
$CI->load->library('session');
}
$clubmode = $CI->config->item('special_callsign') ?? false;
$clubstation = $CI->session->userdata('clubstation') ?? 0;
if ($clubmode && $clubstation == 1) {
// check if the user has the required level
if ($CI->session->userdata('cd_p_level') >= $required_level) {
if ($qso_id != 0) {
// 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) {
return true;
} else {
return false;
}
} else {
return true;
}
} else {
return false;
}
} else {
// return always true if the special callsign mode is disabled, so there is no change in behaviour
return true;
}
}
}

View File

@@ -2,215 +2,223 @@
class AdifHelper {
public function getAdifLine($qso) {
$normalFields = array(
'ADDRESS',
'AGE',
'A_INDEX',
'ANT_AZ',
'ANT_EL',
'ANT_PATH',
'ARRL_SECT',
'AWARD_GRANTED',
'AWARD_SUBMITTED',
'BAND',
'BAND_RX',
'BIOGRAPHY',
'CALL',
'CHECK',
'CLASS',
'CLUBLOG_QSO_UPLOAD_STATUS',
'CNTY',
'COMMENT',
'CONT',
'CONTACTED_OP',
'CONTEST_ID',
'COUNTRY',
'CQZ',
'CREDIT_GRANTED',
'CREDIT_SUBMITTED',
'DARC_DOK',
'DISTANCE',
'DXCC',
'EMAIL',
'EQ_CALL',
'EQSL_QSL_RCVD',
'EQSL_QSL_SENT',
'EQSL_STATUS',
'FISTS',
'FISTS_CC',
'FORCE_INIT',
'GRIDSQUARE',
'HEADING',
'IOTA',
'ITUZ',
'K_INDEX',
'LAT',
'LON',
'LOTW_QSL_RCVD',
'LOTW_QSL_SENT',
'LOTW_STATUS',
'MAX_BURSTS',
'MODE',
'MS_SHOWER',
'NAME',
'NOTES',
'NR_BURSTS',
'NR_PINGS',
'OPERATOR',
'OWNER_CALLSIGN',
'PFX',
'PRECEDENCE',
'PROP_MODE',
'PUBLIC_KEY',
'HRDLOG_QSO_UPLOAD_STATUS',
'QRZCOM_QSO_UPLOAD_STATUS',
'QSLMSG',
'QSL_RCVD',
'QSL_RCVD_VIA',
'QSL_SENT',
'QSL_SENT_VIA',
'QSL_VIA',
'QSO_COMPLETE',
'QSO_RANDOM',
'QTH',
'REGION',
'RIG',
'RST_RCVD',
'RST_SENT',
'RX_PWR',
'SAT_MODE',
'SAT_NAME',
'SFI',
'SILENT_KEY',
'SKCC',
'SOTA_REF',
'WWFF_REF',
'POTA_REF',
'SRX',
'SRX_STRING',
'STATE',
'STX',
'STX_STRING',
'SUBMODE',
'SWL',
'TEN_TEN',
'TX_PWR',
'UKSMG',
'USACA_COUNTIES',
'VUCC_GRIDS',
'WEB',
);
public function getAdifLine($qso) {
$normalFields = array(
'ADDRESS',
'AGE',
'A_INDEX',
'ANT_AZ',
'ANT_EL',
'ANT_PATH',
'ARRL_SECT',
'AWARD_GRANTED',
'AWARD_SUBMITTED',
'BAND',
'BAND_RX',
'BIOGRAPHY',
'CALL',
'CHECK',
'CLASS',
'CLUBLOG_QSO_UPLOAD_STATUS',
'CNTY',
'COMMENT',
'CONT',
'CONTACTED_OP',
'CONTEST_ID',
'COUNTRY',
'CQZ',
'CREDIT_GRANTED',
'CREDIT_SUBMITTED',
'DARC_DOK',
'DISTANCE',
'DXCC',
'EMAIL',
'EQ_CALL',
'EQSL_QSL_RCVD',
'EQSL_QSL_SENT',
'EQSL_STATUS',
'FISTS',
'FISTS_CC',
'FORCE_INIT',
'GRIDSQUARE',
'HEADING',
'IOTA',
'ITUZ',
'K_INDEX',
'LAT',
'LON',
'LOTW_QSL_RCVD',
'LOTW_QSL_SENT',
'LOTW_STATUS',
'MAX_BURSTS',
'MODE',
'MS_SHOWER',
'NAME',
'NOTES',
'NR_BURSTS',
'NR_PINGS',
'OPERATOR',
'OWNER_CALLSIGN',
'PFX',
'PRECEDENCE',
'PROP_MODE',
'PUBLIC_KEY',
'HRDLOG_QSO_UPLOAD_STATUS',
'QRZCOM_QSO_UPLOAD_STATUS',
'QSLMSG',
'QSL_RCVD',
'QSL_RCVD_VIA',
'QSL_SENT',
'QSL_SENT_VIA',
'QSL_VIA',
'QSO_COMPLETE',
'QSO_RANDOM',
'QTH',
'REGION',
'RIG',
'RST_RCVD',
'RST_SENT',
'RX_PWR',
'SAT_MODE',
'SAT_NAME',
'SFI',
'SILENT_KEY',
'SKCC',
'SOTA_REF',
'WWFF_REF',
'POTA_REF',
'SRX',
'SRX_STRING',
'STATE',
'STX',
'STX_STRING',
'SUBMODE',
'SWL',
'TEN_TEN',
'TX_PWR',
'UKSMG',
'USACA_COUNTIES',
'VUCC_GRIDS',
'WEB',
'CNTY_ALT',
'MY_CNTY_ALT',
'MY_DARC_DOK',
'MORSE_KEY_INFO',
'MORSE_KEY_TYPE',
'QSLMSG_RCVD',
);
$dateFields = array(
'EQSL_QSLRDATE',
'EQSL_QSLSDATE',
'LOTW_QSLRDATE',
'LOTW_QSLSDATE',
'QSLRDATE',
'QSLSDATE',
'CLUBLOG_QSO_UPLOAD_DATE',
'HRDLOG_QSO_UPLOAD_DATE',
'QRZCOM_QSO_UPLOAD_DATE',
);
$dateFields = array(
'EQSL_QSLRDATE',
'EQSL_QSLSDATE',
'LOTW_QSLRDATE',
'LOTW_QSLSDATE',
'QSLRDATE',
'QSLSDATE',
'CLUBLOG_QSO_UPLOAD_DATE',
'HRDLOG_QSO_UPLOAD_DATE',
'QRZCOM_QSO_UPLOAD_DATE',
'DCL_QSLRDATE',
'DCL_QSLSDATE',
);
/**
Missing:
USER_DEFINED_0
USER_DEFINED_1
USER_DEFINED_2
USER_DEFINED_3
USER_DEFINED_4
USER_DEFINED_5
USER_DEFINED_6
USER_DEFINED_7
USER_DEFINED_8
USER_DEFINED_9
*/
/**
Missing:
USER_DEFINED_0
USER_DEFINED_1
USER_DEFINED_2
USER_DEFINED_3
USER_DEFINED_4
USER_DEFINED_5
USER_DEFINED_6
USER_DEFINED_7
USER_DEFINED_8
USER_DEFINED_9
*/
// Build ADIF fields
// Build ADIF fields
$line = "";
foreach ($normalFields as $field) {
$line .= $this->getAdifFieldLine($field, $qso->{'COL_' . $field});
}
$line = "";
foreach ($normalFields as $field) {
$line .= $this->getAdifFieldLine($field, $qso->{'COL_' . $field});
}
foreach ($dateFields as $field) {
if ($qso->{'COL_' . $field}) {
$date = strtotime($qso->{'COL_' . $field});
$date = date('Ymd', $date);
$line .= $this->getAdifFieldLine($field, $date);
}
}
foreach ($dateFields as $field) {
if ($qso->{'COL_' . $field}) {
$date = strtotime($qso->{'COL_' . $field});
$date = date('Ymd', $date);
$line .= $this->getAdifFieldLine($field, $date);
}
}
if ($qso->COL_FREQ != 0) {
$freq_in_mhz = $qso->COL_FREQ / 1000000;
$line .= $this->getAdifFieldLine("FREQ", $freq_in_mhz);
}
if ($qso->COL_FREQ != 0) {
$freq_in_mhz = $qso->COL_FREQ / 1000000;
$line .= $this->getAdifFieldLine("FREQ", $freq_in_mhz);
}
if ($qso->COL_FREQ_RX != 0) {
$freq_rx_in_mhz = $qso->COL_FREQ_RX / 1000000;
$line .= $this->getAdifFieldLine("FREQ_RX", $freq_rx_in_mhz);
}
if ($qso->COL_FREQ_RX != 0) {
$freq_rx_in_mhz = $qso->COL_FREQ_RX / 1000000;
$line .= $this->getAdifFieldLine("FREQ_RX", $freq_rx_in_mhz);
}
if (isset($qso->COL_TIME_ON) && (date('YmdHis',strtotime($qso->COL_TIME_ON)) != '-00011130000000')) {
$date_on = strtotime($qso->COL_TIME_ON);
$date_on = date('Ymd', $date_on);
$line .= $this->getAdifFieldLine("QSO_DATE", $date_on);
if (isset($qso->COL_TIME_ON) && (date('YmdHis',strtotime($qso->COL_TIME_ON)) != '-00011130000000')) {
$date_on = strtotime($qso->COL_TIME_ON);
$date_on = date('Ymd', $date_on);
$line .= $this->getAdifFieldLine("QSO_DATE", $date_on);
$time_on = strtotime($qso->COL_TIME_ON);
$time_on = date('His', $time_on);
$line .= $this->getAdifFieldLine("TIME_ON", $time_on);
} else {
$line .= $this->getAdifFieldLine("QSO_DATE", '19700101');
$line .= $this->getAdifFieldLine("TIME_ON", '000000');
}
$time_on = strtotime($qso->COL_TIME_ON);
$time_on = date('His', $time_on);
$line .= $this->getAdifFieldLine("TIME_ON", $time_on);
} else {
$line .= $this->getAdifFieldLine("QSO_DATE", '19700101');
$line .= $this->getAdifFieldLine("TIME_ON", '000000');
}
if (isset($qso->COL_TIME_OFF) && (date('YmdHis',strtotime($qso->COL_TIME_OFF)) != '-00011130000000')) {
$date_off = strtotime($qso->COL_TIME_OFF);
$date_off = date('Ymd', $date_off);
$line .= $this->getAdifFieldLine("QSO_DATE_OFF", $date_off);
if (isset($qso->COL_TIME_OFF) && (date('YmdHis',strtotime($qso->COL_TIME_OFF)) != '-00011130000000')) {
$date_off = strtotime($qso->COL_TIME_OFF);
$date_off = date('Ymd', $date_off);
$line .= $this->getAdifFieldLine("QSO_DATE_OFF", $date_off);
$time_off = strtotime($qso->COL_TIME_OFF);
$time_off = date('His', $time_off);
$line .= $this->getAdifFieldLine("TIME_OFF", $time_off);
} else {
$line .= $this->getAdifFieldLine("QSO_DATE_OFF", '19700101');
$line .= $this->getAdifFieldLine("TIME_OFF", '000000');
}
$time_off = strtotime($qso->COL_TIME_OFF);
$time_off = date('His', $time_off);
$line .= $this->getAdifFieldLine("TIME_OFF", $time_off);
} else {
$line .= $this->getAdifFieldLine("QSO_DATE_OFF", '19700101');
$line .= $this->getAdifFieldLine("TIME_OFF", '000000');
}
// "MY" information
$line .= $this->getAdifFieldLine("STATION_CALLSIGN", $qso->station_callsign);
// "MY" information
$line .= $this->getAdifFieldLine("STATION_CALLSIGN", $qso->station_callsign);
$line .= $this->getAdifFieldLine("MY_CITY", $qso->station_city);
$line .= $this->getAdifFieldLine("MY_CITY", $qso->station_city);
$line .= $this->getAdifFieldLine("MY_COUNTRY", $qso->station_country);
$line .= $this->getAdifFieldLine("MY_COUNTRY", $qso->station_country);
$line .= $this->getAdifFieldLine("MY_DXCC", $qso->station_dxcc);
$line .= $this->getAdifFieldLine("MY_DXCC", $qso->station_dxcc);
if (strpos($qso->station_gridsquare, ',') !== false ) {
$line .= $this->getAdifFieldLine("MY_VUCC_GRIDS", $qso->station_gridsquare);
} else {
$line .= $this->getAdifFieldLine("MY_GRIDSQUARE", $qso->station_gridsquare);
}
if (strpos($qso->station_gridsquare, ',') !== false ) {
$line .= $this->getAdifFieldLine("MY_VUCC_GRIDS", $qso->station_gridsquare);
} else {
$line .= $this->getAdifFieldLine("MY_GRIDSQUARE", $qso->station_gridsquare);
}
$line .= $this->getAdifFieldLine("MY_IOTA", $qso->station_iota);
$line .= $this->getAdifFieldLine("MY_IOTA", $qso->station_iota);
$line .= $this->getAdifFieldLine("MY_SOTA_REF", $qso->station_sota);
$line .= $this->getAdifFieldLine("MY_SOTA_REF", $qso->station_sota);
$line .= $this->getAdifFieldLine("MY_WWFF_REF", $qso->station_wwff);
$line .= $this->getAdifFieldLine("MY_WWFF_REF", $qso->station_wwff);
$line .= $this->getAdifFieldLine("MY_POTA_REF", $qso->station_pota);
$line .= $this->getAdifFieldLine("MY_POTA_REF", $qso->station_pota);
$line .= $this->getAdifFieldLine("MY_CQ_ZONE", $qso->station_cq);
$line .= $this->getAdifFieldLine("MY_CQ_ZONE", $qso->station_cq);
$line .= $this->getAdifFieldLine("MY_ITU_ZONE", $qso->station_itu);
$line .= $this->getAdifFieldLine("MY_ITU_ZONE", $qso->station_itu);
$line .= $this->getAdifFieldLine("MY_STATE", $qso->state);
$line .= $this->getAdifFieldLine("MY_STATE", $qso->state);
// See: https://adif.org/314/ADIF_314.htm#Sponsor_Defined_Code_Format
if ($qso->station_cnty) {
switch ($qso->station_dxcc) {
// See: https://adif.org/314/ADIF_314.htm#Sponsor_Defined_Code_Format
if ($qso->station_cnty) {
switch ($qso->station_dxcc) {
case '6':
case '110':
case '291':
@@ -219,51 +227,37 @@ class AdifHelper {
default:
$county = trim($qso->station_cnty);
break;
}
} else {
$county = '';
}
} else {
$county = '';
}
$line .= $this->getAdifFieldLine("MY_CNTY", $county);
$stationsSig = $qso->station_sig;
// If MY_SIG is WWFF or "" and there's a station_wwff set, use data from station_wwff
if ((empty($stationsSig) || $stationsSig === "WWFF") && !empty($qso->station_wwff)) {
$line .= $this->getAdifFieldLine("MY_SIG", "WWFF");
$line .= $this->getAdifFieldLine("MY_SIG_INFO", $qso->station_wwff);
} else {
$line .= $this->getAdifFieldLine("MY_SIG", $stationsSig);
$line .= $this->getAdifFieldLine("MY_SIG_INFO", $qso->station_sig_info);
}
$line .= $this->getAdifFieldLine("MY_SIG", $qso->station_sig);
$line .= $this->getAdifFieldLine("MY_SIG_INFO", $qso->station_sig_info);
$sig = $qso->{'COL_SIG'};
// If SIG is WWFF or "" and there's a WWFF_REF set, use data from COL_WWFF_REF
if ((empty($sig) || $sig === "WWFF") && !empty($qso->{'COL_WWFF_REF'})) {
$line .= $this->getAdifFieldLine("SIG", "WWFF");
$line .= $this->getAdifFieldLine("SIG_INFO", $qso->{'COL_WWFF_REF'});
} else {
$line .= $this->getAdifFieldLine("SIG", $sig);
$line .= $this->getAdifFieldLine("SIG_INFO", $qso->{'COL_SIG_INFO'});
}
$line .= $this->getAdifFieldLine("SIG", $qso->{'COL_SIG'});
$line .= $this->getAdifFieldLine("SIG_INFO", $qso->{'COL_SIG_INFO'});
/*
Missing:
MY_ANTENNA
MY_FISTS
MY_IOTA_ISLAND_ID
MY_LAT
MY_LON
MY_NAME
MY_POSTAL_CODE
MY_RIG
MY_STREET
MY_USACA_COUNTIES
*/
/*
Missing:
MY_ANTENNA
MY_FISTS
MY_IOTA_ISLAND_ID
MY_LAT
MY_LON
MY_NAME
MY_POSTAL_CODE
MY_RIG
MY_STREET
MY_USACA_COUNTIES
*/
$line .= "<EOR>\r\n\r\n";
$line .= "<EOR>\r\n\r\n";
return $line;
}
return $line;
}
function getAdifFieldLine($adifcolumn, $dbvalue) {
if ($dbvalue !== "" && $dbvalue !== null && $dbvalue !== 0) {

View File

@@ -0,0 +1,154 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
Callbook library
Instead of implementing functions for each callbook, we should call one library, which then calls the correct callbook according to config.
This makes it easy to implement other callbooks as well.
*/
class Callbook {
private $ci;
public function __construct() {
$this->ci = & get_instance();
}
// TODO:
// Implement the following:
// - Implement callsign reduced logic
public function getCallbookData($callsign) {
switch ($this->ci->config->item('callbook')) {
case 'qrz':
if ($this->ci->config->item('qrz_username') == null || $this->ci->config->item('qrz_password') == null) {
$callbook['error'] = 'Lookup not configured. Please review configuration.';
return $callbook;
}
return $this->qrz($this->ci->config->item('qrz_username'), $this->ci->config->item('qrz_password'), $callsign, $this->ci->config->item('use_fullname'));
break;
case 'qrzcq':
if ($this->ci->config->item('qrzcq_username') == null || $this->ci->config->item('qrzcq_password') == null) {
$callbook['error'] = 'Lookup not configured. Please review configuration.';
return $callbook;
}
return $this->qrzcq($this->ci->config->item('qrzcq_username'), $this->ci->config->item('qrzcq_password'), $callsign);
break;
case 'hamqth':
if ($this->ci->config->item('hamqth_username') == null || $this->ci->config->item('hamqth_password') == null) {
$callbook['error'] = 'Lookup not configured. Please review configuration.';
return $callbook;
}
return $this->hamqth($this->ci->config->item('hamqth_username'), $this->ci->config->item('hamqth_password'), $callsign);
break;
default:
$callbook['error'] = 'No callbook defined. Please review configuration.';
return $callbook;
}
}
function qrz($username, $password, $callsign, $fullname) {
if (!$this->ci->load->is_loaded('qrz')) {
$this->ci->load->library('qrz');
}
if (!$this->ci->session->userdata('qrz_session_key')) {
$qrz_session_key = $this->ci->qrz->session($username, $password);
$this->ci->session->set_userdata('qrz_session_key', $qrz_session_key);
}
$callbook = $this->ci->qrz->search($callsign, $this->ci->session->userdata('qrz_session_key'), $fullname);
if ($callbook['error'] ?? '' == 'Invalid session key') {
$qrz_session_key = $this->ci->qrz->session($username, $password);
$this->ci->session->set_userdata('qrz_session_key', $qrz_session_key);
$callbook = $this->ci->qrz->search($callsign, $this->ci->session->userdata('qrz_session_key'), $fullname);
}
if (strpos($callbook['error'] ?? '', 'Not found') !== false && strpos($callsign, "/") !== false) {
$plaincall = $this->get_plaincall($callsign);
// Now try again but give back reduced data, as we can't validate location and stuff (true at the end)
$callbook = $this->ci->qrz->search($plaincall, $this->ci->session->userdata('qrz_session_key'), $fullname, true);
}
return $callbook;
}
function qrzcq($username, $password, $callsign) {
if (!$this->ci->load->is_loaded('qrzcq')) {
$this->ci->load->library('qrzcq');
}
if (!$this->ci->session->userdata('qrzcq_session_key')) {
$result = $this->ci->qrzcq->session($username, $password);
if ($result[0] == 0) {
$this->ci->session->set_userdata('qrzcq_session_key', $result[1]);
} else {
$data['error'] = __("QRZCQ Error").": ".$result[1];
return $data;
}
}
$callbook = $this->ci->qrzcq->search($callsign, $this->ci->session->userdata('qrzcq_session_key'));
if ($callbook['error'] ?? '' == 'Invalid session key') {
$qrzcq_session_key = $this->ci->qrzcq->session($username, $password);
$this->ci->session->set_userdata('qrzcq_session_key', $qrzcq_session_key);
$callbook = $this->ci->qrzcq->search($callsign, $this->ci->session->userdata('qrzcq_session_key'));
}
if (strpos($callbook['error'] ?? '', 'Not found') !== false && strpos($callsign, "/") !== false) {
$plaincall = $this->get_plaincall($callsign);
// Now try again but give back reduced data, as we can't validate location and stuff (true at the end)
$callbook = $this->ci->qrzcq->search($plaincall, $this->ci->session->userdata('qrzcq_session_key'), true);
}
return $callbook;
}
function hamqth($username, $password, $callsign) {
// Load the HamQTH library
if (!$this->ci->load->is_loaded('hamqth')) {
$this->ci->load->library('hamqth');
}
if (!$this->ci->session->userdata('hamqth_session_key')) {
$hamqth_session_key = $this->ci->hamqth->session($username, $password);
$this->ci->session->set_userdata('hamqth_session_key', $hamqth_session_key);
}
$callbook = $this->ci->hamqth->search($callsign, $this->ci->session->userdata('hamqth_session_key'));
// If HamQTH session has expired, start a new session and retry the search.
if ($callbook['error'] == "Session does not exist or expired") {
$hamqth_session_key = $this->ci->hamqth->session($username, $password);
$this->ci->session->set_userdata('hamqth_session_key', $hamqth_session_key);
$callbook = $this->ci->hamqth->search($callsign, $this->ci->session->userdata('hamqth_session_key'));
}
if (strpos($callbook['error'] ?? '', 'Not found') !== false && strpos($callsign, "/") !== false) {
$plaincall = $this->get_plaincall($callsign);
// Now try again but give back reduced data, as we can't validate location and stuff (true at the end)
$callbook = $this->ci->hamqth->search($plaincall, $this->ci->session->userdata('hamqth_session_key'), true);
}
return $callbook;
}
function get_plaincall($callsign) {
$split_callsign = explode('/', $callsign);
if (count($split_callsign) == 1) { // case F0ABC --> return cel 0 //
$lookupcall = $split_callsign[0];
} else if (count($split_callsign) == 3) { // case EA/F0ABC/P --> return cel 1 //
$lookupcall = $split_callsign[1];
} else { // case F0ABC/P --> return cel 0 OR case EA/FOABC --> retunr 1 (normaly not exist) //
if (in_array(strtoupper($split_callsign[1]), array('P', 'M', 'MM', 'QRP', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'))) {
$lookupcall = $split_callsign[0];
} else if (strlen($split_callsign[1]) > 3) { // Last Element longer than 3 chars? Take that as call
$lookupcall = $split_callsign[1];
} else { // Last Element up to 3 Chars? Take first element as Call
$lookupcall = $split_callsign[0];
}
}
return $lookupcall;
}
}

View File

@@ -81,6 +81,7 @@ class Hamqth {
// we always want to return name and callsign
$data['callsign'] = (string)$xml->search->callsign;
$data['name'] = (string)$xml->search->nick;
$data['email'] = (string)$xml->search->email;
// only return certain data of a callsign which does not contain a pre- or suffix (see https://github.com/wavelog/wavelog/issues/452)
if ($reduced == false) {

View File

@@ -21,12 +21,12 @@ class Qra {
}
// calculate the bearing between two squares
function bearing($tx, $rx, $unit = 'M') {
function bearing($tx, $rx, $unit = 'M', $ant_path = null) {
$my = qra2latlong($tx);
$stn = qra2latlong($rx);
if ($my !== false && $stn !== false) {
$bearing = bearing($my[0], $my[1], $stn[0], $stn[1], $unit);
$bearing = bearing($my[0], $my[1], $stn[0], $stn[1], $unit, $ant_path);
return $bearing;
} else {
return false;
@@ -39,7 +39,7 @@ class Qra {
* Inputs are QRA's TX and TX and the unit
*
*/
function distance($tx, $rx, $unit = 'M') {
function distance($tx, $rx, $unit = 'M', $ant_path = null) {
// Calc LatLongs
$my = qra2latlong($tx);
$stn = qra2latlong($rx);
@@ -48,7 +48,7 @@ class Qra {
if ($my && $stn) {
// Feed in Lat Longs plus the unit type
try {
$total_distance = calc_distance($my[0], $my[1], $stn[0], $stn[1], $unit);
$total_distance = calc_distance($my[0], $my[1], $stn[0], $stn[1], $unit, $ant_path);
} catch (Exception $e) {
$total_distance = 0;
}
@@ -65,10 +65,10 @@ class Qra {
* Function returns just the bearing
* Input locator1 and locator2
*/
function get_bearing($tx, $rx) {
function get_bearing($tx, $rx, $ant_path = null) {
$my = qra2latlong($tx);
$stn = qra2latlong($rx);
return get_bearing($my[0], $my[1], $stn[0], $stn[1]);
return get_bearing($my[0], $my[1], $stn[0], $stn[1], $ant_path);
}
/*
@@ -202,13 +202,17 @@ class Qra {
}
function calc_distance($lat1, $lon1, $lat2, $lon2, $unit = 'M') {
function calc_distance($lat1, $lon1, $lat2, $lon2, $unit = 'M', $ant_path = null) {
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$dist = $dist * 60 * 1.1515;
if ($ant_path == "L") { // we only need to calculate the distance for long paths, all other paths are the same
$dist = 24880 - $dist;
}
if ($unit == "K") {
$dist *= 1.609344;
} else if ($unit == "N") {
@@ -220,11 +224,14 @@ function calc_distance($lat1, $lon1, $lat2, $lon2, $unit = 'M') {
return round($dist, 1);
}
function bearing($lat1, $lon1, $lat2, $lon2, $unit = 'M') {
$dist = calc_distance($lat1, $lon1, $lat2, $lon2, $unit);
function bearing($lat1, $lon1, $lat2, $lon2, $unit = 'M', $ant_path = null) {
$dist = calc_distance($lat1, $lon1, $lat2, $lon2, $unit, $ant_path);
$dist = round($dist, 0);
$bearing = get_bearing($lat1, $lon1, $lat2, $lon2);
if ($ant_path == 'L') {
$bearing = ($bearing + 180) % 360;
}
$dirs = array("N", "E", "S", "W");

View File

@@ -96,6 +96,8 @@ class Qrz {
$data['name'] = (string)$xml->Callsign->fname;
}
$data['email'] = (string)$xml->Callsign->email;
// we always give back the name, no matter if reduced data or not
$data['name'] = trim($data['name']);

View File

@@ -0,0 +1,151 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
Controls the interaction with the QRZcq.com Subscription based XML API.
*/
class Qrzcq {
// Return session key
public function session($username, $password) {
// URL to the XML Source
$ci = & get_instance();
$xml_feed_url = 'https://ssl.qrzcq.com/xml/?username='.$username.';password='.urlencode($password).';agent=wavelog';
// CURL Functions
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $xml_feed_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_USERAGENT, 'Wavelog/'.$ci->optionslib->get_option('version'));
$xml = curl_exec($ch);
curl_close($ch);
// Create XML object
$xml = simplexml_load_string($xml);
if (isset($xml->Session->Key)) {
$result = array( 0, (string) $xml->Session->Key);
} else if (isset($xml->Session->Error)) {
$result = array( 1, (string) $xml->Session->Error);
} else {
$result = array( 2, 'Unknown error');
}
return $result;
}
// Set Session Key session.
public function set_session($username, $password) {
$ci = & get_instance();
// URL to the XML Source
$xml_feed_url = 'https://ssl.qrzcq.com/xml/?username='.$username.';password='.urlencode($password).';agent=wavelog';
// CURL Functions
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $xml_feed_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_USERAGENT, 'Wavelog/'.$ci->optionslib->get_option('version'));
$xml = curl_exec($ch);
curl_close($ch);
// Create XML object
$xml = simplexml_load_string($xml);
$key = (string) $xml->Session->Key;
$ci->session->set_userdata('qrzcq_session_key', $key);
return true;
}
public function search($callsign, $key, $reduced = false) {
$data = null;
$ci = & get_instance();
try {
// URL to the XML Source
$xml_feed_url = 'https://ssl.qrzcq.com/xml/?s=' . $key . ';callsign=' . $callsign . '';
// CURL Functions
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $xml_feed_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_USERAGENT, 'Wavelog/'.$ci->optionslib->get_option('version'));
$xml = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpcode != 200) return $data['error'] = 'Problems with qrzcq.com communication'; // Exit function if no 200. If request fails, 0 is returned
// Create XML object
$xml = simplexml_load_string($xml);
if (!empty($xml->Session->Error)) {
return $data['error'] = $xml->Session->Error;
}
// Return Required Fields
$data['callsign'] = (string)$xml->Callsign->call;
$data['name'] = (string)$xml->Callsign->name;
// we always give back the name, no matter if reduced data or not
$data['name'] = trim($data['name']);
// Sanitize gridsquare to allow only up to 8 characters
$unclean_gridsquare = (string)$xml->Callsign->locator; // Get the gridsquare from QRZ convert to string
$clean_gridsquare = strlen($unclean_gridsquare) > 8 ? substr($unclean_gridsquare,0,8) : $unclean_gridsquare; // Trim gridsquare to 8 characters max
if ($reduced == false) {
$data['gridsquare'] = $clean_gridsquare;
$data['city'] = (string)$xml->Callsign->city;
$data['lat'] = (string)$xml->Callsign->latitude;
$data['long'] = (string)$xml->Callsign->longitude;
$data['dxcc'] = (string)$xml->Callsign->dxcc;
$data['state'] = (string)$xml->Callsign->state;
$data['iota'] = (string)$xml->Callsign->iota;
$data['image'] = (string)$xml->Callsign->qslpic;
$data['ituz'] = (string)$xml->Callsign->itu;
$data['cqz'] = (string)$xml->Callsign->cq;
$data['continent'] = (string)$xml->Callsign->continent;
if ($xml->Callsign->country == "United States") {
$data['us_county'] = (string)$xml->Callsign->county;
} else {
$data['us_county'] = null;
$data['county'] = (string)$xml->Callsign->county;
}
} else {
$data['gridsquare'] = '';
$data['city'] = '';
$data['lat'] = '';
$data['long'] = '';
$data['dxcc'] = '';
$data['state'] = '';
$data['iota'] = '';
$data['image'] = (string)$xml->Callsign->qslpic;
$data['county'] = '';
$data['us_county'] = '';
$data['ituz'] = '';
$data['cqz'] = '';
}
} finally {
return $data;
}
}
}

View File

@@ -105,7 +105,7 @@ class Reg1testformat {
if (!empty($row->COL_GRIDSQUARE)) {
if(!array_key_exists($row->COL_GRIDSQUARE, $locators)){
$newlocator = true;
$distance = intval($CI->qra->distance($mylocator, $row->COL_GRIDSQUARE, "K"));
$distance = intval($CI->qra->distance($mylocator, $row->COL_GRIDSQUARE, "K", $row->COL_ANT_PATH));
$locators[$row->COL_GRIDSQUARE] = $distance;
}else{
$newlocator = false;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,271 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Migration_rename_satellites extends CI_Migration {
var $satellites = array(
'INSPIRE-SAT 7' => 'INSPR7',
'Lilacsat-1' => 'LO-90',
'TEVEL-1' => 'TEVEL1',
'TEVEL-2' => 'TEVEL2',
'TEVEL-3' => 'TEVEL3',
'TEVEL-4' => 'TEVEL4',
'TEVEL-5' => 'TEVEL5',
'TEVEL-6' => 'TEVEL6',
'TEVEL-7' => 'TEVEL7',
'TEVEL-8' => 'TEVEL8',
'UVSQ-SAT' => 'UVSQ',
);
var $lotw_sats = array(
'AISAT1',
'AO-10',
'AO-109',
'AO-13',
'AO-16',
'AO-21',
'AO-27',
'AO-3',
'AO-4',
'AO-40',
'AO-51',
'AO-6',
'AO-7',
'AO-73',
'AO-8',
'AO-85',
'AO-91',
'AO-92',
'ARISS',
'Arsene',
'BO-102',
'BY70-1',
'CAS-2T',
'CAS-3H',
'CAS-4A',
'CAS-4B',
'DO-64',
'EO-79',
'EO-88',
'FO-118',
'FO-12',
'FO-20',
'FO-29',
'FO-99',
'FS-3',
'HO-107',
'HO-113',
'HO-119',
'HO-68',
'INSPR7',
'IO-117',
'IO-86',
'JO-97',
'KEDR',
'LEDSAT',
'LO-19',
'LO-78',
'LO-87',
'LO-90',
'MAYA-3',
'MAYA-4',
'MIREX',
'MO-112',
'NO-103',
'NO-104',
'NO-44',
'NO-83',
'NO-84',
'PO-101',
'QO-100',
'RS-1',
'RS-10',
'RS-11',
'RS-12',
'RS-13',
'RS-15',
'RS-2',
'RS-44',
'RS-5',
'RS-6',
'RS-7',
'RS-8',
'SAREX',
'SO-121',
'SO-35',
'SO-41',
'SO-50',
'SO-67',
'TAURUS',
'TEVEL1',
'TEVEL2',
'TEVEL3',
'TEVEL4',
'TEVEL5',
'TEVEL6',
'TEVEL7',
'TEVEL8',
'TO-108',
'UKUBE1',
'UO-14',
'UVSQ',
'VO-52',
'XW-2A',
'XW-2B',
'XW-2C',
'XW-2D',
'XW-2E',
'XW-2F',
);
public function up() {
$this->add_ix('TMP_HRD_IDX_COL_SAT_NAME','`COL_SAT_NAME`');
if ($this->db->table_exists('satellite')) {
foreach ($this->satellites as $exportname => $name) {
$this->update_sat_table($exportname, $name);
$this->update_log_table($exportname, $name);
}
if (!$this->db->field_exists('lotw', 'satellite')) {
$fields = array(
'lotw VARCHAR(1) NOT NULL DEFAULT "N" AFTER `orbit`',
);
$this->dbforge->add_column('satellite', $fields);
}
$this->set_lotw($this->lotw_sats);
$query = $this->db->get_where('satellite', array('name' => 'SONATE'));
if ($query->num_rows() > 0) {
$this->set_lotw(array("SONATE"));
} else {
$this->insert_sat("SONATE", "SONATE-2", "LEO", "V/V", "PKT", "145825000", "PKT", "145825000", "Y");
}
$query = $this->db->get_where('satellite', array('name' => 'MO-122'));
if ($query->num_rows() > 0) {
$this->set_lotw(array("MO-122"));
} else {
$this->insert_sat("MO-122", "MESAT1", "LEO", "V/U", "LSB", "145925000", "USB", "435825000", "Y");
}
$query = $this->db->get_where('satellite', array('name' => 'ASRTU-1'));
if ($query->num_rows() > 0) {
$this->remove_sat("ASRTU-1");
}
$this->insert_sat("AO-123", "ASRTU-1", "LEO", "V/U", "FM", "145850000", "FM", "435400000", "N");
$this->update_log_table("ASRTU-1", "AO-123");
$fields = array(
'exportname' => array(
'name' => 'displayname',
'type' => 'VARCHAR',
'constraint' => 255,
),
);
$this->dbforge->modify_column('satellite', $fields);
}
$this->rm_ix('TMP_HRD_IDX_COL_SAT_NAME');
}
public function down() {
$this->add_ix('TMP_HRD_IDX_COL_SAT_NAME','`COL_SAT_NAME`');
if ($this->db->table_exists('satellite')) {
$fields = array(
'displayname' => array(
'name' => 'exportname',
'type' => 'VARCHAR',
'constraint' => 255,
),
);
$this->dbforge->modify_column('satellite', $fields);
foreach ($this->satellites as $exportname => $name) {
$this->update_sat_table($name, $exportname);
$this->update_log_table($name, $exportname);
}
}
if ($this->db->field_exists('lotw', 'satellite')) {
$this->dbforge->drop_column('satellite', 'lotw');
}
$this->remove_sat("SONATE");
$this->remove_sat("MO-122");
$this->rm_ix('TMP_HRD_IDX_COL_SAT_NAME');
}
function update_sat_table($from, $to) {
$sql= "UPDATE `satellite` SET `name` = '".$to."' WHERE `name` = '".$from."';";
$this->db->query($sql);
}
function update_log_table($from, $to) {
$sql= "UPDATE ".$this->config->item('table_name')." SET `COL_SAT_NAME` = '".$to."' WHERE `COL_SAT_NAME` = '".$from."';";
$this->db->query($sql);
}
function set_lotw($sats) {
$sql = "UPDATE `satellite` SET `lotw` = 'Y' WHERE `name` IN ('".implode('\',\'', $sats)."');";
$this->db->query($sql);
}
function insert_sat($name, $exportname, $orbit, $modename, $uplink_mode, $uplink_freq, $downlink_mode, $downlink_freq, $lotw) {
$data = array(
'name' => $name,
'exportname' => $exportname,
'lotw' => $lotw,
'orbit' => $orbit,
);
$this->db->where('name', $name);
$result = $this->db->get('satellite');
if ($result->num_rows() == 0) {
$this->db->insert('satellite', $data);
$insert_id = $this->db->insert_id();
$modedata = array(
'name' => $modename,
'satelliteid' => $insert_id,
'uplink_mode' => $uplink_mode,
'uplink_freq' => $uplink_freq,
'downlink_mode' => $downlink_mode,
'downlink_freq' => $downlink_freq,
);
$this->db->insert('satellitemode', $modedata);
}
}
function remove_sat($name) {
$this->db->select('id');
$this->db->where('name', $name);
$query = $this->db->get('satellite');
$ids = array();
foreach ($query->result() as $row) {
array_push($ids, $row->id);
}
$this->db->where_in('satelliteid', $ids);
$this->db->delete('satellitemode');
$this->db->where_in('id', $ids);
$this->db->delete('satellite');
}
private function add_ix($index,$cols) {
$ix_exist = $this->db->query("SHOW INDEX FROM ".$this->config->item('table_name')." WHERE Key_name = '".$index."'")->num_rows();
if ($ix_exist == 0) {
$sql = "ALTER TABLE ".$this->config->item('table_name')." ADD INDEX `".$index."` (".$cols.");";
$this->db->query($sql);
}
}
private function rm_ix($index) {
$ix_exist = $this->db->query("SHOW INDEX FROM ".$this->config->item('table_name')." WHERE Key_name = '".$index."'")->num_rows();
if ($ix_exist >= 1) {
$sql = "ALTER TABLE ".$this->config->item('table_name')." DROP INDEX `".$index."`;";
$this->db->query($sql);
}
}
}

Some files were not shown because too many files have changed in this diff Show More