• 0

[PHP] Issues Displaying a League Table


Question

Hi all,

Please see the following documentation for reference: https://secure.rugby-league.com/api/docs/

A developer provided me with the following PHP file (although I have removed the API key and Secret):

/**
 * League Championships
 */

function fetch_league_table() {
    // Replace with your actual API credentials
    $apiKey = 'xxxx';
    $secret = 'xxxx';

    // Generate a digital signature (sig) using the current timestamp
    $timestamp = time();
    $sig = hash_hmac('sha256', $timestamp, $apiKey . $secret);

    // API endpoint and query parameters
    $apiUrl = 'https://secure.rugby-league.com/api/leaguetable';
    $queryParams = [
        'compID' => 4, // Replace with the appropriate competition ID
        'sig' => $sig
    ];

    // Build the full URL
    $urlWithParams = $apiUrl . '?' . http_build_query($queryParams);

    // Initialize cURL
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $urlWithParams);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept: application/json',
        'x-api-key: ' . $apiKey,
        'sig: ' . $sig
    ]);

    // Execute the API request
    $response = curl_exec($ch);

    // Check for errors
    if (curl_errno($ch)) {
        return 'Error fetching data: ' . curl_error($ch);
    }

    curl_close($ch);

    // Decode JSON response
    $data = json_decode($response, true);

        // Handle response and build HTML output
    if ($data['status'] !== 200) {
        return 'No data found.';
    }

    $leagueTable = $data['data']['table'];

    $output = "<h2>" . $data['data']['competition'] . " - " . $data['data']['season'] . "</h2>";
    $output .= "<table border='1' cellpadding='5' cellspacing='0'><thead><tr>";
    $output .= "<th>Position</th><th>Team</th><th>Played</th><th>Wins</th><th>Losses</th><th>Draws</th><th>Points</th></tr></thead><tbody>";

    foreach ($leagueTable as $position => $team) {
        if ($position === 'deductions') continue;
        $output .= "<tr>";
        $output .= "<td>" . $position . "</td>";

        // Fetch the logo URL from the API response
        $logoUrl = isset($team['logo']) ? $team['logo'] : '';
        $logoHtml = $logoUrl ? "<img src='$logoUrl' alt='{$team['teamName']} logo' style='height:20px; margin-right:10px;'>" : '';

        $output .= "<td><strong>" . $logoHtml . $team['teamName'] . "</strong></td>";
        $output .= "<td>" . $team['P'] . "</td>";
        $output .= "<td>" . $team['W'] . "</td>";
        $output .= "<td>" . $team['L'] . "</td>";
        $output .= "<td>" . $team['D'] . "</td>";
        $output .= "<td>" . $team['PTS'] . "</td>";
        $output .= "</tr>";
    }

    $output .= "</tbody></table>";

    // Display deductions if available
    if (isset($leagueTable['deductions'])) {
        $output .= "<h3>Deductions</h3><ul>";
        foreach ($leagueTable['deductions'] as $deduction) {
            $output .= "<li>" . $deduction['team'] . ": -" . $deduction['pts'] . " points (" . $deduction['reason'] . ")</li>";
        }
        $output .= "</ul>";
    }

    return $output;
}

add_shortcode('league_table', 'fetch_league_table');

This PHP file provides us with the table on the website, although I note that the year is 2019. I think this is because the Leaguetable API endpoint doesn't have a year integer. I have been told that I should be able to get the year integer from the Competitions endpoint. But I am not a PHP developer, and I think that the developer that gave me this code got it by going through an AI prompt (i.e. he doesn't know PHP either).

I can see the API endpoint in the code, so I would imagine that I copy that, paste it again but modify the URL and the queryparams to search for year. But what I don't know is how I would then put the query params together so that the table being displayed (compID 4) is for the current year (ex. 2024).

Would someone be able to assist me or point me in the right direction? I tried emailing the support email in the documentation but they have been less than helpful.

Many thanks in advance.

