settings = get_option('threecal_settings', array()); } /** * Render full calendar */ public function render_calendar($args = array()) { $defaults = array( 'view' => 'month', 'category_id' => 0, 'location_id' => 0, 'theme' => 'default', 'show_filters' => true, 'show_legend' => true, 'week_starts_on' => null ); $args = wp_parse_args($args, $defaults); // Get week start from settings if not specified if ($args['week_starts_on'] === null) { $args['week_starts_on'] = isset($this->settings['week_starts_on']) ? $this->settings['week_starts_on'] : 1; } // Get current month/year. // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Calendar navigation params, sanitized with absint(). $month = isset( $_GET['cc_month'] ) ? absint( $_GET['cc_month'] ) : (int) gmdate( 'n' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Calendar navigation params, sanitized with absint(). $year = isset( $_GET['cc_year'] ) ? absint( $_GET['cc_year'] ) : (int) gmdate( 'Y' ); // Validate month/year if ($month < 1 || $month > 12) { $month = (int) gmdate('n'); } if ($year < 2000 || $year > 2100) { $year = (int) gmdate('Y'); } // Get categories for filter/legend $categories = ThreeCal_Category::get_all(); // Generate unique ID for this calendar instance $calendar_id = 'threecal-' . wp_rand(1000, 9999); ob_start(); ?>

get_month_name($month) . ' ' . $year); ?>

render_month_view( $month, $year, $args ); ?>
name); ?>
'published', 'start_after' => $start_date, 'start_before' => $end_date ); if (!empty($args['category_id'])) { $event_args['category_id'] = $args['category_id']; } if (!empty($args['location_id'])) { $event_args['location_id'] = $args['location_id']; } $events = ThreeCal_Event::get_all($event_args); // Group events by day $events_by_day = array(); foreach ($events as $event) { $day = (int) gmdate('j', strtotime($event->start_date)); if (!isset($events_by_day[$day])) { $events_by_day[$day] = array(); } $events_by_day[$day][] = $event; } ob_start(); ?> $days_in_month) : // Empty cell ?>
get_weekday_name(($i + $week_starts_on) % 7)); ?>
'list', 'theme' => 'default', 'show_pagination' => true, 'columns' => 3, 'total' => 0, 'per_page' => 10, 'current_page' => 1 ); $args = wp_parse_args($args, $defaults); if (empty($events)) { return '

' . esc_html__('No events found.', '3task-calendar') . '

'; } ob_start(); ?>
render_event_card( $event, $args['view'] ); ?>
$args['per_page'] ) : ?>
render_pagination( $args['total'], $args['per_page'], $args['current_page'] ); ?>
location_id) { $location = ThreeCal_Location::get($event->location_id); } $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'); ob_start(); ?>
featured_image) : ?>
featured_image, 'medium'); ?>

url) : ?> title); ?> title); ?>

start_date))); if (!$event->all_day) { echo ' ' . esc_html(date_i18n($time_format, strtotime($event->start_date))); } if ($event->end_date && $event->end_date !== $event->start_date) { echo ' - '; if (gmdate('Y-m-d', strtotime($event->start_date)) !== gmdate('Y-m-d', strtotime($event->end_date))) { echo esc_html(date_i18n($date_format, strtotime($event->end_date))); } if (!$event->all_day) { echo ' ' . esc_html(date_i18n($time_format, strtotime($event->end_date))); } } ?>
name); ?> city) : ?> (city); ?>)
description ) ) : ?>
description ), 20 ) ); ?>
'default', 'show_map' => true, 'show_description' => true ); $args = wp_parse_args($args, $defaults); $location = null; if ($event->location_id) { $location = ThreeCal_Location::get($event->location_id); } $categories = ThreeCal_Event::get_categories($event->id); $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'); ob_start(); ?>
featured_image) : ?>

title); ?>

name); ?>

start_date))); if ($event->end_date && gmdate('Y-m-d', strtotime($event->start_date)) !== gmdate('Y-m-d', strtotime($event->end_date))) { echo ' - ' . esc_html(date_i18n($date_format, strtotime($event->end_date))); } ?>
all_day) : ?>

start_date))); if ($event->end_date) { echo ' - ' . esc_html(date_i18n($time_format, strtotime($event->end_date))); } ?>
name); ?>
get_full_address()); ?>
url) : ?>
description)) : ?>
description)); ?>
latitude && $location->longitude) : ?>
'default', 'show_date' => true, 'show_time' => true, 'show_location' => true ); $args = wp_parse_args($args, $defaults); $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'); if (empty($events)) { return '

' . esc_html__('No upcoming events.', '3task-calendar') . '

