$park_ref, 'name' => $row->label ?: $park_ref, 'lat' => floatval( $row->lat ), 'lon' => floatval( $row->lon ), 'cached' => true, ]; } $response = wp_remote_get( 'https://api.pota.app/park/' . $park_ref, [ 'timeout' => 15, 'user-agent' => 'Activator-Toolkit-for-SOTA/1.0 (WordPress plugin; +https://wordpress.org/plugins/activator-toolkit-for-sota)', ] ); if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) { return $memo[ $park_ref ] = null; } $data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! is_array( $data ) || ! isset( $data['latitude'], $data['longitude'] ) ) { return $memo[ $park_ref ] = null; } $name = isset( $data['name'] ) ? sanitize_text_field( $data['name'] ) : $park_ref; sota_magic_location_write( $cache_key, floatval( $data['latitude'] ), floatval( $data['longitude'] ), $name, 'pota', 90 * DAY_IN_SECONDS ); usleep( 150000 ); // be polite to the POTA API return $memo[ $park_ref ] = [ 'ref' => $park_ref, 'name' => $name, 'lat' => floatval( $data['latitude'] ), 'lon' => floatval( $data['longitude'] ), 'cached' => false, ]; } /** * Sort contacts chronologically. Dates arrive as DD/MM/YY from the ADIF parser. */ function sota_magic_sort_contacts_by_time( array $contacts ) { $key = function ( $c ) { $parts = explode( '/', $c['date'] ); if ( count( $parts ) === 3 ) { $y = (int) $parts[2]; $y = $y < 50 ? 2000 + $y : 1900 + $y; $date_key = sprintf( '%04d%02d%02d', $y, (int) $parts[1], (int) $parts[0] ); } else { $date_key = $c['date']; } return $date_key . str_replace( ':', '', $c['time'] ); }; usort( $contacts, function ( $a, $b ) use ( $key ) { return strcmp( $key( $a ), $key( $b ) ); } ); return $contacts; } /** * Render the block in POTA mode: park header, contact map, contact table. * No GPX handling; POTA mode is driven entirely by the ADIF log. */ function sota_magic_render_pota_data( $atts ) { $log_url = $atts['csvUrl'] ?? ''; if ( ! $log_url ) return ''; $park_override = $atts['myParkRef'] ?? ''; $show_map = get_option( 'sota_show_contact_map' ); $block_width = get_option( 'sota_block_width', '' ); $width_class = $block_width === 'wide' ? ' alignwide' : ( $block_width === 'full' ? ' alignfull' : '' ); $width_style = ( is_numeric( $block_width ) && (int) $block_width > 0 ) ? 'max-width:' . absint( $block_width ) . 'px;width:100%;' : ''; static $pota_counter = 0; $pota_counter++; $map_dom_id = 'pota-contact-map-' . $pota_counter; $table_dom_id = 'pota-contact-table-' . $pota_counter; $contacts = sota_magic_sort_contacts_by_time( sota_magic_parse_adif_contacts( $log_url, '', $park_override ) ); if ( ! $contacts ) { return '
' . esc_html__( 'No contacts were found in this log file.', 'activator-toolkit-for-sota' ) . '
1 ? 'My Parks:' : 'My Park:' ); ?> ' . esc_html( $ref ) . '' . ( $info ? ' ' . esc_html( $info['name'] ) : '' ); } echo wp_kses( implode( ', ', $labels ), [ 'strong' => [] ] ); ?>
| Date / Time | Callsign | Frequency | Mode | Their Park | Comments | ' . esc_html( $formatted_date ) . ' ' . esc_html( $tc['time'] ) . ' | ';
echo '' . esc_html( $tc['callsign'] ) . '' . ( $p2p ? 'P2P' : '' ) . ' | '; echo '' . esc_html( $tc['frequency'] ) . ' | '; echo '' . esc_html( $tc['mode'] ) . ' | '; echo '' . esc_html( implode( ', ', $their_parks ) ) . ' | '; echo '' . esc_html( $tc['comments'] ) . ' | '; echo ''; } ?>
|---|