8 answers to this question

Recommended Posts

  • 0

Without the API key and secret I'm not able to test anything, but according to the docs there is no "compID" parameter for the "leaguetable" endpoint, it should be "divisionID", so you're probably getting some kind of default value from 2019  (e.g. since divisionID is omitted it might be using 0)

  • 0
On 11/12/2024 at 22:34, virtorio said:

Without the API key and secret I'm not able to test anything, but according to the docs there is no "compID" parameter for the "leaguetable" endpoint, it should be "divisionID", so you're probably getting some kind of default value from 2019.

Oh damn...that seems right. That would explain why it defaults...

I've received this bit of information since:

Quote

That league table call looks good, expect you only need to pass the division ID to the league table endpoint. See the docs.

To find the divisionIDs and seasonIDs you need to call the competitions endpoint using the relevant compIDs, which are:

Championship: 3
League One: 4
Challenge Cup: 2
1895 Cup: 115
Academy: 52

So the CompID is correct (4).

But now I don't know how to call the competitions endpoint as part of the code from the original post...like I said I'm no developer, especially with PHP. Do I try what I suggested at the start, copy-paste and modify the code for the competition part? But then if so, how do I concatenate the results from the first search and the second?

  • 0

I've updated your code (well I used ChatGPT to update the code as 1. I haven't touched PHP since 2008 and I'm more than a little rusty, and 2. I'm not set up to run any PHP on this computer). You can now re-use the requestApi() function by passing the endpoint url and query params (use of it is shown in the fetch_league_table function).

/**
 * Reusable API request function
 */
function requestApi($endpoint, $queryParams = []) {
    // Replace with your actual API credentials
    $apiKey = 'xxxx';
    $secret = 'xxxx';

    // Generate a digital signature (sig) using the current timestamp
    $timestamp = time();
    $sig = hash_hmac('sha256', $timestamp, $apiKey . $secret);

    // Add the signature to the query parameters
    $queryParams['sig'] = $sig;

    // Build the full URL
    $urlWithParams = $endpoint . '?' . http_build_query($queryParams);

    // Initialize cURL
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $urlWithParams);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept: application/json',
        'x-api-key: ' . $apiKey,
        'sig: ' . $sig
    ]);

    // Execute the API request
    $response = curl_exec($ch);

    // Handle cURL errors
    if (curl_errno($ch)) {
        $error = curl_error($ch);
        curl_close($ch);
        return [
            'success' => false,
            'error' => "Error fetching data: $error"
        ];
    }

    curl_close($ch);

    // Decode JSON response
    $data = json_decode($response, true);

    // Check for decoding errors
    if (json_last_error() !== JSON_ERROR_NONE) {
        return [
            'success' => false,
            'error' => 'Error decoding JSON response.'
        ];
    }

    return [
        'success' => true,
        'data' => $data
    ];
}

/**
 * League Championships
 */
