1

When creating the player, there was a need to collect auditions. I set up the collection and everything works.

You need to manually enter the data that is already available.

I added the following code to functions.php file:

/**
 * ------------------------------------------------------------------------------------------------
 * Адмінка статистики
 * ------------------------------------------------------------------------------------------------
 */
function theasmart_add_admin_page() {
    add_menu_page(
        'Аналітика прослуховувань', // Заголовок сторінки
        'Аналітика казок', // Назва в меню
        'manage_options', // Права доступу
        'theasmart-audio-analytics', // Слаг сторінки
        'theasmart_render_admin_page', // Функція рендеру
        'dashicons-chart-bar', // Іконка
        20 // Позиція в меню
    );
}
add_action('admin_menu', 'theasmart_add_admin_page');

function theasmart_render_admin_page() {
    $active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'analytics'; // Визначаємо активну вкладку

    ?>
    <div class="wrap">
        <h1>📊 Аналітика прослуховувань аудіоказок</h1>
        <h2 class="nav-tab-wrapper">
            <a href="?page=theasmart-audio-analytics&tab=analytics" class="nav-tab <?php echo $active_tab === 'analytics' ? 'nav-tab-active' : ''; ?>">Аналітика</a>
            <a href="?page=theasmart-audio-analytics&tab=edit" class="nav-tab <?php echo $active_tab === 'edit' ? 'nav-tab-active' : ''; ?>">Редагування</a>
            <a href="?page=theasmart-audio-analytics&tab=charts" class="nav-tab <?php echo $active_tab === 'charts' ? 'nav-tab-active' : ''; ?>">Графіки</a>
        </h2>

        <?php
        // Виведення контенту залежно від вибраної вкладки
        switch ($active_tab) {
            case 'analytics':
                theasmart_render_analytics_tab();
                break;
            case 'edit':
                theasmart_render_edit_tab();
                break;
            case 'charts':
                theasmart_render_charts_tab();
                break;
            default:
                theasmart_render_analytics_tab();
                break;
        }
        ?>
    </div>
    <?php
}

// Функція для відображення вкладки "Аналітика"
function theasmart_render_analytics_tab() {
    ?>
    <table class="widefat fixed">
        <thead>
            <tr>
                <th>Назва треку</th>
                <th>Почали слухати</th>
                <th>50%</th>
                <th>80%</th>
                <th>Прослухано повністю</th>
            </tr>
        </thead>
        <tbody>
            <?php
            $track_ids = [10701, 10702, 10703]; // Список ID треків (можна зробити динамічним)

            foreach ($track_ids as $track_id) {
                $track_name = get_the_title($track_id); // Отримуємо назву сторінки за ID

                $response = wp_remote_get("https://thea-smart.com/wp-json/custom/v1/get-listener-stats/{$track_id}");
                if (is_wp_error($response)) {
                    continue;
                }

                $stats = json_decode(wp_remote_retrieve_body($response), true);
                ?>
                <tr>
                    <td><?php echo esc_html($track_name ?: 'Невідомий трек'); ?></td>
                    <td><?php echo esc_html($stats['start'] ?? 0); ?></td>
                    <td><?php echo esc_html($stats['50%'] ?? 0); ?></td>
                    <td><?php echo esc_html($stats['80%'] ?? 0); ?></td>
                    <td><?php echo esc_html($stats['completed'] ?? 0); ?></td>
                </tr>
                <?php
            }
            ?>
        </tbody>
    </table>
    <?php
}

// Функція для відображення вкладки "Редагування"
// Функція для відображення вкладки "Редагування"
function theasmart_render_edit_tab() {
    $track_ids = [10701, 10702, 10703]; // ID треків

    // Обробка форми для збереження
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['theasmart_nonce']) && wp_verify_nonce($_POST['theasmart_nonce'], 'theasmart_save_listener_data')) {
    foreach ($track_ids as $track_id) {
        if (isset($_POST['save_' . $track_id])) {
            $data = [
                'start'     => isset($_POST['start_' . $track_id]) ? intval($_POST['start_' . $track_id]) : 0,
                '50%'       => isset($_POST['fifty_' . $track_id]) ? intval($_POST['fifty_' . $track_id]) : 0,
                '80%'       => isset($_POST['eighty_' . $track_id]) ? intval($_POST['eighty_' . $track_id]) : 0,
                'completed' => isset($_POST['completed_' . $track_id]) ? intval($_POST['completed_' . $track_id]) : 0,
            ];

            // Логування даних перед відправкою
            error_log('Data to send: ' . json_encode($data));

            // Відправка оновлених даних через API
            $response = wp_remote_post("https://thea-smart.com/wp-json/custom/v1/update-listener-stats/{$track_id}", [
                'body'    => json_encode($data),
                'headers' => [
                    'Content-Type' => 'application/json',
                    'Accept'       => 'application/json'
                ],
                'method'  => 'POST',
                'timeout' => 30  // Додано час очікування
            ]);

            // Логування відповіді
            if (is_wp_error($response)) {
                // Детальне логування помилки
                error_log('API Request Error for Track ' . $track_id . ': ' . $response->get_error_message());
                
                echo '<div class="error"><p>Помилка з\'єднання для треку ' . 
                     esc_html(get_the_title($track_id)) . ': ' . 
                     esc_html($response->get_error_message()) . '</p></div>';
            } else {
                $status_code = wp_remote_retrieve_response_code($response);
                $body = wp_remote_retrieve_body($response);
                
                // Розширене логування відповіді
                error_log('API Response for Track ' . $track_id . ':');
                error_log('Status Code: ' . $status_code);
                error_log('Response Body: ' . $body);

                // Розширена перевірка статус-коду
                if ($status_code >= 200 && $status_code < 300) {
                    echo '<div class="updated"><p>Дані успішно збережено для треку ' . 
                         esc_html(get_the_title($track_id)) . '</p></div>';
                } else {
                    echo '<div class="error"><p>Помилка збереження для треку ' . 
                         esc_html(get_the_title($track_id)) . ': Код ' . 
                         esc_html($status_code) . ' - ' . 
                         esc_html($body) . '</p></div>';
                }
            }
        }
    }
}
?>

