Skip to content

Commit 1b944ea

Browse files
authored
2.7.7
2.7.7
2 parents 32505c1 + 2e7fb31 commit 1b944ea

16 files changed

Lines changed: 1033 additions & 144 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,6 @@ Thanks to Andy (VE7CXZ), Gavin (M1BXF), Graham (W5ISP), Robert (M0VFC), Corby (K
129129

130130
Cloudlog is supported by Patreon and donations via PayPal, thanks to the following people:
131131

132-
Paul (M0TZO), Tim (G4VXE), Paul (N8HM), Michelle (W5NYV), Mitchell (AD0HJ), Dan (M0TCB), Martin (DK3ML), Juan Carlos (EA5WA), Iain (M0PCB), Charlie (GM1TGY), Ondrej (OK1CDJ), Trystan (G0KAY), Oliver (DL6KBG), Volkmar Schirmer, Jordan (M0PIR), Thomas Ziegler, Mathis (DB9MAT), Ken (VE3HLS), Tyler (WL7T), Jeremy Taylor, Ben Kuhn, Eric Thresher, Michael Cullen, Juuso (OH1JW), Anthony Castiglia, Fernando Ramirez-Ferrer, Robert Dixon, Mark Percival, Julia (KV1V), Timo Tomasini, Ant (NU1U), Christopher Williams, Danny Barnes, Vic, Tom (M0LTE), smurphboy, Lars (SM0TGU), Theo (PD9DP), Stefan (SM0RGM). Peter (G0ABI), Lou (KI5FTY), Michael (DG3NAB), Dragan (4O4A), minorsecond, Emily (W7AYQ), Steve (M0SKM), Rob (M0VFC), Doug (WA6L), Petr (OK1PKR), Fabian (HB9HIL), Daniel (OK2VLK), John (M5JFS), Johnathan (2E0DEF), Peter (M0LNB)
132+
Paul (M0TZO), Tim (G4VXE), Paul (N8HM), Michelle (W5NYV), Mitchell (AD0HJ), Dan (M0TCB), Martin (DK3ML), Juan Carlos (EA5WA), Iain (M0PCB), Charlie (GM1TGY), Ondrej (OK1CDJ), Trystan (G0KAY), Oliver (DL6KBG), Volkmar Schirmer, Jordan (M0PIR), Thomas Ziegler, Mathis (DB9MAT), Ken (VE3HLS), Tyler (WL7T), Jeremy Taylor, Ben Kuhn, Eric Thresher, Michael Cullen, Juuso (OH1JW), Anthony Castiglia, Fernando Ramirez-Ferrer, Robert Dixon, Mark Percival, Julia (KV1V), Timo Tomasini, Ant (NU1U), Christopher Williams, Danny Barnes, Vic, Tom (M0LTE), smurphboy, Lars (SM0TGU), Theo (PD9DP), Stefan (SM0RGM). Peter (G0ABI), Lou (KI5FTY), Michael (DG3NAB), Dragan (4O4A), minorsecond, Emily (W7AYQ), Steve (M0SKM), Rob (M0VFC), Doug (WA6L), Petr (OK1PKR), Fabian (HB9HIL), Daniel (OK2VLK), John (M5JFS), Johnathan (2E0DEF), Peter (M0LNB), Bernard (EI8FDB).
133133

134-
If you'd like to donate to Cloudlog to help allow @magicbug spend less time doing commercial work and more time coding Cloudlog then you can donate via [PayPal](https://paypal.me/PGoodhall), [Github Sponsor](https://github.com/sponsors/magicbug) or become a [Patreon](https://www.patreon.com/MM9SQL)
134+
If you'd like to donate to Cloudlog to help allow @magicbug spend less time doing commercial work and more time coding Cloudlog then you can donate via [PayPal](https://paypal.me/PGoodhall), [Github Sponsor](https://github.com/sponsors/magicbug) or become a [Patreon](https://www.patreon.com/2m0sql)

application/config/migration.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
|
2323
*/
2424

25-
$config['migration_version'] = 231;
25+
$config['migration_version'] = 232;
2626

2727
/*
2828
|--------------------------------------------------------------------------

application/controllers/Logbookadvanced.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,79 @@ function update_qsl_received() {
244244
print json_encode($q);
245245
}
246246

247+
function update_station_location() {
248+
$this->load->model('logbookadvanced_model');
249+
250+
$ids = xss_clean($this->input->post('id'));
251+
$user_id = (int)$this->session->userdata('user_id');
252+
$station_id = xss_clean($this->input->post('station_id'));
253+
254+
$status = $this->logbookadvanced_model->updateStationLocation($ids, $user_id, $station_id);
255+
256+
$data = $this->logbookadvanced_model->getQsosForAdif($ids, $user_id);
257+
258+
$results = $data->result('array');
259+
260+
$qsos = [];
261+
foreach ($results as $data) {
262+
$qsos[] = new QSO($data);
263+
}
264+
265+
$q = [];
266+
foreach ($qsos as $qso) {
267+
$q[] = $qso->toArray();
268+
}
269+
270+
header("Content-Type: application/json");
271+
print json_encode($q);
272+
}
273+
274+
function update_satellite() {
275+
$this->load->model('logbookadvanced_model');
276+
277+
$ids = xss_clean($this->input->post('id'));
278+
$user_id = (int)$this->session->userdata('user_id');
279+
$sat_name = xss_clean($this->input->post('sat_name'));
280+
$sat_mode = xss_clean($this->input->post('sat_mode'));
281+
$uplink_freq = xss_clean($this->input->post('uplink_freq'));
282+
$downlink_freq = xss_clean($this->input->post('downlink_freq'));
283+
$uplink_mode = xss_clean($this->input->post('uplink_mode'));
284+
$downlink_mode = xss_clean($this->input->post('downlink_mode'));
285+
286+
$status = $this->logbookadvanced_model->updateSatellite($ids, $user_id, $sat_name, $sat_mode, $uplink_freq, $downlink_freq, $uplink_mode, $downlink_mode);
287+
288+
$data = $this->logbookadvanced_model->getQsosForAdif($ids, $user_id);
289+
290+
$results = $data->result('array');
291+
292+
$qsos = [];
293+
foreach ($results as $data) {
294+
$qsos[] = new QSO($data);
295+
}
296+
297+
$q = [];
298+
foreach ($qsos as $qso) {
299+
$q[] = $qso->toArray();
300+
}
301+
302+
header("Content-Type: application/json");
303+
print json_encode($q);
304+
}
305+
306+
public function selectSatellite() {
307+
$this->load->view('logbookadvanced/selectsatellite');
308+
}
309+
247310
public function startAtLabel() {
248311
$this->load->view('logbookadvanced/startatform');
249312
}
250313

314+
public function selectStationLocation() {
315+
$this->load->model('stations');
316+
$data['station_profile'] = $this->stations->all_of_user();
317+
$this->load->view('logbookadvanced/selectstationlocation', $data);
318+
}
319+
251320
public function qslSlideshow() {
252321
$cleanids = $this->security->xss_clean($this->input->post('ids'));
253322
$this->load->model('logbookadvanced_model');
@@ -465,6 +534,7 @@ public function setUserOptions() {
465534
$json_string['iota']['show'] = $this->input->post('iota');
466535
$json_string['pota']['show'] = $this->input->post('pota');
467536
$json_string['operator']['show'] = $this->input->post('operator');
537+
$json_string['stationLocation']['show'] = $this->input->post('stationLocation');
468538

469539
$obj['column_settings']= json_encode($json_string);
470540

application/migrations/018_clubloguserfields.php

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,33 @@ class Migration_clubloguserfields extends CI_Migration {
66

77
public function up()
88
{
9-
$user_fields = array(
10-
'user_clublog_name VARCHAR(255) DEFAULT NULL',
11-
'user_clublog_password VARCHAR(255) DEFAULT NULL',
12-
'user_clublog_callsign VARCHAR(255) DEFAULT NULL'
9+
// Check and add each field only if it does not exist
10+
$fields_to_add = array(
11+
'user_clublog_name' => array(
12+
'type' => 'VARCHAR',
13+
'constraint' => 255,
14+
'null' => TRUE,
15+
),
16+
'user_clublog_password' => array(
17+
'type' => 'VARCHAR',
18+
'constraint' => 255,
19+
'null' => TRUE,
20+
),
21+
'user_clublog_callsign' => array(
22+
'type' => 'VARCHAR',
23+
'constraint' => 255,
24+
'null' => TRUE,
25+
),
1326
);
14-
$this->dbforge->add_column('users', $user_fields);
27+
28+
// Get current columns in 'users' table
29+
$fields = $this->db->list_fields('users');
30+
31+
foreach ($fields_to_add as $field => $definition) {
32+
if (!in_array($field, $fields)) {
33+
$this->dbforge->add_column('users', array($field => $definition));
34+
}
35+
}
1536
}
1637

1738
public function down()
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
defined('BASEPATH') OR exit('No direct script access allowed');
4+
5+
/*
6+
* Tag Cloudlog as 2.7.7
7+
*/
8+
9+
class Migration_tag_2_7_7 extends CI_Migration {
10+
11+
public function up()
12+
{
13+
14+
// Tag Cloudlog 2.7.7
15+
$this->db->where('option_name', 'version');
16+
$this->db->update('options', array('option_value' => '2.7.7'));
17+
18+
// Trigger Version Info Dialog
19+
$this->db->where('option_type', 'version_dialog');
20+
$this->db->where('option_name', 'confirmed');
21+
$this->db->update('user_options', array('option_value' => 'false'));
22+
23+
}
24+
25+
public function down()
26+
{
27+
$this->db->where('option_name', 'version');
28+
$this->db->update('options', array('option_value' => '2.7.6'));
29+
}
30+
}

application/models/Logbookadvanced_model.php

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -392,16 +392,86 @@ public function updateQslReceived($ids, $user_id, $method, $sent) {
392392
}
393393
}
394394