function fetch_league_table() {
    $endpoint = 'https://secure.rugby-league.com/api/leaguetable';
    $queryParams = [
        'compID' => 4 // Replace with the appropriate competition ID
    ];

    // Call the reusable request function
    $result = requestApi($endpoint, $queryParams);

    if (!$result['success']) {
        return $result['error'];
    }

    $data = $result['data'];

    // Handle response and build HTML output
    if ($data['status'] !== 200) {
        return 'No data found.';
    }

    $leagueTable = $data['data']['table'];

    $output = "<h2>" . $data['data']['competition'] . " - " . $data['data']['season'] . "</h2>";
    $output .= "<table border='1' cellpadding='5' cellspacing='0'><thead><tr>";
    $output .= "<th>Position</th><th>Team</th><th>Played</th><th>Wins</th><th>Losses</th><th>Draws</th><th>Points</th></tr></thead><tbody>";

    foreach ($leagueTable as $position => $team) {
        if ($position === 'deductions') continue;
        $output .= "<tr>";
        $output .= "<td>" . $position . "</td>";

        // Fetch the logo URL from the API response
        $logoUrl = isset($team['logo']) ? $team['logo'] : '';
        $logoHtml = $logoUrl ? "<img src='$logoUrl' alt='{$team['teamName']} logo' style='height:20px; margin-right:10px;'>" : '';

        $output .= "<td><strong>" . $logoHtml . $team['teamName'] . "</strong></td>";
        $output .= "<td>" . $team['P'] . "</td>";
        $output .= "<td>" . $team['W'] . "</td>";
        $output .= "<td>" . $team['L'] . "</td>";
        $output .= "<td>" . $team['D'] . "</td>";
        $output .= "<td>" . $team['PTS'] . "</td>";
        $output .= "</tr>";
    }

    $output .= "</tbody></table>";

    // Display deductions if available
    if (isset($leagueTable['deductions'])) {
        $output .= "<h3>Deductions</h3><ul>";
        foreach ($leagueTable['deductions'] as $deduction) {
            $output .= "<li>" . $deduction['team'] . ": -" . $deduction['pts'] . " points (" . $deduction['reason'] . ")</li>";
        }
        $output .= "</ul>";
    }

    return $output;
}

add_shortcode('league_table', 'fetch_league_table');

 

For the next step, how would you like it to work? Should it use the "competitions" endpoint to get a list of all "divisionID"'s for a particular (current) year, and then print all those? Is there just a particular divisionID you want displayed, etc?

 

  • 0
On 11/12/2024 at 23:31, virtorio said:

I've updated your code (well I used ChatGPT to update the code as 1. I haven't touched PHP since 2008 and I'm more than a little rusty, and 2. I'm not set up to run any PHP on this computer). You can now re-use the requestApi() function by passing the endpoint url and query params (use of it is shown in the fetch_league_table function).

For the next step, how would you like it to work? Should it use the "competitions" endpoint to get a list of all "divisionID"'s for a particular (current) year, and then print all those? Is there just a particular divisionID you want displayed, etc?

Oh wow! Ok, that's great news! I've just performed a test and it still provides the table for 2019, but as you mentioned it's going to because it doesn't have the year parameter set.

I think you're right about the next step: display all DivisionID's for the current year. I haven't been provided with a specific DivisonID so I guess it would be all of them (at least for the moment)...

Wow, many thanks for taking a shot at this for me. I've been staring at the code for so long trying to understand it my eyes are getting crossed. :laugh:

  • 0

This is what I've got so far, but haven't been able to test it. You're welcome to PM your api key/secret (I won't share it with anyone - promise) if you want and I can run through it.

 

/**
 * Reusable API request function
 */
function request_api($endpoint, $queryParams = []) {
    // Replace with your actual API credentials
    $apiKey = 'xxxx';
    $secret = 'xxxx';

    // Generate a digital signature (sig) using the current timestamp
    $timestamp = time();
    $sig = hash_hmac('sha256', $timestamp, $apiKey . $secret);

    // Add the signature to the query parameters
    $queryParams['sig'] = $sig;

    // Build the full URL
    $urlWithParams = $endpoint . '?' . http_build_query($queryParams);

    // Initialize cURL
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $urlWithParams);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept: application/json',
        'x-api-key: ' . $apiKey,
        'sig: ' . $sig
    ]);

    // Execute the API request
    $response = curl_exec($ch);

    // Handle cURL errors
    if (curl_errno($ch)) {
        $error = curl_error($ch);
        curl_close($ch);
        return [
            'success' => false,
            'error' => "Error fetching data: $error"
        ];
    }

    curl_close($ch);

    // Decode JSON response
    $data = json_decode($response, true);

    // Check for decoding errors
    if (json_last_error() !== JSON_ERROR_NONE) {
        return [
            'success' => false,
            'error' => 'Error decoding JSON response.'
        ];
    }

    return [
        'success' => true,
        'data' => $data
    ];
}

/**
 * Renders the league table as HTML
 */
