Project Overview
An Event Calendar Application allows users to view, add, edit, and delete events. This project covers event management, date handling, and dynamic content rendering using PHP and MySQL. It can be enhanced with features like recurring events, reminders, and calendar views.
Prerequisites
Ensure you have the following:
- Web Server: Apache (using XAMPP, WAMP, or MAMP)
- PHP: Version 7.4 or higher
- MySQL: For database management
- Code Editor: VS Code, Sublime Text, PHPStorm, etc.
- Composer: For dependency management (optional)
- Basic Understanding of Date and Time in PHP
Step-by-Step Procedure
1. Setting Up the Development Environment
- Install XAMPP:
- Download from XAMPP Official Website.
- Follow the installation wizard and install it in the default directory.
- Start Apache and MySQL:
- Open the XAMPP Control Panel.
- Start the Apache and MySQL modules.
2. Creating the Database
- Access phpMyAdmin:
- Navigate to
http://localhost/phpmyadmin/
in your browser.
- Navigate to
- Create a New Database:
- Click on “New” in the left sidebar.
- Name the database
event_calendar
. - Choose “utf8mb4_unicode_ci” as the collation.
- Click “Create”.
- Create an
events
Table:- Select the
event_calendar
database. - Click on “New” to create a table.
- Define the table with the following fields:
- Click “Save”.
- Select the
3. Project Structure
Organize your project files as follows:
event-calendar/
├── assets/
│ ├── css/
│ │ └── styles.css
│ └── js/
│ └── scripts.js
├── config/
│ └── db.php
├── templates/
│ ├── header.php
│ └── footer.php
├── add_event.php
├── edit_event.php
├── delete_event.php
├── view_event.php
├── calendar.php
├── index.php
└── README.md
4. Configuration
a. Database Connection (config/db.php
)
Create a file named db.php
inside the config
directory to handle database connections.
<?php
// config/db.php
$host = 'localhost';
$db = 'event_calendar';
$user = 'root'; // Default XAMPP MySQL user
$pass = ''; // Default XAMPP MySQL password is empty
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // Enable exceptions
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // Fetch associative arrays
PDO::ATTR_EMULATE_PREPARES => false, // Disable emulation
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
// Handle connection errors
http_response_code(500);
echo "Database connection failed.";
exit;
}
?>
5. Creating Reusable Templates
a. Header (templates/header.php
)
<?php
// templates/header.php
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Event Calendar Application</title>
<link rel="stylesheet" href="/event-calendar/assets/css/styles.css">
</head>
<body>
<header>
<h1>Event Calendar Application</h1>
<nav>
<a href="/event-calendar/index.php">Home</a>
<a href="/event-calendar/add_event.php">Add Event</a>
<a href="/event-calendar/calendar.php">View Calendar</a>
</nav>
</header>
<main>
b. Footer (templates/footer.php
)
<?php
// templates/footer.php
?>
</main>
<footer>
<p>© <?php echo date("Y"); ?> Your Company Name</p>
</footer>
<script src="/event-calendar/assets/js/scripts.js"></script>
</body>
</html>
6. Styling the Application (assets/css/styles.css
)
Add basic styles to enhance the appearance.
/* assets/css/styles.css */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
header, footer {
background-color: #333;
color: #fff;
padding: 10px 20px;
}
header h1, footer p {
margin: 0;
}
nav a {
color: #fff;
margin-right: 15px;
text-decoration: none;
}
main {
padding: 20px;
}
form {
max-width: 600px;
margin: auto;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
}
input[type="text"],
input[type="date"],
textarea {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
button {
padding: 10px 15px;
background-color: #007BFF;
color: #fff;
border: none;
cursor: pointer;
}
button:hover {
background-color: #0069d9;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
table, th, td {
border: 1px solid #ddd;
}
th, td {
padding: 12px;
text-align: left;
}
th {
background-color: #f4f4f4;
}
a {
color: #007BFF;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.error {
background-color: #f8d7da;
color: #842029;
padding: 15px;
margin-bottom: 20px;
border: 1px solid #f5c2c7;
border-radius: 4px;
}
.success {
background-color: #d1e7dd;
color: #0f5132;
padding: 15px;
margin-bottom: 20px;
border: 1px solid #badbcc;
border-radius: 4px;
}
.calendar {
width: 100%;
border-collapse: collapse;
}
.calendar th,
.calendar td {
border: 1px solid #ddd;
padding: 10px;
text-align: center;
vertical-align: top;
height: 100px;
}
.calendar th {
background-color: #f4f4f4;
}
.event {
background-color: #ffc107;
padding: 2px 5px;
margin-top: 5px;
border-radius: 3px;
font-size: 0.9em;
}
7. Adding a New Event (add_event.php
)
This page allows users to add new events to the calendar.
<?php
// add_event.php
require 'config/db.php';
require 'templates/header.php';
$errors = [];
$success = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Sanitize and validate inputs
$title = trim($_POST['title']);
$description = trim($_POST['description']);
$event_date = trim($_POST['event_date']);
if (empty($title)) {
$errors[] = 'Event title is required.';
}
if (empty($event_date)) {
$errors[] = 'Event date is required.';
} elseif (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $event_date)) {
$errors[] = 'Invalid date format.';
}
if (empty($errors)) {
// Insert into database
$stmt = $pdo->prepare('INSERT INTO events (title, description, event_date) VALUES (?, ?, ?)');
if ($stmt->execute([$title, $description, $event_date])) {
$success = 'Event added successfully.';
// Clear form fields
$title = $description = $event_date = '';
} else {
$errors[] = 'There was an error adding the event. Please try again.';
}
}
}
?>
<h2>Add New Event</h2>
<?php if (!empty($errors)): ?>
<div class="error">
<ul>
<?php foreach($errors as $error): ?>
<li><?php echo htmlspecialchars($error); ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="success">
<p><?php echo htmlspecialchars($success); ?></p>
</div>
<?php endif; ?>
<form action="add_event.php" method="POST">
<div class="form-group">
<label for="title">Event Title:</label>
<input type="text" id="title" name="title" value="<?php echo htmlspecialchars($title ?? ''); ?>" required>
</div>
<div class="form-group">
<label for="description">Event Description:</label>
<textarea id="description" name="description" rows="5"><?php echo htmlspecialchars($description ?? ''); ?></textarea>
</div>
<div class="form-group">
<label for="event_date">Event Date:</label>
<input type="date" id="event_date" name="event_date" value="<?php echo htmlspecialchars($event_date ?? ''); ?>" required>
</div>
<button type="submit">Add Event</button>
</form>
<?php
require 'templates/footer.php';
?>
8. Viewing All Events (index.php
)
This page lists all upcoming and past events with options to view, edit, or delete them.
<?php
// index.php
require 'config/db.php';
require 'templates/header.php';
// Fetch all events
$stmt = $pdo->query('SELECT * FROM events ORDER BY event_date DESC');
$events = $stmt->fetchAll();
?>
<h2>All Events</h2>
<?php if ($events): ?>
<table>
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Event Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($events as $event): ?>
<tr>
<td><?php echo htmlspecialchars($event['id']); ?></td>
<td><?php echo htmlspecialchars($event['title']); ?></td>
<td><?php echo htmlspecialchars($event['event_date']); ?></td>
<td>
<a href="view_event.php?id=<?php echo $event['id']; ?>">View</a> |
<a href="edit_event.php?id=<?php echo $event['id']; ?>">Edit</a> |
<a href="delete_event.php?id=<?php echo $event['id']; ?>" onclick="return confirm('Are you sure you want to delete this event?');">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p>No events found. <a href="add_event.php">Add a new event</a>.</p>
<?php endif; ?>
<?php
require 'templates/footer.php';
?>
9. Viewing a Single Event (view_event.php
)
This page displays the full details of a single event.
<?php
// view_event.php
require 'config/db.php';
require 'templates/header.php';
// Get event ID from URL
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
// Fetch event details
$stmt = $pdo->prepare('SELECT * FROM events WHERE id = ?');
$stmt->execute([$id]);
$event = $stmt->fetch();
if ($event):
?>
<h2><?php echo htmlspecialchars($event['title']); ?></h2>
<p><strong>Date:</strong> <?php echo htmlspecialchars($event['event_date']); ?></p>
<p><strong>Description:</strong><br><?php echo nl2br(htmlspecialchars($event['description'])); ?></p>
<a href="index.php">Back to All Events</a>
<?php
else:
echo "<p>Event not found.</p>";
endif;
require 'templates/footer.php';
?>
10. Editing an Event (edit_event.php
)
This page allows users to update existing event details.
<?php
// edit_event.php
require 'config/db.php';
require 'templates/header.php';
$errors = [];
$success = '';
// Get event ID from URL
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
// Fetch existing event
$stmt = $pdo->prepare('SELECT * FROM events WHERE id = ?');
$stmt->execute([$id]);
$event = $stmt->fetch();
if (!$event) {
echo "<p>Event not found.</p>";
require 'templates/footer.php';
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Sanitize and validate inputs
$title = trim($_POST['title']);
$description = trim($_POST['description']);
$event_date = trim($_POST['event_date']);
if (empty($title)) {
$errors[] = 'Event title is required.';
}
if (empty($event_date)) {
$errors[] = 'Event date is required.';
} elseif (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $event_date)) {
$errors[] = 'Invalid date format.';
}
if (empty($errors)) {
// Update in database
$stmt = $pdo->prepare('UPDATE events SET title = ?, description = ?, event_date = ? WHERE id = ?');
if ($stmt->execute([$title, $description, $event_date, $id])) {
$success = 'Event updated successfully.';
// Refresh event data
$stmt = $pdo->prepare('SELECT * FROM events WHERE id = ?');
$stmt->execute([$id]);
$event = $stmt->fetch();
} else {
$errors[] = 'There was an error updating the event. Please try again.';
}
}
}
?>
<h2>Edit Event</h2>
<?php if (!empty($errors)): ?>
<div class="error">
<ul>
<?php foreach($errors as $error): ?>
<li><?php echo htmlspecialchars($error); ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="success">
<p><?php echo htmlspecialchars($success); ?></p>
</div>
<?php endif; ?>
<form action="edit_event.php?id=<?php echo $id; ?>" method="POST">
<div class="form-group">
<label for="title">Event Title:</label>
<input type="text" id="title" name="title" value="<?php echo htmlspecialchars($event['title']); ?>" required>
</div>
<div class="form-group">
<label for="description">Event Description:</label>
<textarea id="description" name="description" rows="5"><?php echo htmlspecialchars($event['description']); ?></textarea>
</div>
<div class="form-group">
<label for="event_date">Event Date:</label>
<input type="date" id="event_date" name="event_date" value="<?php echo htmlspecialchars($event['event_date']); ?>" required>
</div>
<button type="submit">Update Event</button>
</form>
<?php
require 'templates/footer.php';
?>
11. Deleting an Event (delete_event.php
)
This script handles the deletion of events.
<?php
// delete_event.php
require 'config/db.php';
// Get event ID from URL
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
// Delete event
$stmt = $pdo->prepare('DELETE FROM events WHERE id = ?');
$stmt->execute([$id]);
// Redirect back to all events
header('Location: index.php');
exit;
?>
12. Viewing the Event Calendar (calendar.php
)
This page displays events in a calendar format.
<?php
// calendar.php
require 'config/db.php';
require 'templates/header.php';
// Fetch all events
$stmt = $pdo->query('SELECT * FROM events ORDER BY event_date ASC');
$events = $stmt->fetchAll();
// Organize events by date
$events_by_date = [];
foreach ($events as $event) {
$events_by_date[$event['event_date']][] = $event;
}
// Get current month and year
$month = isset($_GET['month']) ? (int)$_GET['month'] : date('n');
$year = isset($_GET['year']) ? (int)$_GET['year'] : date('Y');
// Number of days in the month
$num_days = cal_days_in_month(CAL_GREGORIAN, $month, $year);
// First day of the month
$first_day = date('w', strtotime("$year-$month-01"));
// Previous and next month/year for navigation
$prev_month = $month - 1;
$prev_year = $year;
if ($prev_month < 1) {
$prev_month = 12;
$prev_year -= 1;
}
$next_month = $month + 1;
$next_year = $year;
if ($next_month > 12) {
$next_month = 1;
$next_year += 1;
}
?>
<h2>Event Calendar - <?php echo date('F Y', strtotime("$year-$month-01")); ?></h2>
<div class="calendar-navigation">
<a href="calendar.php?month=<?php echo $prev_month; ?>&year=<?php echo $prev_year; ?>">« Previous</a>
<a href="calendar.php?month=<?php echo $next_month; ?>&year=<?php echo $next_year; ?>">Next »</a>
</div>
<table class="calendar">
<thead>
<tr>
<th>Sun</th>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
<th>Sat</th>
</tr>
</thead>
<tbody>
<?php
$day = 1;
for ($week = 0; $week < 6; $week++) { // Maximum 6 weeks in a month
echo "<tr>";
for ($d = 0; $d < 7; $d++) {
if ($week === 0 && $d < $first_day) {
echo "<td></td>";
} elseif ($day > $num_days) {
echo "<td></td>";
} else {
$current_date = "$year-$month-" . str_pad($day, 2, '0', STR_PAD_LEFT);
echo "<td>";
echo "<strong>$day</strong><br>";
if (isset($events_by_date[$current_date])) {
foreach ($events_by_date[$current_date] as $event) {
echo "<div class='event'><a href='view_event.php?id={$event['id']}'>{$event['title']}</a></div>";
}
}
echo "</td>";
$day++;
}
}
echo "</tr>";
if ($day > $num_days) {
break;
}
}
?>
</tbody>
</table>
<?php
require 'templates/footer.php';
?>
13. Testing the Application
- Access the Event Calendar:
- Navigate to
http://localhost/event-calendar/calendar.php
. - Verify that the current month’s calendar is displayed with events marked on their respective dates.
- Navigate to
- Add a New Event:
- Navigate to
http://localhost/event-calendar/add_event.php
. - Fill in the event details and submit.
- Verify that the event appears on the calendar and in the list of all events.
- Navigate to
- View an Event:
- Click on an event title in the calendar or events list.
- Ensure that the full event details are displayed.
- Edit an Event:
- Navigate to
http://localhost/event-calendar/edit_event.php?id={event_id}
. - Update event details and submit.
- Verify that changes are reflected on the calendar and events list.
- Navigate to
- Delete an Event:
- Click on “Delete” next to an event in the events list.
- Confirm deletion.
- Ensure that the event is removed from the calendar and database.
14. Deployment Considerations
When deploying your Event Calendar Application to a live server, consider the following:
- Time Zone Settings:
- Ensure that your PHP and database time zones are correctly configured to display accurate event dates.
- Input Validation:
- Thoroughly validate all user inputs to prevent SQL injection and other attacks.
- Use HTTPS:
- Secure data transmission by implementing HTTPS.
- Error Handling:
- Provide user-friendly error messages without exposing sensitive information.
- Optimize Performance:
- Implement caching strategies for frequently accessed data to enhance performance.
- Regular Backups:
- Schedule regular backups of your database to prevent data loss.
- Responsive Design:
- Enhance the calendar’s responsiveness for better viewing on different devices.
15. Enhancements and Best Practices
- Recurring Events:
- Implement functionality for recurring events (daily, weekly, monthly).
- Event Reminders:
- Send email or SMS reminders to users about upcoming events.
- User Roles:
- Assign roles (admin, user) to control who can add or manage events.
- Search and Filter:
- Allow users to search for events by title or filter by date ranges.
- Integration with Google Calendar:
- Enable users to sync events with their Google Calendar.
- API Integration:
- Expose events data via a RESTful API for integration with other applications.