Add Most Worked Callsigns feature

Introduces a new 'Most Worked Callsigns' page, controller, model, and view to display callsigns worked multiple times from the active logbook. Adds language support for this feature in multiple languages and updates the navigation menu to include a link to the new page. Also includes DataTables integration and filter options for bands, modes, satellites, date range, and minimum QSOs.
WillItBreak
Peter Goodhall 2025-08-23 21:11:36 +01:00
rodzic a89b04966e
commit 76f55f7f27
37 zmienionych plików z 630 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,58 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Mostworked extends CI_Controller {
function __construct()
{
parent::__construct();
$this->load->model('user_model');
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); }
// Load language files
$this->lang->load('most_worked');
}
public function index()
{
// Check if users logged in
if ($this->user_model->validate_session() == 0) {
// user is not logged in
redirect('user/login');
}
$this->load->model('mostworked_model');
$this->load->model('logbooks_model');
// Get filter parameters
$filters = array(
'band' => $this->input->post('band') ?: 'all',
'mode' => $this->input->post('mode') ?: 'all',
'satellite' => $this->input->post('satellite') ?: 'all',
'fromdate' => $this->input->post('fromdate') ?: '',
'todate' => $this->input->post('todate') ?: '',
'min_qsos' => $this->input->post('min_qsos') ?: 5
);
// Get active station logbook
$logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
if (!$logbooks_locations_array) {
$data['mostworked_callsigns'] = array();
} else {
$data['mostworked_callsigns'] = $this->mostworked_model->get_most_worked_callsigns($filters);
}
// Get filter dropdown data
$data['bands'] = $this->mostworked_model->get_bands();
$data['modes'] = $this->mostworked_model->get_modes();
$data['satellites'] = $this->mostworked_model->get_satellites();
$data['filters'] = $filters;
$data['page_title'] = "Most Worked Callsigns";
$this->load->view('interface_assets/header', $data);
$this->load->view('mostworked/index', $data);
$this->load->view('interface_assets/footer');
}
}

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Days with QSOs';
$lang['menu_timeline'] = 'Timeline';
$lang['menu_accumulated_statistics'] = 'Accumulated Statistics';
$lang['menu_timeplotter'] = 'Timeplotter';
$lang['menu_most_worked'] = 'Най-Работени';
$lang['menu_custom_maps'] = 'Custom Maps';
$lang['menu_continents'] = 'Continents';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Най-Работени Позивни';
$lang['most_worked_description'] = 'Тази страница показва позивните, с които сте работили най-често от вашия активен дневник.';
$lang['most_worked_rank'] = 'Ранг';
$lang['most_worked_callsign'] = 'Позивен';
$lang['most_worked_contacts'] = 'Контакти';
$lang['most_worked_first_qso'] = 'Първо QSO';
$lang['most_worked_last_qso'] = 'Последно QSO';
$lang['most_worked_bands'] = 'Ленти';
$lang['most_worked_modes'] = 'Режими';
$lang['most_worked_no_data'] = 'Няма намерени QSO! Уверете се, че имате избран активен дневник и записани QSO.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = '天数';
$lang['menu_timeline'] = '时间线';
$lang['menu_accumulated_statistics'] = '累积统计';
$lang['menu_timeplotter'] = '时间图';
$lang['menu_most_worked'] = '最常工作';
$lang['menu_custom_maps'] = '自定义地图';
$lang['menu_continents'] = '大陆';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = '最常工作的呼号';
$lang['most_worked_description'] = '此页面显示您从活动日志簿中最频繁工作的呼号。';
$lang['most_worked_rank'] = '排名';
$lang['most_worked_callsign'] = '呼号';
$lang['most_worked_contacts'] = '联系';
$lang['most_worked_first_qso'] = '首次QSO';
$lang['most_worked_last_qso'] = '最后QSO';
$lang['most_worked_bands'] = '频段';
$lang['most_worked_modes'] = '模式';
$lang['most_worked_no_data'] = '未找到QSO请确保您已选择活动日志簿并记录了QSO。';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Dny s QSO';
$lang['menu_timeline'] = 'Časová osa';
$lang['menu_accumulated_statistics'] = 'Kumulativní statistiky';
$lang['menu_timeplotter'] = 'Graf času';
$lang['menu_most_worked'] = 'Nejvíce Pracované';
$lang['menu_custom_maps'] = 'Vlastní mapy';
$lang['menu_continents'] = 'Kontinenty';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Nejvíce Pracované Značky';
$lang['most_worked_description'] = 'Tato stránka zobrazuje značky, se kterými jste pracovali nejčastěji z vašeho aktivního deníku.';
$lang['most_worked_rank'] = 'Pořadí';
$lang['most_worked_callsign'] = 'Značka';
$lang['most_worked_contacts'] = 'Kontakty';
$lang['most_worked_first_qso'] = 'První QSO';
$lang['most_worked_last_qso'] = 'Poslední QSO';
$lang['most_worked_bands'] = 'Pásma';
$lang['most_worked_modes'] = 'Režimy';
$lang['most_worked_no_data'] = 'Nebyly nalezeny žádné QSO! Ujistěte se, že máte vybraný aktivní deník a zaznamenané QSO.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Days with QSOs';
$lang['menu_timeline'] = 'Timeline';
$lang['menu_accumulated_statistics'] = 'Accumulated Statistics';
$lang['menu_timeplotter'] = 'Timeplotter';
$lang['menu_most_worked'] = 'Meest Gewerkt';
$lang['menu_custom_maps'] = 'Custom Maps';
$lang['menu_continents'] = 'Continents';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Meest Gewerkte Roepletters';
$lang['most_worked_description'] = 'Deze pagina toont de roepletters waarmee u het vaakst heeft gewerkt vanuit uw actieve logboek.';
$lang['most_worked_rank'] = 'Rang';
$lang['most_worked_callsign'] = 'Roepletter';
$lang['most_worked_contacts'] = 'Contacten';
$lang['most_worked_first_qso'] = 'Eerste QSO';
$lang['most_worked_last_qso'] = 'Laatste QSO';
$lang['most_worked_bands'] = 'Banden';
$lang['most_worked_modes'] = 'Modi';
$lang['most_worked_no_data'] = 'Geen QSO\'s gevonden! Zorg ervoor dat u een actief logboek hebt geselecteerd en QSO\'s hebt gelogd.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Days with QSOs';
$lang['menu_timeline'] = 'Timeline';
$lang['menu_accumulated_statistics'] = 'Accumulated Statistics';
$lang['menu_timeplotter'] = 'Timeplotter';
$lang['menu_most_worked'] = 'Most Worked';
$lang['menu_custom_maps'] = 'Custom Maps';
$lang['menu_continents'] = 'Continents';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Most Worked Callsigns';
$lang['most_worked_description'] = 'This page shows the callsigns you have worked most frequently from your active logbook.';
$lang['most_worked_rank'] = 'Rank';
$lang['most_worked_callsign'] = 'Callsign';
$lang['most_worked_contacts'] = 'Contacts';
$lang['most_worked_first_qso'] = 'First QSO';
$lang['most_worked_last_qso'] = 'Last QSO';
$lang['most_worked_bands'] = 'Bands';
$lang['most_worked_modes'] = 'Modes';
$lang['most_worked_no_data'] = 'No QSOs found! Make sure you have an active logbook selected and QSOs logged.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'QSO:llsia päiviä';
$lang['menu_timeline'] = 'Aikajana';
$lang['menu_accumulated_statistics'] = 'Kertyneet tilastot';
$lang['menu_timeplotter'] = 'Aikajana';
$lang['menu_most_worked'] = 'Eniten Työskennellyt';
$lang['menu_custom_maps'] = 'Custom Maps';
$lang['menu_continents'] = 'Mantereet';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Eniten Työskennellyt Kutsumerkit';
$lang['most_worked_description'] = 'Tämä sivu näyttää kutsumerkit, joiden kanssa olet työskennellyt useimmin aktiivisesta lokikirjastasi.';
$lang['most_worked_rank'] = 'Sijoitus';
$lang['most_worked_callsign'] = 'Kutsumerkki';
$lang['most_worked_contacts'] = 'Yhteydet';
$lang['most_worked_first_qso'] = 'Ensimmäinen QSO';
$lang['most_worked_last_qso'] = 'Viimeinen QSO';
$lang['most_worked_bands'] = 'Kaistat';
$lang['most_worked_modes'] = 'Tilat';
$lang['most_worked_no_data'] = 'QSO:ja ei löytynyt! Varmista, että sinulla on aktiivinen lokikirja valittuna ja QSO:ja kirjattuna.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Days with QSOs';
$lang['menu_timeline'] = 'Timeline';
$lang['menu_accumulated_statistics'] = 'Accumulated Statistics';
$lang['menu_timeplotter'] = 'Timeplotter';
$lang['menu_most_worked'] = 'Plus Travaillé';
$lang['menu_custom_maps'] = 'Custom Maps';
$lang['menu_continents'] = 'Continents';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Indicatifs les Plus Travaillés';
$lang['most_worked_description'] = 'Cette page affiche les indicatifs que vous avez travaillés le plus fréquemment de votre carnet de trafic actif.';
$lang['most_worked_rank'] = 'Rang';
$lang['most_worked_callsign'] = 'Indicatif';
$lang['most_worked_contacts'] = 'Contacts';
$lang['most_worked_first_qso'] = 'Premier QSO';
$lang['most_worked_last_qso'] = 'Dernier QSO';
$lang['most_worked_bands'] = 'Bandes';
$lang['most_worked_modes'] = 'Modes';
$lang['most_worked_no_data'] = 'Aucun QSO trouvé ! Assurez-vous d\'avoir un carnet de trafic actif sélectionné et des QSO enregistrés.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Tage mit QSOs';
$lang['menu_timeline'] = 'Zeitleiste';
$lang['menu_accumulated_statistics'] = 'Kumulierte Statistiken';
$lang['menu_timeplotter'] = 'Zeitplotter';
$lang['menu_most_worked'] = 'Meist Gearbeitet';
$lang['menu_custom_maps'] = 'Benutzerdefinierte Karte';
$lang['menu_continents'] = 'Kontinente';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Meist Gearbeitete Rufzeichen';
$lang['most_worked_description'] = 'Diese Seite zeigt die Rufzeichen, die Sie am häufigsten aus Ihrem aktiven Logbuch gearbeitet haben.';
$lang['most_worked_rank'] = 'Rang';
$lang['most_worked_callsign'] = 'Rufzeichen';
$lang['most_worked_contacts'] = 'Kontakte';
$lang['most_worked_first_qso'] = 'Erstes QSO';
$lang['most_worked_last_qso'] = 'Letztes QSO';
$lang['most_worked_bands'] = 'Bänder';
$lang['most_worked_modes'] = 'Modi';
$lang['most_worked_no_data'] = 'Keine QSOs gefunden! Stellen Sie sicher, dass Sie ein aktives Logbuch ausgewählt haben und QSOs protokolliert sind.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Days with QSOs';
$lang['menu_timeline'] = 'Timeline';
$lang['menu_accumulated_statistics'] = 'Accumulated Statistics';
$lang['menu_timeplotter'] = 'Timeplotter';
$lang['menu_most_worked'] = 'Περισσότερα Εργασμένα';
$lang['menu_custom_maps'] = 'Custom Maps';
$lang['menu_continents'] = 'Continents';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Περισσότερα Εργασμένα Διακριτικά';
$lang['most_worked_description'] = 'Αυτή η σελίδα δείχνει τα διακριτικά που έχετε εργαστεί πιο συχνά από το ενεργό σας ημερολόγιο.';
$lang['most_worked_rank'] = 'Κατάταξη';
$lang['most_worked_callsign'] = 'Διακριτικό';
$lang['most_worked_contacts'] = 'Επαφές';
$lang['most_worked_first_qso'] = 'Πρώτο QSO';
$lang['most_worked_last_qso'] = 'Τελευταίο QSO';
$lang['most_worked_bands'] = 'Ζώνες';
$lang['most_worked_modes'] = 'Τρόποι';
$lang['most_worked_no_data'] = 'Δεν βρέθηκαν QSO! Βεβαιωθείτε ότι έχετε επιλέξει ενεργό ημερολόγιο και καταγεγραμμένα QSO.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Giorni con QSO';
$lang['menu_timeline'] = 'Cronologia';
$lang['menu_accumulated_statistics'] = 'Statistiche accumulate';
$lang['menu_timeplotter'] = 'Plotter temporale';
$lang['menu_most_worked'] = 'Più Lavorato';
$lang['menu_custom_maps'] = 'Mappe personalizzate';
$lang['menu_continents'] = 'Continenti';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Nominativi Più Lavorati';
$lang['most_worked_description'] = 'Questa pagina mostra i nominativi con cui hai lavorato più frequentemente dal tuo logbook attivo.';
$lang['most_worked_rank'] = 'Posizione';
$lang['most_worked_callsign'] = 'Nominativo';
$lang['most_worked_contacts'] = 'Contatti';
$lang['most_worked_first_qso'] = 'Primo QSO';
$lang['most_worked_last_qso'] = 'Ultimo QSO';
$lang['most_worked_bands'] = 'Bande';
$lang['most_worked_modes'] = 'Modi';
$lang['most_worked_no_data'] = 'Nessun QSO trovato! Assicurati di aver selezionato un logbook attivo e di aver registrato dei QSO.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Dni z QSO';
$lang['menu_timeline'] = 'Oś czasu';
$lang['menu_accumulated_statistics'] = 'Skumulowane statystyki';
$lang['menu_timeplotter'] = 'Ploter czasu';
$lang['menu_most_worked'] = 'Najczęściej Pracowane';
$lang['menu_custom_maps'] = 'Niestandardowe mapy';
$lang['menu_continents'] = 'Kontynenty';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Najczęściej Pracowane Znaki';
$lang['most_worked_description'] = 'Ta strona pokazuje znaki, z którymi pracowałeś najczęściej z twojego aktywnego dziennika.';
$lang['most_worked_rank'] = 'Pozycja';
$lang['most_worked_callsign'] = 'Znak';
$lang['most_worked_contacts'] = 'Kontakty';
$lang['most_worked_first_qso'] = 'Pierwsze QSO';
$lang['most_worked_last_qso'] = 'Ostatnie QSO';
$lang['most_worked_bands'] = 'Pasma';
$lang['most_worked_modes'] = 'Tryby';
$lang['most_worked_no_data'] = 'Nie znaleziono QSO! Upewnij się, że masz wybrany aktywny dziennik i zarejestrowane QSO.';