function render_league_table_html($data) {
    // Handle response and build HTML output
    if ($data['status'] !== 200) {
        return 'No data found.';
    }

    $leagueTable = $data['data']['table'];

    $output = "<h2>" . $data['data']['competition'] . " - " . $data['data']['season'] . "</h2>";
    $output .= "<table border='1' cellpadding='5' cellspacing='0'><thead><tr>";
    $output .= "<th>Position</th><th>Team</th><th>Played</th><th>Wins</th><th>Losses</th><th>Draws</th><th>Points</th></tr></thead><tbody>";

    foreach ($leagueTable as $position => $team) {
        if ($position === 'deductions') continue;
        $output .= "<tr>";
        $output .= "<td>" . $position . "</td>";

        // Fetch the logo URL from the API response
        $logoUrl = isset($team['logo']) ? $team['logo'] : '';
        $logoHtml = $logoUrl ? "<img src='$logoUrl' alt='{$team['teamName']} logo' style='height:20px; margin-right:10px;'>" : '';

        $output .= "<td><strong>" . $logoHtml . $team['teamName'] . "</strong></td>";
        $output .= "<td>" . $team['P'] . "</td>";
        $output .= "<td>" . $team['W'] . "</td>";
        $output .= "<td>" . $team['L'] . "</td>";
        $output .= "<td>" . $team['D'] . "</td>";
        $output .= "<td>" . $team['PTS'] . "</td>";
        $output .= "</tr>";
    }

    $output .= "</tbody></table>";

    // Display deductions if available
    if (isset($leagueTable['deductions'])) {
        $output .= "<h3>Deductions</h3><ul>";
        foreach ($leagueTable['deductions'] as $deduction) {
            $output .= "<li>" . $deduction['team'] . ": -" . $deduction['pts'] . " points (" . $deduction['reason'] . ")</li>";
        }
        $output .= "</ul>";
    }

    return $output;
}

/**
 * Fetch competitions based on compIDs
 */
function fetch_competitions($compIDs) {
    $endpoint = 'https://secure.rugby-league.com/api/competitions';
    $queryParams = [
        'compIDs' => implode(',', $compIDs) // Convert array to comma-separated string
    ];

    // Call the reusable request function
    $result = request_api($endpoint, $queryParams);

    if (!$result['success']) {
        return [
            'success' => false,
            'error' => $result['error']
        ];
    }

    $data = $result['data'];

    // Validate response format
    if (!isset($data) || !is_array($data)) {
        return [
            'success' => false,
            'error' => 'Invalid response format from API.'
        ];
    }

    // Map API response to required format
    $competitions = [];
    foreach ($data as $comp) {
        $competition = [
            'compID' => $comp['compID'],
            'compName' => $comp['name'],
            'divisions' => []
        ];

        if (isset($comp['seasons']) && is_array($comp['seasons'])) {
            foreach ($comp['seasons'] as $season) {
                if (isset($season['divisions']) && is_array($season['divisions'])) {
                    foreach ($season['divisions'] as $divisionID => $division) {
                        $competition['divisions'][] = [
                            'divisionID' => $division['divisionID'],
                            'divisionName' => $division['divisionName']
                        ];
                    }
                }
            }
        }

        $competitions[] = $competition;
    }

    return [
        'success' => true,
        'data' => $competitions
    ];
}

/**
 * League Championships
 */
function fetch_league_table() {
    // Always fetch competitions for compID 4
    $compIDs = [4];
    $competitionsResult = fetch_competitions($compIDs);

    if (!$competitionsResult['success']) {
        return $competitionsResult['error'];
    }

    $competitions = $competitionsResult['data'];
    $output = '';

    // Loop through each competition and fetch league table for its divisions
    foreach ($competitions as $competition) {
        foreach ($competition['divisions'] as $division) {
            $divisionID = $division['divisionID'];
            $endpoint = 'https://secure.rugby-league.com/api/leaguetable';
            $queryParams = [
                'divisionID' => $divisionID // Use divisionID instead of compID
            ];

            // Call the reusable request function
            $result = request_api($endpoint, $queryParams);

            if (!$result['success']) {
                $output .= "<p>Error fetching league table for Division ID $divisionID: {$result['error']}</p>";
                continue;
            }

            $data = $result['data'];

            // Pass data to the render function and append the HTML
            $output .= render_league_table_html($data);
        }
    }

    return $output;
}

