Event Management Guide

⚠️ Documentation Under Review: This documentation is currently being updated and verified against the actual implementation. Some information may be incorrect or incomplete. Please verify all code examples against the actual source code before use.

Overview

The Neuron CMS includes a comprehensive event management system for creating and managing calendar events. This feature enables you to create events with dates, times, locations, and categories, perfect for conferences, meetings, workshops, and other scheduled activities.

Architecture

Event Model

Location: Neuron\Cms\Models\Event

The Event model extends Neuron\Orm\Model and represents calendar events:

use Neuron\Orm\Model;
use Neuron\Orm\Attributes\Table;
use Neuron\Orm\Attributes\BelongsTo;

#[Table( 'events' )]
class Event extends Model
{
    #[BelongsTo( User::class, 'created_by' )]
    protected ?User $creator;

    #[BelongsTo( EventCategory::class, 'category_id' )]
    protected ?EventCategory $category;
}

Event Properties

Property Type Description
id int Event ID (auto-increment)
title string Event title
slug string URL-friendly identifier
description string Short event description
content_raw string Editor.js JSON content
location string Event location/venue
start_date DateTimeImmutable Event start date/time
end_date DateTimeImmutable Event end date/time (optional)
all_day bool All-day event flag
category_id int Event category ID
status string Publication status
featured_image string Featured image URL
organizer string Event organizer name
contact_email string Contact email address
contact_phone string Contact phone number
created_by int Creator user ID
view_count int Number of views
created_at DateTimeImmutable Creation timestamp
updated_at DateTimeImmutable Last update timestamp

Event Categories

Events can be organized into categories for better organization:

use Neuron\Orm\Model;
use Neuron\Orm\Attributes\Table;
use Neuron\Orm\Attributes\HasMany;

#[Table( 'event_categories' )]
class EventCategory extends Model
{
    #[HasMany( Event::class, 'category_id' )]
    protected array $events;
}

Event Status

Events use the same status workflow as content:

use Neuron\Cms\Enums\ContentStatus;

ContentStatus::Draft      // Not publicly visible
ContentStatus::Published  // Live and accessible

Creating Events

Via Code

use Neuron\Cms\Models\Event;
use Neuron\Cms\Repositories\DatabaseEventRepository;
use Neuron\Cms\Enums\ContentStatus;

$event = new Event();
$event->setTitle( 'Annual Conference 2025' );
$event->setSlug( 'annual-conference-2025' );
$event->setDescription( 'Join us for our annual conference' );
$event->setLocation( 'Convention Center, Main Hall' );
$event->setStartDate( new DateTimeImmutable( '2025-06-15 09:00:00' ) );
$event->setEndDate( new DateTimeImmutable( '2025-06-17 17:00:00' ) );
$event->setAllDay( false );
$event->setOrganizer( 'Tech Community' );
$event->setContactEmail( '[email protected]' );
$event->setStatus( ContentStatus::Published );

$repository = new DatabaseEventRepository( $database );
$repository->save( $event );

All-Day Events

For all-day events, set the flag and use date-only times:

$event->setAllDay( true );
$event->setStartDate( new DateTimeImmutable( '2025-06-15 00:00:00' ) );
$event->setEndDate( new DateTimeImmutable( '2025-06-15 23:59:59' ) );

Event Services

Creator

Creates new events with automatic slug generation:

use Neuron\Cms\Services\Event\Creator;
use Neuron\Cms\Repositories\DatabaseEventRepository;

$creator = new Creator( $eventRepository, $categoryRepository );

$event = $creator->create( title: 'Workshop: PHP Best Practices',
    startDate: new DateTimeImmutable( '2025-07-01 14:00:00' ),
    endDate: new DateTimeImmutable( '2025-07-01 17:00:00' ),
    location: 'Room 101',
    categoryId: 3,
    status: ContentStatus::Published
);

Updater

Updates existing events:

use Neuron\Cms\Services\Event\Updater;