Wyświetl plik

@ -31,6 +31,7 @@ $lang['menu_days_with_qsos'] = 'Dias com QSOs';
$lang['menu_timeline'] = 'Linha do Tempo';
$lang['menu_accumulated_statistics'] = 'Estatísticas Acumuladas';
$lang['menu_timeplotter'] = 'Gráfico Temporal';
$lang['menu_most_worked'] = 'Mais Trabalhado';
$lang['menu_custom_maps'] = 'Mapas Personalizados';
$lang['menu_continents'] = 'Continentes';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Indicativos Mais Trabalhados';
$lang['most_worked_description'] = 'Esta página mostra os indicativos com os quais você trabalhou com mais frequência a partir do seu livro de registro ativo.';
$lang['most_worked_rank'] = 'Posição';
$lang['most_worked_callsign'] = 'Indicativo';
$lang['most_worked_contacts'] = 'Contatos';
$lang['most_worked_first_qso'] = 'Primeiro QSO';
$lang['most_worked_last_qso'] = 'Último QSO';
$lang['most_worked_bands'] = 'Bandas';
$lang['most_worked_modes'] = 'Modos';
$lang['most_worked_no_data'] = 'Nenhum QSO encontrado! Certifique-se de ter um livro de registro ativo selecionado e QSOs registrados.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Дней с QSO';
$lang['menu_timeline'] = 'Лента событий';
$lang['menu_accumulated_statistics'] = 'Объединённая статистика';
$lang['menu_timeplotter'] = 'Графики';
$lang['menu_most_worked'] = 'Самые Работанные';
$lang['menu_custom_maps'] = 'Карты';
$lang['menu_continents'] = 'Континенты';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Самые Работанные Позывные';
$lang['most_worked_description'] = 'Эта страница показывает позывные, с которыми вы работали чаще всего из вашего активного журнала.';
$lang['most_worked_rank'] = 'Ранг';
$lang['most_worked_callsign'] = 'Позывной';
$lang['most_worked_contacts'] = 'Контакты';
$lang['most_worked_first_qso'] = 'Первое QSO';
$lang['most_worked_last_qso'] = 'Последнее QSO';
$lang['most_worked_bands'] = 'Диапазоны';
$lang['most_worked_modes'] = 'Режимы';
$lang['most_worked_no_data'] = 'QSO не найдены! Убедитесь, что у вас выбран активный журнал и записаны QSO.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Días con QSOs';
$lang['menu_timeline'] = 'Línea de Tiempo';
$lang['menu_accumulated_statistics'] = 'Estadísticas Acumuladas';
$lang['menu_timeplotter'] = 'Gráfico de Tiempo';
$lang['menu_most_worked'] = 'Más Trabajado';
$lang['menu_custom_maps'] = 'Mapas Personalizados';
$lang['menu_continents'] = 'Continentes';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Indicativos Más Trabajados';
$lang['most_worked_description'] = 'Esta página muestra los indicativos que has trabajado con más frecuencia desde tu libro de guardia activo.';
$lang['most_worked_rank'] = 'Rango';
$lang['most_worked_callsign'] = 'Indicativo';
$lang['most_worked_contacts'] = 'Contactos';
$lang['most_worked_first_qso'] = 'Primer QSO';
$lang['most_worked_last_qso'] = 'Último QSO';
$lang['most_worked_bands'] = 'Bandas';
$lang['most_worked_modes'] = 'Modos';
$lang['most_worked_no_data'] = '¡No se encontraron QSOs! Asegúrate de tener un libro de guardia activo seleccionado y QSOs registrados.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = 'Dagar med QSOs';
$lang['menu_timeline'] = 'Tidslinje';
$lang['menu_accumulated_statistics'] = 'Ackumulerad statistik';
$lang['menu_timeplotter'] = 'Tidplotter';
$lang['menu_most_worked'] = 'Mest Arbetade';
$lang['menu_custom_maps'] = 'Anpassade kartor';
$lang['menu_continents'] = 'Kontinenter';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'Mest Arbetade Anropssignaler';
$lang['most_worked_description'] = 'Den här sidan visar de anropssignaler du har arbetat med oftast från din aktiva loggbok.';
$lang['most_worked_rank'] = 'Rang';
$lang['most_worked_callsign'] = 'Anropssignal';
$lang['most_worked_contacts'] = 'Kontakter';
$lang['most_worked_first_qso'] = 'Första QSO';
$lang['most_worked_last_qso'] = 'Senaste QSO';
$lang['most_worked_bands'] = 'Band';
$lang['most_worked_modes'] = 'Lägen';
$lang['most_worked_no_data'] = 'Inga QSO hittades! Se till att du har en aktiv loggbok vald och QSO loggade.';