/**
 * Shortcode to display the league table
 */
add_shortcode('league_table', 'fetch_league_table');

 

 

  • 0

@virtorioI meant to send you the keys earlier, I know I can trust you with them. My bad.

I'll send they keys in a moment, and I'll try the script on the server on my side once I read through it to try and see what is going on. (Y)

  • 0

Seems like it was mostly correct, just needed to correct one array error and it wasn't handling invalid requests from the API properly.

/**
 * Reusable API request function
 */
function request_api($endpoint, $queryParams = []) {
    // Replace with your actual API credentials
    $apiKey = 'xxx';
    $secret = 'xxx';

    // Generate a digital signature (sig) using the current timestamp
    $timestamp = time();
    $sig = hash_hmac('sha256', $timestamp, $apiKey . $secret);

    // Add the signature to the query parameters
    $queryParams['sig'] = $sig;

    // Build the full URL
    $urlWithParams = $endpoint . '?' . http_build_query($queryParams);

    // Initialize cURL
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $urlWithParams);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept: application/json',
        'x-api-key: ' . $apiKey,
        'sig: ' . $sig
    ]);

    // Execute the API request
    $response = curl_exec($ch);

    // Handle cURL errors
    if (curl_errno($ch)) {
        $error = curl_error($ch);
        curl_close($ch);
        return [
            'success' => false,
            'error' => "Error fetching data: $error"
        ];
    }

    curl_close($ch);

    // Decode JSON response
    $data = json_decode($response, true);

    // Check for decoding errors
    if (json_last_error() !== JSON_ERROR_NONE) {
        return [
            'success' => false,
            'error' => 'Error decoding JSON response.'
        ];
    }

    if ($data['status'] !== 200) {
        return [
            'success' => false,
            'error' => $data['response']
        ];
    }

    return [
        'success' => true,
        'data' => $data
    ];
}

/**
 * Renders the league table as HTML
 */
function render_league_table_html($data) {
    // Handle response and build HTML output
    if ($data['status'] !== 200) {
        return 'No data found.';
    }

    $leagueTable = $data['data']['table'];

    $output = "<h2>" . $data['data']['competition'] . " - " . $data['data']['season'] . "</h2>";
    $output .= "<table border='1' cellpadding='5' cellspacing='0'><thead><tr>";
    $output .= "<th>Position</th><th>Team</th><th>Played</th><th>Wins</th><th>Losses</th><th>Draws</th><th>Points</th></tr></thead><tbody>";

    foreach ($leagueTable as $position => $team) {
        if ($position === 'deductions') continue;
        $output .= "<tr>";
        $output .= "<td>" . $position . "</td>";

        // Fetch the logo URL from the API response
        $logoUrl = isset($team['logo']) ? $team['logo'] : '';
        $logoHtml = $logoUrl ? "<img src='$logoUrl' alt='{$team['teamName']} logo' style='height:20px; margin-right:10px;'>" : '';

        $output .= "<td><strong>" . $logoHtml . $team['teamName'] . "</strong></td>";
        $output .= "<td>" . $team['P'] . "</td>";
        $output .= "<td>" . $team['W'] . "</td>";
        $output .= "<td>" . $team['L'] . "</td>";
        $output .= "<td>" . $team['D'] . "</td>";
        $output .= "<td>" . $team['PTS'] . "</td>";
        $output .= "</tr>";
    }

    $output .= "</tbody></table>";

    // Display deductions if available
    if (isset($leagueTable['deductions'])) {
        $output .= "<h3>Deductions</h3><ul>";
        foreach ($leagueTable['deductions'] as $deduction) {
            $output .= "<li>" . $deduction['team'] . ": -" . $deduction['pts'] . " points (" . $deduction['reason'] . ")</li>";
        }
        $output .= "</ul>";
    }

    return $output;
}

