Search code examples
phplaraveleloquentlaravel-4grouping

Group Events by Week Commencing in Eloquent


I have the following method in my Event model for my events:

public static function getEvents($perPage = 10)
{
    $events = Event::where('active', '=', 1)->paginate($perPage);

    return $events;
}

Each event has a start_date and I need to take that start date and group the results in the view by week commencing, as in the Monday of the week each event occurs. I have this in my controller:

public function index()
{
    $events = Event::getEvents($perPage = 5);

    $this->layout->content = View::make('events.index')->with('events', $events);
}

Can anyone help me out with grouping these events by week commencing? Thanks.

I'm part way there in terms of getting the week commencing date using:

foreach ($events as $event)
{
    $start_date = DateTime::createFromFormat('Y-m-d', $event->start_date);
    $week = $start_date->format('YW');
    $monday = 1;

    $day_offset = ($monday - $start_date->format('N'));

    $week_commencing = $start_date->modify("$day_offset days");
    $week_commencing = $week_commencing->format('jS F Y');
}

Now I just need to use that to group the events but I'm not sure how to.

EDIT: I feel I'm getting closer to a solution but still need a little help. I now have the below in my controller, and it does print out 1 week commencing then all the events but when var_dump(ing) the $events->weeks_commencing there is only 1 date in the object, so I'm nearly there. Any pointers guys?:

    foreach ($events as $event)
    {
        $start_date = DateTime::createFromFormat('Y-m-d', $event->start_date);
        $week = $start_date->format('YW');
        $monday = 1;

        $day_offset = ($monday - $start_date->format('N'));

        $week_commencing = $start_date->modify("$day_offset days");

        if (!array_key_exists($week, $events))
        {
            $events->weeks_commencing = (object) array(
                'week'      => $week_commencing->format('jS F Y')
            );
        }
    }

EDIT: OK I now have this in my controller. It's getting closer but not quite right yet.

    foreach ($events as $event)
    {
        $start_date = DateTime::createFromFormat('Y-m-d', $event->start_date);
        $week = $start_date->format('YW');
        $monday = 1;

        $day_offset = ($monday - $start_date->format('N'));

        $week_commencing = $start_date->modify("$day_offset days");

        if (array_key_exists($week, $events))
        {
            $events = (object) array(
                'week'      => $week_commencing->format('jS F Y'),
                'events'    => array()
            );
        }

        $events->events[] = $event;
    }

Solution

  • OK, so I've solved my issue now, with the following code:

    public function index()
    {
        $events = Event::getEvents($perPage = 10);
    
        $events_by_week = array();
    
        foreach ($events as $event)
        {
            $start_date = DateTime::createFromFormat('Y-m-d', $event->start_date);
            $week = $start_date->format('YW');
            $monday = 1;
    
            $day_offset = ($monday - $start_date->format('N'));
    
            $week_commencing = $start_date->modify("$day_offset days");
    
            if (!array_key_exists($week, $events_by_week))
            {
                $events_by_week[$week] = (object) array(
                    'week'      => $week_commencing->format('jS F Y'),
                    'events'    => array()
                );
            }
    
            $events_by_week[$week]->events[] = $event;
        }
    
        $this->layout->content = View::make('events.index')->with(array('events_by_week' => $events_by_week, 'events' => $events));
    }