Wyświetl plik

@ -32,6 +32,7 @@ $lang['menu_days_with_qsos'] = "QSO'lu Günler";
$lang['menu_timeline'] = 'Zaman Çizelgesi';
$lang['menu_accumulated_statistics'] = 'Birikmiş İstatistikler';
$lang['menu_timeplotter'] = 'Zaman Çizici';
$lang['menu_most_worked'] = 'En Çok Çalışılan';
$lang['menu_custom_maps'] = 'Özel Haritalar';
$lang['menu_continents'] = 'Kıtalar';

Wyświetl plik

@ -0,0 +1,12 @@
<?php
$lang['most_worked_title'] = 'En Çok Çalışılan Çağrı İşaretleri';
$lang['most_worked_description'] = 'Bu sayfa, aktif günlük defterinizden en sık çalıştığınız çağrı işaretlerini gösterir.';
$lang['most_worked_rank'] = 'Sıra';
$lang['most_worked_callsign'] = 'Çağrı İşareti';
$lang['most_worked_contacts'] = 'İletişimler';
$lang['most_worked_first_qso'] = 'İlk QSO';
$lang['most_worked_last_qso'] = 'Son QSO';
$lang['most_worked_bands'] = 'Bantlar';
$lang['most_worked_modes'] = 'Modlar';
$lang['most_worked_no_data'] = 'QSO bulunamadı! Aktif bir günlük defteri seçtiğinizden ve QSO\'lar kaydettiğinizden emin olun.';