/**
 * Fetch competitions based on compIDs
 */
function fetch_competitions($compIDs) {
    $endpoint = 'https://secure.rugby-league.com/api/competitions';
    $queryParams = [
        'compIDs' => implode(',', $compIDs) // Convert array to comma-separated string
    ];

    // Call the reusable request function
    $result = request_api($endpoint, $queryParams);

    if (!$result['success']) {
        return [
            'success' => false,
            'error' => $result['error']
        ];
    }

    $data = $result['data'];

    // Validate response format
    if (!isset($data) || !is_array($data)) {
        return [
            'success' => false,
            'error' => 'Invalid response format from API.'
        ];
    }

    // Map API response to required format
    $competitions = [];
    foreach ($data['data'] as $comp) {
        $competition = [
            'compID' => $comp['compID'],
            'compName' => $comp['name'],
            'divisions' => []
        ];

        if (isset($comp['seasons']) && is_array($comp['seasons'])) {
            foreach ($comp['seasons'] as $season) {
                if (isset($season['divisions']) && is_array($season['divisions'])) {
                    foreach ($season['divisions'] as $divisionID => $division) {
                        $competition['divisions'][] = [
                            'divisionID' => $division['divisionID'],
                            'divisionName' => $division['divisionName']
                        ];
                    }
                }
            }
        }

        $competitions[] = $competition;
    }

    return [
        'success' => true,
        'data' => $competitions
    ];
}

/**
 * League Championships
 */
function fetch_league_table() {
    // Always fetch competitions for compID 4
    $compIDs = [4];
    $competitionsResult = fetch_competitions($compIDs);

    if (!$competitionsResult['success']) {
        return $competitionsResult['error'];
    }

    $competitions = $competitionsResult['data'];
    $output = '';

    // Loop through each competition and fetch league table for its divisions
    foreach ($competitions as $competition) {
        foreach ($competition['divisions'] as $division) {
            $divisionID = $division['divisionID'];
            $endpoint = 'https://secure.rugby-league.com/api/leaguetable';
            $queryParams = [
                'divisionID' => $divisionID // Use divisionID instead of compID
            ];

            // Call the reusable request function
            $result = request_api($endpoint, $queryParams);

            if (!$result['success']) {
                $output .= "<p>Error fetching league table for Division ID $divisionID: {$result['error']}</p>";
                continue;
            }

            $data = $result['data'];

            // Pass data to the render function and append the HTML
            $output .= render_league_table_html($data);
        }
    }

    return $output;
}

/**
 * Shortcode to display the league table
 */
add_shortcode('league_table', 'fetch_league_table');

 

  • 0