395+
public function updateStationLocation($ids, $user_id, $station_id) {
396+
$this->load->model('user_model');
397+
398+
if(!$this->user_model->authorize(2)) {
399+
return array('message' => 'Error');
400+
} else {
401+
// Verify that the station_id belongs to the user
402+
$this->load->model('Stations');
403+
$stations = $this->Stations->all_of_user($user_id)->result();
404+
$valid_station = false;
405+
foreach ($stations as $station) {
406+
if ($station->station_id == $station_id) {
407+
$valid_station = true;
408+
break;
409+
}
410+
}
411+
412+
if (!$valid_station) {
413+
return array('message' => 'Invalid station ID');
414+
}
415+
416+
$data = array(
417+
'station_id' => $station_id
418+
);
419+
$this->db->where_in('COL_PRIMARY_KEY', json_decode($ids, true));
420+
$this->db->update($this->config->item('table_name'), $data);
421+
422+
return array('message' => 'OK');
423+
}
424+
}
425+
426+
public function updateSatellite($ids, $user_id, $sat_name, $sat_mode, $uplink_freq, $downlink_freq, $uplink_mode, $downlink_mode) {
427+
$this->load->model('user_model');
428+
429+
if(!$this->user_model->authorize(2)) {
430+
return array('message' => 'Error');
431+
} else {
432+
$this->load->library('frequency');
433+
434+
// Calculate bands from frequencies using existing Frequency library
435+
$uplink_band = $this->frequency->GetBand($uplink_freq);
436+
$downlink_band = $this->frequency->GetBand($downlink_freq);
437+
438+
// Determine mode based on uplink and downlink modes
439+
$mode = $uplink_mode;
440+
if (($uplink_mode == 'USB' && $downlink_mode == 'LSB') || ($uplink_mode == 'LSB' && $downlink_mode == 'USB')) {
441+
$mode = 'SSB';
442+
}
443+
444+
$data = array(
445+
'COL_SAT_NAME' => $sat_name,
446+
'COL_SAT_MODE' => $sat_mode,
447+
'COL_FREQ' => $uplink_freq,
448+
'COL_FREQ_RX' => $downlink_freq,
449+
'COL_BAND' => $uplink_band,
450+
'COL_BAND_RX' => $downlink_band,
451+
'COL_MODE' => $mode,
452+
'COL_PROP_MODE' => 'SAT'
453+
);
454+
455+
$this->db->where_in('COL_PRIMARY_KEY', json_decode($ids, true));
456+
$this->db->update($this->config->item('table_name'), $data);
457+
458+
return array('message' => 'OK');
459+
}
460+
}
461+
395462
public function updateQsoWithCallbookInfo($qsoID, $qso, $callbook) {
396463
$updatedData = array();
397464
if (!empty($callbook['name']) && empty($qso['COL_NAME'])) {
398465
$updatedData['COL_NAME'] = $callbook['name'];
399466
}
400467
if (!empty($callbook['gridsquare']) && empty($qso['COL_GRIDSQUARE']) && empty($qso['COL_VUCC_GRIDS'] )) {
401-
if (strpos(trim($callbook['gridsquare']), ',') === false) {
402-
$updatedData['COL_GRIDSQUARE'] = strtoupper(trim($callbook['gridsquare']));
403-
} else {
404-
$updatedData['COL_VUCC_GRIDS'] = strtoupper(trim($callbook['gridsquare']));
468+
// Validate gridsquare before adding - reject obvious invalid/placeholder values
469+
if ($this->isValidGridsquare($callbook['gridsquare'])) {
470+
if (strpos(trim($callbook['gridsquare']), ',') === false) {
471+
$updatedData['COL_GRIDSQUARE'] = strtoupper(trim($callbook['gridsquare']));
472+
} else {
473+
$updatedData['COL_VUCC_GRIDS'] = strtoupper(trim($callbook['gridsquare']));
474+
}
405475
}
406476
}
407477
if (!empty($callbook['city']) && empty($qso['COL_QTH'])) {
@@ -435,6 +505,52 @@ public function updateQsoWithCallbookInfo($qsoID, $qso, $callbook) {
435505
return false;
436506
}
437507

508+
/**
509+
* Validate gridsquare to reject obvious invalid/placeholder values
510+
* Returns false for gridsquares like AA00AA, JJ00JJ, etc. which are
511+
* commonly used as placeholders when the actual grid is unknown
512+
*/
513+
private function isValidGridsquare($gridsquare) {
514+
if (empty($gridsquare)) {
515+
return false;
516+
}
517+
518+
$gridsquare = strtoupper(trim($gridsquare));
519+
520+
// Handle multiple gridsquares (VUCC format)
521+
$grids = explode(',', $gridsquare);
522+
523+
foreach ($grids as $grid) {
524+
$grid = trim($grid);
525+
526+
// Must be valid length (4, 6, 8, or 10 characters)
527+
$len = strlen($grid);
528+
if ($len < 4 || $len > 10 || $len % 2 != 0) {
529+
return false;
530+
}
531+
532+
// Basic format validation
533+
if (!preg_match('/^[A-R]{2}[0-9]{2}([A-X]{2})?([0-9]{2})?([A-X]{2})?$/', $grid)) {
534+
return false;
535+
}
536+
537+
// Reject obvious placeholder patterns where field and subfield are identical
538+
// e.g., AA00AA, BB11BB, JJ00JJ etc.
539+
if ($len >= 6) {
540+
$field = substr($grid, 0, 2); // First 2 chars (e.g., "AA", "JJ")
541+
$subfield = substr($grid, 4, 2); // Chars 5-6 (e.g., "AA", "JJ")
542+
543+
// If both field letters are the same AND both subfield letters are the same
544+
// AND they match each other, it's likely a placeholder
545+
if ($field[0] === $field[1] && $subfield[0] === $subfield[1] && $field[0] === $subfield[0]) {
546+
return false;
547+
}
548+
}
549+
}
550+
551+
return true;
552+
}
553+
438554
function get_modes() {
439555
$CI =& get_instance();
440556
$CI->load->model('logbooks_model');

application/views/logbookadvanced/index.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
var custom_date_format = "<?php echo $custom_date_format ?>";
88
<?php
99
if (!isset($options)) {
10-
$options = "{\"datetime\":{\"show\":\"true\"},\"de\":{\"show\":\"true\"},\"dx\":{\"show\":\"true\"},\"mode\":{\"show\":\"true\"},\"rstr\":{\"show\":\"true\"},\"rsts\":{\"show\":\"true\"},\"band\":{\"show\":\"true\"},\"myrefs\":{\"show\":\"true\"},\"refs\":{\"show\":\"true\"},\"name\":{\"show\":\"true\"},\"qslvia\":{\"show\":\"true\"},\"qsl\":{\"show\":\"true\"},\"lotw\":{\"show\":\"true\"},\"eqsl\":{\"show\":\"true\"},\"qslmsg\":{\"show\":\"true\"},\"dxcc\":{\"show\":\"true\"},\"state\":{\"show\":\"true\"},\"cqzone\":{\"show\":\"true\"},\"iota\":{\"show\":\"true\"},\"pota\":{\"show\":\"true\"},\"operator\":{\"show\":\"true\"}}";
10+
$options = "{\"datetime\":{\"show\":\"true\"},\"de\":{\"show\":\"true\"},\"dx\":{\"show\":\"true\"},\"mode\":{\"show\":\"true\"},\"rstr\":{\"show\":\"true\"},\"rsts\":{\"show\":\"true\"},\"band\":{\"show\":\"true\"},\"myrefs\":{\"show\":\"true\"},\"refs\":{\"show\":\"true\"},\"name\":{\"show\":\"true\"},\"qslvia\":{\"show\":\"true\"},\"qsl\":{\"show\":\"true\"},\"lotw\":{\"show\":\"true\"},\"eqsl\":{\"show\":\"true\"},\"qslmsg\":{\"show\":\"true\"},\"dxcc\":{\"show\":\"true\"},\"state\":{\"show\":\"true\"},\"cqzone\":{\"show\":\"true\"},\"iota\":{\"show\":\"true\"},\"pota\":{\"show\":\"true\"},\"operator\":{\"show\":\"true\"},\"stationLocation\":{\"show\":\"true\"}}";
1111
}
1212
echo "var user_options = $options;";
1313
if (!isset($options->pota)) {
@@ -18,6 +18,10 @@
1818
echo "\nvar o_template = { operator: {show: 'true'}};";
1919
echo "\nuser_options={...user_options, ...o_template}";
2020
}
21+
if (!isset($options->stationLocation)) {
22+
echo "\nvar o_template = { stationLocation: {show: 'true'}};";
23+
echo "\nuser_options={...user_options, ...o_template}";
24+
}
2125
?>
2226
</script>
2327
<script>
@@ -329,6 +333,8 @@
329333
<div class="mb-2 btn-group">
330334
<span class="h6 me-1"><?php echo lang('filter_actions_w_selected'); ?></span>
331335
<button type="button" class="btn btn-sm btn-primary me-1" id="btnUpdateFromCallbook"><?php echo lang('filter_actions_update_f_callbook'); ?></button>
336+
<button type="button" class="btn btn-sm btn-primary me-1" id="changeStationLocation">Change Station Location</button>
337+
<button type="button" class="btn btn-sm btn-primary me-1" id="changeSatellite">Assign Satellite</button>
332338
<button type="button" class="btn btn-sm btn-primary me-1" id="queueBureau"><?php echo lang('filter_actions_queue_bureau'); ?></button>
333339
<button type="button" class="btn btn-sm btn-primary me-1" id="queueDirect"><?php echo lang('filter_actions_queue_direct'); ?></button>
334340
<button type="button" class="btn btn-sm btn-primary me-1" id="queueElectronic"><?php echo lang('filter_actions_queue_electronic'); ?></button>
@@ -425,6 +431,9 @@
425431
<?php if (($options->de->show ?? "true") == "true") {
426432
echo '<th>' . lang('gen_hamradio_de') . '</th>';
427433
} ?>
434+
<?php if (($options->stationLocation->show ?? "true") == "true") {
435+
echo '<th>Station Location</th>';
436+
} ?>
428437
<?php if (($options->dx->show ?? "true") == "true") {
429438
echo '<th>' . lang('gen_hamradio_dx') . '</th>';
430439
} ?>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<form method="post" class="col-md">
2+
<div class="mb-3 row">
3+
<label class="my-1 me-2 col-md-4" for="sat_name_select">Satellite Name:</label>
4+
<div class="col-md-8">
5+
<input list="satellite_names_bulk" id="sat_name_select" type="text" name="sat_name_select" class="form-control" placeholder="Select satellite...">
6+
<datalist id="satellite_names_bulk" class="satellite_names_list_bulk"></datalist>
7+
</div>
8+
</div>
9+
<div class="mb-3 row">
10+
<label class="my-1 me-2 col-md-4" for="sat_mode_select">Satellite Mode:</label>
11+
<div class="col-md-8">
12+
<input list="satellite_modes_bulk" id="sat_mode_select" type="text" name="sat_mode_select" class="form-control" placeholder="Select mode...">
13+
<datalist id="satellite_modes_bulk" class="satellite_modes_list_bulk"></datalist>
14+
</div>
15+
</div>
16+
<input type="hidden" id="uplink_freq_hidden" name="uplink_freq_hidden" value="">
17+
<input type="hidden" id="downlink_freq_hidden" name="downlink_freq_hidden" value="">
18+
<input type="hidden" id="uplink_mode_hidden" name="uplink_mode_hidden" value="">
19+
<input type="hidden" id="downlink_mode_hidden" name="downlink_mode_hidden" value="">
20+
</form>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<form method="post" class="col-md">
2+
<div class="mb-3 row">
3+
<label class="my-1 me-2 col-md-4" for="station_id_select">Station Location:</label>
4+
<div class="col-md-8">
5+
<select class="form-select" id="station_id_select" name="station_id_select">
6+
<option value="">-- Select Station Location --</option>
7+
<?php foreach($station_profile->result() as $station) { ?>
8+
<option value="<?php echo $station->station_id; ?>">
9+
<?php echo $station->station_callsign; ?> - <?php echo $station->station_profile_name; ?>
10+
</option>
11+
<?php } ?>
12+
</select>
13+
</div>
14+
</div>
15+
</form>

0 commit comments

Comments
 (0)