settings = get_option('threecal_settings', array()); // Schedule daily notification check if (!wp_next_scheduled('threecal_daily_notifications')) { wp_schedule_event(time(), 'daily', 'threecal_daily_notifications'); } add_action('threecal_daily_notifications', array($this, 'send_reminder_notifications')); } /** * Send event reminder notifications */ public function send_reminder_notifications() { if (!$this->is_enabled()) { return; } // Get events happening tomorrow $tomorrow = gmdate('Y-m-d', strtotime('+1 day')); $events = ThreeCal_Event::get_all(array( 'status' => 'published', 'start_after' => $tomorrow . ' 00:00:00', 'start_before' => $tomorrow . ' 23:59:59' )); foreach ($events as $event) { $this->send_event_reminders($event); } } /** * Send reminders for a specific event */ public function send_event_reminders($event) { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table, caching not needed for email reminders. $subscribers = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "threecal_subscribers WHERE (event_id = %d OR event_id IS NULL) AND status = 'active'", $event->id ) ); foreach ($subscribers as $subscriber) { $this->send_reminder($subscriber, $event); } } /** * Send individual reminder */ private function send_reminder($subscriber, $event) { $location = null; if ($event->location_id) { $location = ThreeCal_Location::get($event->location_id); } $template = isset($this->settings['notification_template']) ? $this->settings['notification_template'] : $this->get_default_template(); $date_format = isset($this->settings['date_format']) ? $this->settings['date_format'] : get_option('date_format'); $time_format = isset($this->settings['time_format']) ? $this->settings['time_format'] : get_option('time_format'); // Replace placeholders $replacements = array( '{subscriber_name}' => $subscriber->name ?: __('Subscriber', '3task-calendar'), '{subscriber_email}' => $subscriber->email, '{event_title}' => $event->title, '{event_date}' => date_i18n($date_format, strtotime($event->start_date)), '{event_time}' => $event->all_day ? __('All day', '3task-calendar') : date_i18n($time_format, strtotime($event->start_date)), '{event_location}' => $location ? $location->name : '', '{event_address}' => $location ? $location->get_full_address() : '', '{event_description}' => wp_strip_all_tags($event->description), '{event_url}' => $event->url ?: '', '{site_name}' => get_bloginfo('name'), '{site_url}' => home_url(), '{unsubscribe_url}' => $this->get_unsubscribe_url($subscriber) ); $message = str_replace(array_keys($replacements), array_values($replacements), $template); $subject = sprintf( /* translators: %s: event title */ __('Reminder: %s', '3task-calendar'), $event->title ); $this->send($subscriber->email, $subject, $message); } /** * Send email */ public function send($to, $subject, $message, $headers = array()) { $sender_name = isset($this->settings['notification_sender_name']) ? $this->settings['notification_sender_name'] : get_bloginfo('name'); $sender_email = isset($this->settings['notification_sender_email']) ? $this->settings['notification_sender_email'] : get_option('admin_email'); $default_headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: ' . $sender_name . ' <' . $sender_email . '>' ); $headers = array_merge($default_headers, $headers); // Wrap message in HTML template $html_message = $this->wrap_html($message, $subject); return wp_mail($to, $subject, $html_message, $headers); } /** * Wrap message in HTML template */ private function wrap_html($message, $subject) { ob_start(); ?>