I need to setup a cron task in order to generate a list of bookings.ics from my Bookings Calendar plugin. My function which is located inside my functions.php is this one. It is processing my bookings through my Wordpress database and exports them to /wp-content/uplodas/bookings.ics
Nevertheless, in order to execute that, I have made a GET request which is located in this corresponding URL here: https://mywebsite.com/booking?ical=1
What I want to avoid is firstly, try and hide that URL from the public and also add a token to that request at any time that it has to generate the booking calendar in .ics format.
Therefore, maybe
CODE
Function which generates the bookings.ics file
/** * Generate ICS feed for approved bookings, FULL COMPLIANT ICS FEED GENERATOR */ function generate_booking_ics_feed() { if (isset($_GET['ical']) && $_GET['ical'] == '1' ) { global $wpdb; // start output buffering ob_start(); // Clear all output buffers while (ob_get_level()) { ob_end_clean(); } // Get timezone data $timezone = wp_timezone(); $timezone_string = $timezone->getName(); $timezone_offset = $timezone->getOffset(new DateTime()); $timezone_offset_hours = $timezone_offset / 3600; $timezone_offset_formatted = sprintf('%+03d%02d', floor($timezone_offset_hours), ($timezone_offset_hours - floor($timezone_offset_hours)) * 60 ); // Get timezone abbreviation alternative way $timezone_abbr = (new DateTime())->format('T'); // Begin VCALENDAR with required properties echo "BEGIN:VCALENDAR\r\n"; echo "VERSION:2.0\r\n"; echo "PRODID:-//".get_bloginfo('name')."//Bookings//EN\r\n"; echo "CALSCALE:GREGORIAN\r\n"; echo "METHOD:PUBLISH\r\n"; // Query approved bookings from WP Booking Calendar tables $bookings = $wpdb->get_results(" SELECT b.booking_id, b.form, b.booking_type, d.booking_date FROM {$wpdb->prefix}booking as b JOIN {$wpdb->prefix}bookingdates as d ON b.booking_id = d.booking_id WHERE d.approved = 1 ORDER BY d.booking_date "); // Generate DTSTAMP once for all events $dtstamp = gmdate('Ymd\THis\Z'); foreach ($bookings as $booking) { // Debug output (view source to see raw data) // Try multiple methods to extract name $name = 'Booking #'.$booking->booking_id; // Default fallback // Method 1: Parse form data $form_data = array(); $form_data = $booking->form; $name = extract_name_from_form($form_data); // Returns "John" $surname = extract_surname_from_form($form_data); $email = extract_email_from_form($form_data); // Format dates with timezone $start = new DateTime($booking->booking_date, new DateTimeZone('UTC')); $end = clone $start; $end->add(new DateInterval('PT1H')); // 1 hour duration // Generate unique UID with timestamp // Generate unique UID with timestamp and random component $uid = uniqid($booking->booking_id.'-', true).'@'.parse_url(home_url(), PHP_URL_HOST); echo "BEGIN:VEVENT\r\n"; echo "UID:".$uid."\r\n"; echo "DTSTAMP:".$dtstamp."\r\n"; echo "DTSTART:".$start->format('Ymd\THis\Z')."\r\n"; echo "DTEND:".$end->format('Ymd\THis\Z')."\r\n"; echo "SUMMARY:".$name. " ". $surname . " ". $email. " - ".$booking->booking_type."\r\n"; echo "DESCRIPTION:Booking ID: ".$booking->booking_id."\r\n"; echo "STATUS:CONFIRMED\r\n"; echo "TRANSP:OPAQUE\r\n"; // Blocks time on calendar echo "SEQUENCE:0\r\n"; echo "CREATED:".$dtstamp."\r\n"; echo "LAST-MODIFIED:".$dtstamp."\r\n"; echo "END:VEVENT\r\n"; } echo "END:VCALENDAR\r\n"; // 2. Save to file (with debug logging) $file_info = save_ics_file($ics_content); error_log("ICS file saved to: {$file_info['path']}, Size: {$file_info['size']} bytes"); // 3. Output to browser output_ics_headers(); } } Function which saves the file to my directory:
function save_ics_file($content) { $upload_dir = wp_upload_dir(); $path = $upload_dir['basedir'] . '/bookings.ics'; // Verify upload directory is writable if (!wp_is_writable($upload_dir['basedir'])) { throw new Exception("Upload directory not writable: " . $upload_dir['basedir']); } // Write to temporary file first $temp_path = $path . '.tmp'; $bytes = file_put_contents($temp_path, $content); if ($bytes === false) { throw new Exception("Failed to write temporary file"); } // Verify temporary file if (!file_exists($temp_path) || filesize($temp_path) === 0) { throw new Exception("Temporary file creation failed"); } // Move to final location if (!rename($temp_path, $path)) { throw new Exception("Failed to move file to final destination"); } // Set permissions chmod($path, 0644); return [ 'path' => $path, 'size' => filesize($path), 'url' => $upload_dir['baseurl'] . '/bookings.ics' ]; } Finally, the goal create the cron task that it will be triggered every 10-15 minutes which it will rewrite the bookings.ics file every time and therefore the link which will be provided must be hidden from the public view but be exposed only in my Google Calendar settings so that it can be read and rendered into the Google calendar's view. Any help would be really appreciating.
Thank you
https://mywebsite.com/booking?ical=1into google cal rather thanwp-content/uploads/booking.ics? Then you can remove cron entirely, and cache the result in the DB to speed things up. Put it in a transient that expires after 15/20 minutes and you've sidestepped the problem entirely!