Event Calendar - weekly view

94 posts by 3 authors in: Forums > CMS Builder
Last Post: January 13   (RSS)

Thank you, that's worked

By Djulia - November 25 - edited: November 25

Hi MercerDesign,

Can you try with this version? Thanks!

Djulia

Attachments:

calendar_functions.php 32K

Amazing, thank you

By Djulia - November 26 - edited: November 26

Thanks! You could perhaps add a vertical-align:top to the cell to align the events. It's just a suggestion.

.calendar-week th, .calendar-week td {
	width: 80px;
	border: 1px solid #ccc;
	padding: 10px;
	text-align: left;
	word-wrap: break-word;
	vertical-align: top;
}

Hi, my client needs to show an event that happens at midnight, I tried updating the calendar_functions file but it didn't update anything. Can you help please? I've attached my latest working files.

By Djulia - December 16 - edited: December 16

Hi MercerDesign,

Can you try with this version? Thanks!

Djulia

Attachments:

calendar_functions.php 33K

Thank you

It would be cool if this could support RRule for repeating events like the 3rd Wednesday of every month for 12 months.

Jeff Shields
yaadev.com

By Djulia - December 18 - edited: December 18

Hi Jeff,

Thanks for the suggestion! Supporting RRule is a great idea for handling complex recurring events like "the 3rd Wednesday of every month for 12 months."

To integrate support for the RRule standard, we can use the PHP Recurr library.

Step 1: Add Recurr to the project via Composer

composer require simshaun/recurr

Step 2: Pre-processing events

use Recurr\Rule;
use Recurr\Transformer\ArrayTransformer;

/**
 * Expands events based on their RRule (recurrence rule).
 *
 * This function processes an array of events, checks if each event has an RRule, 
 * and generates the corresponding occurrences based on the RRule. If an event 
 * does not have an RRule, it is added to the result as is. For events with 
 * valid recurrence rules, the function will expand them into multiple occurrences
 * and return the list of expanded events.
 *
 * @param array $events The array of events, where each event can have an optional 'rrule' key.
 * @return array The array of expanded events with start and end dates adjusted for each occurrence.
 */
function expandRRuleEvents(array $events): array {
    $expandedEvents = [];
    $transformer = new ArrayTransformer();

    foreach ($events as $event) {
        // If the event has no RRule, add it as is
        if (empty($event['rrule'])) {
            $expandedEvents[] = $event;
            continue;
        }

        // Extract original time (hours, minutes, seconds) from the start and end dates
        $originalStartTime = (new DateTime($event['start_date']))->format('H:i:s');
        $originalEndTime = (new DateTime($event['end_date']))->format('H:i:s');

        // Ensure the event has a valid recurrence rule
        try {
            $rule = new Rule($event['rrule'], new DateTime($event['start_date']));
            $occurrences = $transformer->transform($rule);

            foreach ($occurrences as $occurrence) {
                $newEvent = $event;

                // Adjust start and end dates by applying the original time
                $newEvent['start_date'] = $occurrence->getStart()->format('Y-m-d') . ' ' . $originalStartTime;
                $newEvent['end_date'] = $occurrence->getEnd()->format('Y-m-d') . ' ' . $originalEndTime;

                unset($newEvent['rrule']); // Remove the RRule key to avoid unnecessary duplicates

                $expandedEvents[] = $newEvent;
            }
        } catch (Exception $e) {
            // If the rule is invalid, log the error and skip the event
            error_log("RRule processing error: " . $e->getMessage());
        }
    }

    return $expandedEvents;
}

Before calling renderMonthCalendar, we can apply pre-processing to the events.

// Displays the monthly view with events for the month
$expandedEvents = expandRRuleEvents($events);
renderMonthCalendar($month, $year, $expandedEvents, $weekStart, $lang, $translations);

Here’s an example of an event with an RRule:

$events = [
    [
        'title' => 'Team Meeting',
        'start_date' => '2024-01-17 10:00:00',
        'end_date' => '2024-01-17 11:00:00',
        'description' => 'Monthly team sync-up',
        'location' => 'Conference Room',
        'rrule' => 'FREQ=MONTHLY;BYDAY=3WE;COUNT=12',           // RRule for the 3rd Wednesday of each month.
        //'rrule' => 'FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=12',     // Repeat the event every Monday, Wednesday, and Friday for 12 occurrences.
        //'rrule' => 'FREQ=YEARLY;BYDAY=1MO;BYMONTH=1;COUNT=5', // Repeat the event on the first Monday of January, every year, for 5 years.
        //'rrule' => 'FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=10',     // Repeat the event every Monday, Wednesday, and Friday for 10 occurrences.
    ],
];

With this integration, the calendar becomes compatible with complex rules defined by RRule while retaining the flexibility to handle simple or one-time events.

Thanks,
Djulia