Wyświetl plik

@ -0,0 +1,206 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Mostworked_model extends CI_Model
{
/*
* Get callsigns worked more than a minimum number of times from the active logbook
*/
function get_most_worked_callsigns($filters = array())
{
$CI =& get_instance();
$CI->load->model('logbooks_model');
$logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
if (!$logbooks_locations_array) {
return array();
}
$location_list = "'" . implode("','", $logbooks_locations_array) . "'";
// Set defaults
$min_qsos = isset($filters['min_qsos']) ? intval($filters['min_qsos']) : 5;
$band = isset($filters['band']) ? $filters['band'] : 'all';
$mode = isset($filters['mode']) ? $filters['mode'] : 'all';
$satellite = isset($filters['satellite']) ? $filters['satellite'] : 'all';
$fromdate = isset($filters['fromdate']) ? $filters['fromdate'] : '';
$todate = isset($filters['todate']) ? $filters['todate'] : '';
$sql = "SELECT
col_call as callsign,
COUNT(*) as contact_count,
MIN(col_time_on) as first_qso,
MAX(col_time_on) as last_qso,
GROUP_CONCAT(DISTINCT col_band ORDER BY col_band) as bands,
GROUP_CONCAT(DISTINCT COALESCE(col_submode, col_mode) ORDER BY col_mode) as modes
FROM " . $this->config->item('table_name') . "
WHERE station_id IN (" . $location_list . ")
AND col_call IS NOT NULL
AND col_call != ''";
// Apply filters
if ($band != 'all') {
if ($band == 'SAT') {
$sql .= " AND col_prop_mode = 'SAT'";
} else {
$sql .= " AND col_band = '" . $this->db->escape_str($band) . "'";
$sql .= " AND (col_prop_mode != 'SAT' OR col_prop_mode IS NULL)";
}
}
if ($mode != 'all') {
$sql .= " AND (col_mode = '" . $this->db->escape_str($mode) . "' OR col_submode = '" . $this->db->escape_str($mode) . "')";
}
if ($satellite != 'all') {
$sql .= " AND col_sat_name = '" . $this->db->escape_str($satellite) . "'";
}
if (!empty($fromdate)) {
$sql .= " AND DATE(col_time_on) >= '" . $this->db->escape_str($fromdate) . "'";
}
if (!empty($todate)) {
$sql .= " AND DATE(col_time_on) <= '" . $this->db->escape_str($todate) . "'";
}
$sql .= " GROUP BY col_call
HAVING contact_count >= " . $min_qsos . "
ORDER BY contact_count DESC, col_call ASC";
$query = $this->db->query($sql);
return $query->result();
}
/*
* Get list of modes from the active logbook
*/
function get_modes()
{
$CI =& get_instance();
$CI->load->model('logbooks_model');
$logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
if (!$logbooks_locations_array) {
return array();
}
$location_list = "'" . implode("','", $logbooks_locations_array) . "'";
$sql = "SELECT DISTINCT COALESCE(col_submode, col_mode) as mode
FROM " . $this->config->item('table_name') . "
WHERE station_id IN (" . $location_list . ")
AND COALESCE(col_submode, col_mode) IS NOT NULL
AND COALESCE(col_submode, col_mode) != ''
ORDER BY mode";
$query = $this->db->query($sql);
return $query->result();
}
/*
* Get list of satellites from the active logbook
*/
function get_satellites()
{
$CI =& get_instance();
$CI->load->model('logbooks_model');
$logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
if (!$logbooks_locations_array) {
return array();
}
$location_list = "'" . implode("','", $logbooks_locations_array) . "'";
$sql = "SELECT DISTINCT col_sat_name as satellite
FROM " . $this->config->item('table_name') . "
WHERE station_id IN (" . $location_list . ")
AND col_sat_name IS NOT NULL
AND col_sat_name != ''
ORDER BY col_sat_name";
$query = $this->db->query($sql);
return $query->result();
}
/*
* Get list of bands from the active logbook
*/
function get_bands()
{
$CI =& get_instance();
$CI->load->model('logbooks_model');
$logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
if (!$logbooks_locations_array) {
return array();
}
$location_list = "'" . implode("','", $logbooks_locations_array) . "'";
$sql = "SELECT DISTINCT col_band as band
FROM " . $this->config->item('table_name') . "
WHERE station_id IN (" . $location_list . ")
AND col_band IS NOT NULL
AND col_band != ''
AND (col_prop_mode != 'SAT' OR col_prop_mode IS NULL)
ORDER BY
CASE col_band
WHEN '160m' THEN 1
WHEN '80m' THEN 2
WHEN '60m' THEN 3
WHEN '40m' THEN 4
WHEN '30m' THEN 5
WHEN '20m' THEN 6
WHEN '17m' THEN 7
WHEN '15m' THEN 8
WHEN '12m' THEN 9
WHEN '10m' THEN 10
WHEN '6m' THEN 11
WHEN '4m' THEN 12
WHEN '2m' THEN 13
WHEN '1.25m' THEN 14
WHEN '70cm' THEN 15
ELSE 999
END, col_band";
$query = $this->db->query($sql);
$results = array();
foreach($query->result() as $row) {
$results[] = $row->band;
}
return $results;
}
/*
* Get detailed contact information for a specific callsign
*/
function get_callsign_details($callsign)
{
$CI =& get_instance();
$CI->load->model('logbooks_model');
$logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
if (!$logbooks_locations_array) {
return array();
}
$location_list = "'" . implode("','", $logbooks_locations_array) . "'";
$this->db->select('col_time_on, col_band, col_mode, col_submode, col_rst_sent, col_rst_rcvd, col_country, col_qsl_sent, col_qsl_rcvd');
$this->db->from($this->config->item('table_name'));
$this->db->where('station_id IN (' . $location_list . ')', NULL, FALSE);
$this->db->where('col_call', $callsign);
$this->db->order_by('col_time_on', 'DESC');
$query = $this->db->get();
return $query->result();
}
}

