Generating calendar using php Carbon in Laravel showing multiple dates while going though foreach loop for adding extarenal data

Viewed 24

I am trying to build a simple calendar using Carbon in Laravel 9. Also, I need to show some content from the database on specific dates. The calendar is well made without the other contents but with content, some dates which don't have external data are duplicated.

The controller code

 $date = empty($date) ? Carbon::now() : Carbon::createFromDate($date);
            $startOfCalendar = $date->copy()->firstOfMonth()->startOfWeek(Carbon::SUNDAY);
            $endOfCalendar = $date->copy()->lastOfMonth()->endOfWeek(Carbon::SATURDAY);

            $html = '<div class="calendar">';

            $html .= '<div class="month-year">';
            $html .= '<span class="month">' . $date->format('M') . '</span>';
            $html .= '<span class="year">' . $date->format('Y') . '</span>';
            $html .= '</div>';

            $html .= '<div class="days">';

            $dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
            foreach ($dayLabels as $dayLabel)
            {
                $html .= '<span class="day-label">' . $dayLabel . '</span>';
            }

            $get_events = CalendarEvents::where("event_date",">=",date("Y-m-d", strtotime($startOfCalendar)))->get();

            while($startOfCalendar <= $endOfCalendar)
            {
                $extraClass = $startOfCalendar->format('m') != $date->format('m') ? 'dull' : '';
                $extraClass .= $startOfCalendar->isToday() ? ' today' : '';
                foreach ($get_events as $events) {
                    if($events->event_date == date('Y-m-d',strtotime($startOfCalendar))) {
                        $html .= '<span class="day flip' . $extraClass . '"><span class="content">' . $startOfCalendar->format('j').'|'.$events->event_name. '</span></span>';

                    }
                    else {
                        $html .= '<span class="day' . $extraClass . '"><span class="content">' . $startOfCalendar->format('j') . '</span></span>';
                        break;
                    }
                    }

                $startOfCalendar->addDay();
            }
            $html .= '</div></div>';
            

Here the events' dates are printed once but dates without the events are printed multiple times. How can I correct this? Thanks in advance

1 Answers

your loop seems a bit off. Assuming you have multiple events on some days and no events on others, you probably want something like the following.

$date = empty($date) ?Carbon::now() : Carbon::createFromDate($date);
$startOfCalendar = $date->copy()->firstOfMonth()->startOfWeek(Carbon::SUNDAY);
$endOfCalendar = $date->copy()->lastOfMonth()->endOfWeek(Carbon::SATURDAY);

$html = '<div class="calendar">';

$html .= '<div class="month-year">';
$html .= '<span class="month">' . $date->format('M') . '</span>';
$html .= '<span class="year">' . $date->format('Y') . '</span>';
$html .= '</div>';

$html .= '<div class="days">';

$dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
foreach ($dayLabels as $dayLabel) 
{
    $html .= '<span class="day-label">' . $dayLabel . '</span>';
}

$get_events = CalendarEvents::where("event_date", ">=", date("Y-m-d", strtotime($startOfCalendar)))->get();

while ($startOfCalendar <= $endOfCalendar) 
{
    $extraClass = $startOfCalendar->format('m') != $date->format('m') ? 'dull' : '';
    $extraClass .= $startOfCalendar->isToday() ? ' today' : '';

    $startOfCalendarFormated = $startOfCalendar->format('j');
    $startOfCalendarSqlFormat = $startOfCalendar->format('Y-m-d');

    $html .= '<span class="day flip' . $extraClass . '"><span class="content">';

    $filled = false;
    foreach ($get_events as $events) {
        if ($events->event_date == $startOfCalendarSqlFormat) {
            $html .= $startOfCalendarFormated . '|' . $events->event_name . "<br>";
            $filled = true;
        }
    }

    if(!$filled){
        $html .= "No events | {$startOfCalendarFormated}";
    }

    $html .= '</span></span>';

    $startOfCalendar->addDay();
}
$html .= '</div></div>';

I'm making assumptions on how you want your HTML formatted, but hopefully you get the picture.

Related