i was actually reading through this just to try and understand how api stuff like this works but honestly yeah it’s confusing esp with that compID/year thing… did you try calling the competitions endpoint directly? i’m curious what it returns, maybe it lists the compID for each year? like if 2024 has a diff compID than 2019? not sure though lol just guessing tbh. if anyone figures it out pls update here 🙏 kinda want to learn from this too

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Camtasia 2026.1.3 by Razvan Serea TechSmith Camtasia is the complete professional solution for high-quality screen recording, video editing and sharing. Camtasia 2026 makes editing your videos easier, and faster than ever. The new editor is packed with enhanced video processing, all-new production technology, an innovative library, and stock videos and other creative assets to help you create more polished, professional videos. No video experience needed. Anyone can create informative, engaging videos. Create professional, eye-catching videos: Add special video effects - Apply Behaviors that are perfectly designed to animate your text, images, or icons. Get a crisp, polished look without being a professional video editor. Drag-and-drop your edits - What you see is what you get. Every effect and element in your video can be dropped and edited directly in the preview window. And you can edit at resolutions up to beautiful 4K, for clear video at any size. Get exceptional performance - Camtasia takes full advantage of your computer’s processor with 64-bit performance. You’ll get fast rendering times and enhanced stability—even on your most complex projects. Camtasia 2026.1.3 changelog: Feature Updates Improved keyboard navigability in tool panels. Improved screen reader accessibility of headings in Preferences. Tool panels can now be resized using a keyboard-navigable control. Updated color of folder icon in User Library tab for better visibility. Grouped media now render a composite waveform considering all audio media within that group. Added Long Path Aware to the manifest of Editor and Recorder. Performance Improvements Improved performance for editing groups on the timeline. Improved the project loading performance when timeline has lots of trec media with cursor data. Updates for IT Administrators Updated cpp-httplib from 0.38.0 to 0.43.3. Updated expat from 2.7.4 to 2.8.0. Updated freetype from 2.13.3 to 2.14.3. Updated harfbuzz from 13.0.1 to 14.2.0. Updated libpng16 from 1.6.55 to 1.6.58. Updated pango from 1.57.0 to 1.57.1. Updated girepository from 2.86.3 to 2.88.0. Updated pcre2-posix from 10.47.0 to 12.0.2. Added new harfbuzz-gpu.dll. Updated FFmpeg from 7.1.1 to 7.1.2. Updated aom from 3.11.0 to 3.13.1. Updated dav1d from 1.5.0 to 1.5.1. Updated ogg from 1.3.5 to 1.3.6. Updated SDL2 from 2.32.4 to 2.32.10. Updated zlib from 1.3.1 to 1.3.2. Updated Nalpeiron binaries to version 4.4.69.3. Bug Fixes Fixed an issue which prevented some user submitted crash reports from being sent. Fixed a potential memory leak when decoding HEVC or VP9 video. Fixed a potential crash when trying to delete a range selection on a magnetic track. Fixed a bug with the Properties Panel showing stale properties when only a caption is selected on the timeline. Fixed an issue that could prevent the Opacity and Blur properties from being changed in the Background Removal effect. Fixed an issue where larger Camtasia online projects may fail to open in Camtasia Editor. Table of contents thumbnails are no longer created for Smart Player exports with no table of contents. Fix resetting skew revert to revert just skew and not scale as well. Fixed editing in Snagit with snagX file with Unicode characters. Fixed a bug where grouped visual media could be cropped in some cases. Fixed importing SnagX files with Unicode characters. Localization fixes. Download: Camtasia 2026.1.3 | 309.0 MB (Shareware) View: Camtasia Homepage | Tutorials | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • yeah it seems to be Edge only. The dialog buttons work as expected in Chrome and Firefox. The phone is using Android 16 (OneUI 8.5) and Edge version  149.0.4022.53
    • I'm not aware of this issue, but to help the other guys.  What version of Android are you using? Did you try a different browser? To see if Edge is the issue here.
    • I agree when are you going to read this (really poor BTW) article? Here is a better article so you actually know what is going on and answers questions you had in other comments --> https://arstechnica.com/gadgets/2026/05/speed-boosting-low-latency-profile-is-one-of-the-improvements-coming-to-windows-11/ It is unclear if one will be able to disable the new profile at this point but I am not seeing any reason why one would.
  • Recent Achievements

    • One Month Later
      Jamswaz earned a badge
      One Month Later
    • Week One Done
      Jamswaz earned a badge
      Week One Done
    • Rookie
      Marzoid went up a rank
      Rookie
    • Community Regular
      coch went up a rank
      Community Regular
    • One Year In
      slackerzz earned a badge
      One Year In
  • Popular Contributors

    1. 1
      +primortal
      510
    2. 2
      PsYcHoKiLLa
      188
    3. 3
      +Edouard
      156
    4. 4
      Steven P.
      83
    5. 5
      ATLien_0
      75
  • Tell a friend

    Love Neowin? Tell a friend!