Wyświetl plik

@ -158,6 +158,31 @@ if ($this->session->userdata('user_id') != null) {
<script type="text/javascript" src="<?php echo base_url(); ?>assets/js/buttons.html5.min.js"></script>
<script type="text/javascript" src="<?php echo base_url(); ?>assets/js/selectize.js"></script>
<?php if ($this->uri->segment(1) == "mostworked") { ?>
<script>
$(document).ready(function() {
$('#mostworked_table').DataTable({
"pageLength": 25,
"responsive": true,
"order": [[ 0, "asc" ]],
"columnDefs": [
{ "orderable": false, "targets": 0 },
{ "type": "num", "targets": 2 }
],
"language": {
url: getDataTablesLanguageUrl()
}
});
// Clear filters button
$('#clear_filters').click(function() {
$('#mostworked_filter_form')[0].reset();
$('#mostworked_filter_form').submit();
});
});
</script>
<?php } ?>
<?php if ($this->uri->segment(1) == "station") { ?>
<script language="javascript" src="<?php echo base_url(); ?>assets/js/HamGridSquare.js"></script>
<script src="<?php echo base_url(); ?>assets/js/sections/station_locations.js"></script>

Wyświetl plik

@ -133,6 +133,8 @@
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="<?php echo site_url('timeplotter'); ?>" title="View time when worked"><i class="fas fa-chart-bar"></i> <?php echo lang('menu_timeplotter'); ?></a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="<?php echo site_url('mostworked'); ?>" title="Most Worked Callsigns"><i class="fas fa-address-book"></i> <?php echo lang('menu_most_worked'); ?></a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="<?php echo site_url('map/custom'); ?>" title="Custom Maps of QSOs"><i class="fas fa-map"></i> <?php echo lang('menu_custom_maps'); ?></a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="<?php echo site_url('continents'); ?>" title="Continents"><i class="fas fa-globe-europe"></i> <?php echo lang('menu_continents'); ?></a>

Wyświetl plik

@ -0,0 +1,131 @@
<div class="container" style="padding-top: 10px;">
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-header">
<h2 class="card-title">Most Worked Callsigns</h2>
<p class="card-text">Callsigns worked multiple times from your active logbook, showing contact frequency and other details.</p>
</div>
<div class="card-body">
<!-- Filter Form -->
<form method="post" id="mostworked_filter_form">
<div class="row mb-3">
<div class="col-md-2">
<label for="band" class="form-label">Band:</label>
<select class="form-select form-select-sm" name="band" id="band">
<option value="all" <?php echo ($filters['band'] == 'all') ? 'selected' : ''; ?>>All Bands</option>
<option value="SAT" <?php echo ($filters['band'] == 'SAT') ? 'selected' : ''; ?>>Satellites</option>
<?php foreach($bands as $band) { ?>
<option value="<?php echo $band; ?>" <?php echo ($filters['band'] == $band) ? 'selected' : ''; ?>><?php echo $band; ?></option>
<?php } ?>
</select>
</div>
<div class="col-md-2">
<label for="mode" class="form-label">Mode:</label>
<select class="form-select form-select-sm" name="mode" id="mode">
<option value="all" <?php echo ($filters['mode'] == 'all') ? 'selected' : ''; ?>>All Modes</option>
<?php foreach($modes as $mode) { ?>
<option value="<?php echo $mode->mode; ?>" <?php echo ($filters['mode'] == $mode->mode) ? 'selected' : ''; ?>><?php echo $mode->mode; ?></option>
<?php } ?>
</select>
</div>
<div class="col-md-2">
<label for="satellite" class="form-label">Satellite:</label>
<select class="form-select form-select-sm" name="satellite" id="satellite">
<option value="all" <?php echo ($filters['satellite'] == 'all') ? 'selected' : ''; ?>>All Satellites</option>
<?php foreach($satellites as $sat) { ?>
<option value="<?php echo $sat->satellite; ?>" <?php echo ($filters['satellite'] == $sat->satellite) ? 'selected' : ''; ?>><?php echo $sat->satellite; ?></option>
<?php } ?>
</select>
</div>
<div class="col-md-2">
<label for="fromdate" class="form-label">From Date:</label>
<input type="date" class="form-control form-control-sm" name="fromdate" id="fromdate" value="<?php echo $filters['fromdate']; ?>">
</div>
<div class="col-md-2">
<label for="todate" class="form-label">To Date:</label>
<input type="date" class="form-control form-control-sm" name="todate" id="todate" value="<?php echo $filters['todate']; ?>">
</div>
<div class="col-md-2">
<label for="min_qsos" class="form-label">Min QSOs:</label>
<select class="form-select form-select-sm" name="min_qsos" id="min_qsos">
<option value="2" <?php echo ($filters['min_qsos'] == 2) ? 'selected' : ''; ?>>2+</option>
<option value="3" <?php echo ($filters['min_qsos'] == 3) ? 'selected' : ''; ?>>3+</option>
<option value="5" <?php echo ($filters['min_qsos'] == 5) ? 'selected' : ''; ?>>5+</option>
<option value="10" <?php echo ($filters['min_qsos'] == 10) ? 'selected' : ''; ?>>10+</option>
<option value="20" <?php echo ($filters['min_qsos'] == 20) ? 'selected' : ''; ?>>20+</option>
<option value="50" <?php echo ($filters['min_qsos'] == 50) ? 'selected' : ''; ?>>50+</option>
</select>
</div>
</div>
<div class="row mb-3">
<div class="col-md-12">
<button type="submit" class="btn btn-primary btn-sm">Apply Filters</button>
<button type="button" class="btn btn-secondary btn-sm" id="clear_filters">Clear Filters</button>
</div>
</div>
</form>
<?php if (empty($mostworked_callsigns)) { ?>
<div class="alert alert-warning" role="alert">
<strong>No QSOs found!</strong> Make sure you have an active logbook selected and QSOs logged, or try adjusting your filters.
</div>
<?php } else { ?>
<div class="alert alert-info" role="alert">
<strong><?php echo count($mostworked_callsigns); ?> callsigns</strong> worked <?php echo $filters['min_qsos']; ?>+ times with current filters.
</div>
<div class="table-responsive">
<table id="mostworked_table" class="table table-striped table-hover">
<thead>
<tr>
<th>Rank</th>
<th>Callsign</th>
<th>Contacts</th>
<th>First QSO</th>
<th>Last QSO</th>
</tr>
</thead>
<tbody>
<?php $rank = 1; ?>
<?php
// 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/cloudlog.php
$custom_date_format = $this->config->item('qso_date_format');
}
foreach ($mostworked_callsigns as $row) { ?>
<tr>
<td><?php echo $rank++; ?></td>
<td>
<strong><?php echo str_replace("0","&Oslash;",strtoupper($row->callsign)); ?></strong>
</td>
<td>
<span class="badge bg-primary"><?php echo $row->contact_count; ?></span>
</td>
<td>
<?php
$timestamp = strtotime($row->first_qso);
echo date($custom_date_format, $timestamp);
?>
</td>
<td>
<?php
$timestamp = strtotime($row->last_qso);
echo date($custom_date_format, $timestamp);
?>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<?php } ?>
</div>
</div>
</div>
</div>
</div>