$updater = new Updater( $eventRepository );

$updater->update( $event,
    title: 'Updated Workshop Title',
    location: 'Room 202' );

Querying Events

Upcoming Events

$repository = new DatabaseEventRepository( $settings );

// Get upcoming events
$upcomingEvents = $repository->getUpcoming( limit: 10 );

// Get events for specific date range
$events = $repository->getByDateRange( startDate: new DateTimeImmutable( '2025-06-01' ),
    endDate: new DateTimeImmutable( '2025-06-30' )
);

// Get events by category
$categoryEvents = $repository->getByCategory( $categoryId );

Past Events

// Get past events
$pastEvents = $repository->getPast( limit: 10 );

// Check if event has passed
if( $event->getEndDate() < new DateTimeImmutable() )
{
    // Event has ended
}

Event Display

Event List View

// In controller
$events = $repository->findUpcoming();

// In view
foreach( $events as $event )
{
    echo '<article>';
    echo '<h3>' . htmlspecialchars( $event->getTitle() ) . '</h3>';
    echo '<time>' . $event->getStartDate()->format( 'F j, Y g:i A' ) . '</time>';
    echo '<p>' . htmlspecialchars( $event->getLocation() ) . '</p>';
    echo '</article>';
}

Calendar Integration

Events can be integrated with calendar libraries:

// Generate iCal format
$ical = "BEGIN:VCALENDAR\r\n";
$ical .= "VERSION:2.0\r\n";
$ical .= "BEGIN:VEVENT\r\n";
$ical .= "SUMMARY:" . $event->getTitle() . "\r\n";
$ical .= "DTSTART:" . $event->getStartDate()->format( 'Ymd\THis' ) . "\r\n";
$ical .= "DTEND:" . $event->getEndDate()->format( 'Ymd\THis' ) . "\r\n";
$ical .= "LOCATION:" . $event->getLocation() . "\r\n";
$ical .= "END:VEVENT\r\n";
$ical .= "END:VCALENDAR\r\n";

Database Schema

Events are stored in two tables created by migrations:

events table

Created by 20251221000001_create_events_table.php:

event_categories table

Created by 20251221000000_create_event_categories_table.php:

Event Routes

Register routes for event display:

# config/routes.yaml
events:
  method: GET
  route: /events
  controller: App\Controllers\Events@index

event_detail:
  method: GET
  route: /events/{slug}
  controller: App\Controllers\Events@show

events_calendar:
  method: GET
  route: /events/calendar/{year}/{month}
  controller: App\Controllers\Events@calendar

Best Practices

Date Handling

Event Validation

Performance

Example: Complete Event System

<?php
namespace App\Controllers;

use Neuron\Cms\Repositories\DatabaseEventRepository;
use Neuron\Cms\Services\Event\EventCreator;

class EventsController extends Controller
{
    private DatabaseEventRepository $repository;

    public function __construct( DatabaseEventRepository $repository )
    {
        $this->repository = $repository;
    }

    public function index()
    {
        $upcoming = $this->repository->getUpcoming( limit: 20 );

        return $this->view( 'events/index', [
            'events' => $upcoming,
            'title' => 'Upcoming Events'
        ] );
    }

    public function show( string $slug )
    {
        $event = $this->repository->findBySlug( $slug );

        if( !$event )
{
            return $this->notFound();
        }

        // Increment view count
        $event->incrementViewCount();
        $this->repository->save( $event );

        return $this->view( 'events/show', [
            'event' => $event
        ] );
    }

    public function calendar( int $year, int $month )
    {
        $startDate = new DateTimeImmutable( "$year-$month-01" );
        $endDate = $startDate->modify( 'last day of this month' );

        $events = $this->repository->getByDateRange( $startDate, $endDate );

        return $this->view( 'events/calendar', [
            'events' => $events,
            'year' => $year,
            'month' => $month
        ] );
    }
}

Additional Resources