<h2>Редагування даних прослуховувань</h2>
<form method="post">
    <?php wp_nonce_field('theasmart_save_listener_data', 'theasmart_nonce'); // CSRF захист ?>
    <table class="widefat fixed">
        <thead>
            <tr>
                <th>Назва треку</th>
                <th>Почали слухати</th>
                <th>50%</th>
                <th>80%</th>
                <th>Прослухано повністю</th>
                <th>Зберегти</th>
            </tr>
        </thead>
        <tbody>
            <?php
            foreach ($track_ids as $track_id) {
                $track_name = get_the_title($track_id) ?: 'Невідомий трек';

                // Отримання статистики через API
                $response = wp_remote_get("https://thea-smart.com/wp-json/custom/v1/get-listener-stats/{$track_id}");
                $stats = (!is_wp_error($response)) ? json_decode(wp_remote_retrieve_body($response), true) : [];

                $start     = esc_attr($stats['start'] ?? 0);
                $fifty     = esc_attr($stats['50%'] ?? 0);
                $eighty    = esc_attr($stats['80%'] ?? 0);
                $completed = esc_attr($stats['completed'] ?? 0);
                ?>
                <tr>
                    <td><?php echo esc_html($track_name); ?></td>
                    <td><input type="number" name="start_<?php echo esc_attr($track_id); ?>" value="<?php echo $start; ?>"></td>
                    <td><input type="number" name="fifty_<?php echo esc_attr($track_id); ?>" value="<?php echo $fifty; ?>"></td>
                    <td><input type="number" name="eighty_<?php echo esc_attr($track_id); ?>" value="<?php echo $eighty; ?>"></td>
                    <td><input type="number" name="completed_<?php echo esc_attr($track_id); ?>" value="<?php echo $completed; ?>"></td>
                    <td><button type="submit" name="save_<?php echo esc_attr($track_id); ?>" class="button-primary">Зберегти</button></td>
                </tr>
                <?php
            }
            ?>
        </tbody>
    </table>
</form>

// Функція для відображення вкладки "Графіки"
function theasmart_render_charts_tab() {
    ?>
    <h2>Графіки</h2>
    <p>Тут ви зможете побачити графіки на основі аналітичних даних.</p>
    <!-- Тут можна вставити код для графіків, використовуючи бібліотеку, як-от Chart.js -->
    <?php
}



// Реєстрація маршруту для REST API
add_action('rest_api_init', function () {
    register_rest_route('custom/v1', '/update-listener-stats/(?P<track_id>\d+)', [
        'methods' => 'POST',
        'callback' => 'update_listener_stats_callback',
    ]);
});

// Функція обробника для збереження даних
function update_listener_stats_callback( $data ) {
    // Отримуємо track_id з запиту
    $track_id = $data['track_id'];

    // Перевіряємо, чи track_id є коректним
    if ( ! is_numeric($track_id) ) {
        return new WP_REST_Response('Невірний track_id', 400);
    }

    // Отримуємо дані з POST-запиту
    $start = isset($_POST['start']) ? intval($_POST['start']) : 0;
    $fifty = isset($_POST['50%']) ? intval($_POST['50%']) : 0;
    $eighty = isset($_POST['80%']) ? intval($_POST['80%']) : 0;
    $completed = isset($_POST['completed']) ? intval($_POST['completed']) : 0;

    // Тут можна додати логіку для збереження цих даних у базі або інші операції

    // Виведемо успішну відповідь
    return new WP_REST_Response('Дані успішно оновлені для треку ' . $track_id, 200);
}

add_action( 'rest_api_init', function () {
    register_rest_route( 'custom/v1', '/update-listener-stats/(?P<track_id>\d+)', [
        'methods' => 'POST',
        'callback' => 'handle_update_listener_stats',
    ] );
} );

function handle_update_listener_stats( $data ) {
    $track_id = $data['track_id'];
    $stats = json_decode($data->get_body(), true);

    // Обробка даних і повернення відповіді
    if ($track_id && $stats) {
        // Логіка оновлення даних у базі або в іншому місці
        return new WP_REST_Response('Data saved successfully', 200);
    } else {
        return new WP_REST_Response('Invalid data', 400);
    }
}

Analytics works, but editing does not work. It says that changes have been made, but the data does not change.

4
  • 1
    Your question is not very clear. For example, what is "the player" that you are creating? Try to better explain the context with details and try to provide some debugging details. Commented Mar 27 at 0:31
  • I have a player in which I collect listening data. Then the data is displayed in the wp admin. It became necessary to manually enter the data into the table. To do this, I created a tab with editing, but I screwed something up and the data is not updated when making changes through the admin. This is what the player looks like link Commented Mar 27 at 1:06
  • Update your question please, if you want to get more chances to have some answer. Don't hesitate to include screenshots, more details or related debugging log, if it helps to clarify things. Commented Mar 27 at 4:14
  • 1
    So you are registering two callbacks for the route /update-listener-stats/(?P<track_id>\d+), update_listener_stats_callback and handle_update_listener_stats, I suppose those are what you are talking about here regarding the editing that is "not working"? In both of those I can only see you access some of the passed parameters, but I don't see you actually updating anything with them? Commented Mar 27 at 7:03

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.