Trying to GET data with ajax from database and show in fullcalendar

There were a couple security issues and error checking that I did see. Try these:

<?php 
add_action('wp_ajax_get_timeslot_data', 'get_timeslot_data');
add_action('wp_ajax_nopriv_get_timeslot_data', 'get_timeslot_data');

function get_timeslot_data() {
    if (!isset($_POST['activityId']) || !ctype_digit($_POST['activityId'])) {
        wp_send_json_error("Invalid activity ID");
    }

    global $wpdb;
    $activity_id = intval($_POST['activityId']);
    $table_name = $wpdb->prefix . 'booking_seasons'; // Support custom table prefixes

    $result = $wpdb->get_row($wpdb->prepare("SELECT timeslot_dates FROM $table_name WHERE id = %d", $activity_id));

    if (!$result || empty($result->timeslot_dates)) {
        wp_send_json_error("No time slots found");
    }

    $time_slots = maybe_unserialize($result->timeslot_dates);

    if (!is_array($time_slots)) {
        wp_send_json_error("Invalid time slot data format");
    }

    $events = [];
    foreach ($time_slots as $slot => $dates) {
        $times = explode(" - ", $slot);
        if (count($times) !== 2) {
            continue; // Skip invalid time slot format
        }

        foreach ($dates as $date) {
            $events[] = [
                'title' => sanitize_text_field($slot),
                'start' => esc_html($date . "T" . trim($times[0])),
                'end' => esc_html($date . "T" . trim($times[1]))
            ];
        }
    }

    wp_send_json_success($events);
}
?>
  • Supports dynamic table prefix ($wpdb->prefix)

  • Ensures activity ID is numeric (ctype_digit())

  • Uses maybe_unserialize() for safer data handling

  • Handles invalid time slot formats Uses sanitize_text_field()

  • esc_html() to prevent security issues

     jQuery(document).ready(function() {
             if (typeof activityData !== 'undefined' && activityData.activityId) {
         var activityId = activityData.activityId;
         } else {
             console.error("activityData is undefined or missing activityId.");
         return;
         }
    
     console.log(activityId);
     console.log("jQuery is working");
    
     var calendarEl = jQuery('#calendar-' + activityId);
    
     if (!calendarEl.length) {
         console.error("Calendar element not found for activity ID:", activityId);
         return;
     }
    
     var calendar = new FullCalendar.Calendar(calendarEl[0], {
         initialView: 'timeGridWeek',
         slotDuration: '00:15:00',
         selectable: true,
         allDaySlot: false,
         events: function(fetchInfo, successCallback, failureCallback) {
             console.log('Activity ID inside events:', activityId);
    
             if (typeof my_ajax_object === 'undefined' || !my_ajax_object.ajaxurl) {
                 console.error("my_ajax_object.ajaxurl is undefined.");
                 failureCallback("AJAX URL missing");
                 return;
             }
    
             jQuery.ajax({
                 url: my_ajax_object.ajaxurl,
                 type: 'POST',
                 data: {
                     action: 'get_timeslot_data',
                     activityId: activityId,
                 },
                 success: function(response) {
                     if (response.success) {
                         successCallback(response.data);
                     } else {
                         console.error("Error fetching events:", response.data);
                         failureCallback("Error fetching events");
                     }
                 },
                 error: function(xhr, status, error) {
                     console.error("AJAX Error:", error);
                     failureCallback("Failed to fetch events: " + error);
                 }
             });
         },
         headerToolbar: {
             left: 'prev,next today',
             center: 'title',
             right: 'timeGridDay,timeGridWeek,dayGridMonth'
         },
     });
    
     calendar.render();
     });
    
  • Prevents errors if activityData or calendarEl is missing

  • Ensures my_ajax_object.ajaxurl exists before making the AJAX request

  • Improved error handling for failureCallback

Without knowing your error, I’m not checking with actual usage, those are what I can see.

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)