'; } ob_start(); ?> 0, 'theme' => 'default', 'show_nav' => true, 'show_today' => true, 'week_starts_on' => null ); $args = wp_parse_args($args, $defaults); // Get week start from settings if not specified if ($args['week_starts_on'] === null) { $args['week_starts_on'] = isset($this->settings['week_starts_on']) ? $this->settings['week_starts_on'] : 1; } // Get current month/year from URL or use current date. // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Calendar navigation params, sanitized with absint(). $month = isset($_GET['cc_mini_month']) ? absint($_GET['cc_mini_month']) : (int) gmdate('n'); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Calendar navigation params, sanitized with absint(). $year = isset($_GET['cc_mini_year']) ? absint($_GET['cc_mini_year']) : (int) gmdate('Y'); // Validate month/year if ($month < 1 || $month > 12) { $month = (int) gmdate('n'); } if ($year < 2000 || $year > 2100) { $year = (int) gmdate('Y'); } $week_starts_on = $args['week_starts_on']; $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'); // Get first day of month $first_day = mktime(0, 0, 0, $month, 1, $year); $days_in_month = (int) gmdate('t', $first_day); $first_weekday = (int) gmdate('w', $first_day); // Adjust for week start $first_weekday = ($first_weekday - $week_starts_on + 7) % 7; // Get events for this month $start_date = gmdate('Y-m-d 00:00:00', $first_day); $end_date = gmdate('Y-m-t 23:59:59', $first_day); $event_args = array( 'status' => 'published', 'start_after' => $start_date, 'start_before' => $end_date ); if (!empty($args['category_id'])) { $event_args['category_id'] = $args['category_id']; } $events = ThreeCal_Event::get_all($event_args); // Group events by day with full event data for popup $events_by_day = array(); $events_data_by_day = array(); foreach ($events as $event) { $day = (int) gmdate('j', strtotime($event->start_date)); if (!isset($events_by_day[$day])) { $events_by_day[$day] = array(); $events_data_by_day[$day] = array(); } $events_by_day[$day][] = $event; // Prepare event data for JSON $event_time = $event->all_day ? __('All day', '3task-calendar') : date_i18n($time_format, strtotime($event->start_date)); $events_data_by_day[$day][] = array( 'id' => $event->id, 'title' => $event->title, 'time' => $event_time, 'color' => $event->color, 'url' => $event->url ? $event->url : '' ); } // Calculate navigation URLs $prev_month = $month - 1; $prev_year = $year; if ($prev_month < 1) { $prev_month = 12; $prev_year--; } $next_month = $month + 1; $next_year = $year; if ($next_month > 12) { $next_month = 1; $next_year++; } $current_url = remove_query_arg(array('cc_mini_month', 'cc_mini_year')); $prev_url = add_query_arg(array('cc_mini_month' => $prev_month, 'cc_mini_year' => $prev_year), $current_url); $next_url = add_query_arg(array('cc_mini_month' => $next_month, 'cc_mini_year' => $next_year), $current_url); $today_url = remove_query_arg(array('cc_mini_month', 'cc_mini_year'), $current_url); // Generate unique ID $calendar_id = 'threecal-mini-' . wp_rand(1000, 9999); ob_start(); ?>
‹ get_month_name($month) . ' ' . $year); ?> ›
get_month_name($month) . ' ' . $year); ?>
$days_in_month) : ?>
get_weekday_initial(($i + $week_starts_on) % 7)); ?>
data-date-formatted="" data-events="" >
'; // Previous if ($current_page > 1) { $output .= ''; $output .= '« ' . esc_html__('Previous', '3task-calendar'); $output .= ''; } // Page numbers for ($i = 1; $i <= $total_pages; $i++) { if ($i === $current_page) { $output .= '' . $i . ''; } else { $output .= '' . $i . ''; } } // Next if ($current_page < $total_pages) { $output .= ''; $output .= esc_html__('Next', '3task-calendar') . ' »'; $output .= ''; } $output .= ''; return $output; } /** * Get month name */ private function get_month_name($month) { $months = array( 1 => __('January', '3task-calendar'), 2 => __('February', '3task-calendar'), 3 => __('March', '3task-calendar'), 4 => __('April', '3task-calendar'), 5 => __('May', '3task-calendar'), 6 => __('June', '3task-calendar'), 7 => __('July', '3task-calendar'), 8 => __('August', '3task-calendar'), 9 => __('September', '3task-calendar'), 10 => __('October', '3task-calendar'), 11 => __('November', '3task-calendar'), 12 => __('December', '3task-calendar') ); return isset($months[$month]) ? $months[$month] : ''; } /** * Get weekday name (short) */ private function get_weekday_name($day) { $days = array( 0 => __('Sun', '3task-calendar'), 1 => __('Mon', '3task-calendar'), 2 => __('Tue', '3task-calendar'), 3 => __('Wed', '3task-calendar'), 4 => __('Thu', '3task-calendar'), 5 => __('Fri', '3task-calendar'), 6 => __('Sat', '3task-calendar') ); return isset($days[$day]) ? $days[$day] : ''; } /** * Get weekday initial (single letter for mini calendar) */ private function get_weekday_initial($day) { $days = array( /* translators: Single letter abbreviation for Sunday */ 0 => _x('S', 'Sunday initial', '3task-calendar'), /* translators: Single letter abbreviation for Monday */ 1 => _x('M', 'Monday initial', '3task-calendar'), /* translators: Single letter abbreviation for Tuesday */ 2 => _x('T', 'Tuesday initial', '3task-calendar'), /* translators: Single letter abbreviation for Wednesday */ 3 => _x('W', 'Wednesday initial', '3task-calendar'), /* translators: Single letter abbreviation for Thursday */ 4 => _x('T', 'Thursday initial', '3task-calendar'), /* translators: Single letter abbreviation for Friday */ 5 => _x('F', 'Friday initial', '3task-calendar'), /* translators: Single letter abbreviation for Saturday */ 6 => _x('S', 'Saturday initial', '3task-calendar') ); return isset($days[$day]) ? $days[$day] : ''; } }