Event Calendar helps to manage events quickly with a better user experience. Mostly, the event calendar is embedded on a web page to list events date-wise. If the web application requires a calendar to organize events, you can build an event calendar with PHP easily. Nowadays Google Calendar is the most effective way to schedule events with no stress. The event created in the web application can be added to the Google Calendar automatically using REST API.
Sync with Google Calendar functionality makes event management featureful in the web application. You can add events programmatically to Google Calendar from the website using Calendar API. The Google Calendar API provides an easy way to add events to Google calendar with the REST API service. PHP can be used to the seamless integration of Google calendar event add functionality. This tutorial explains how to create event dynamically in the web application and add event to Google calendar from the website using PHP.
The following functionality will be implemented to add event to Google calendar with PHP.
Before getting started to build a PHP script to add event to Google calendar using PHP, take a look at the file structure.
google_calendar_add_event_with_php/ ├── config.php ├── dbConfig.php ├── index.php ├── addEvent.php ├── google_calendar_event_sync.php ├── GoogleCalendarApi.class.php └── css/ └── style.css
Google Project is required to get the API keys that will be used to make API calls to Google Calendar. If you already have an existing Google Application, API keys can be used from it. Just make sure that the Google Calendar API is enabled in this existing Google project. If you don’t any Google applications, follow the below steps to register your application on Google Developers Console and get the API keys.
A dialog box will appear with OAuth client details, note the Client ID and Client secret for later use in the script. This Client ID and Client secret allow you to access the Google Calendar API.
Note that: The Client ID and Client secret need to be specified at the time of the Google Calendar API call. Also, the Authorized redirect URIs must be matched with the Redirect URL specified in the script.
A table is required in the database to store event information on the local server. The following SQL creates an events
table with some basic fields in the MySQL database.
CREATE TABLE `events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`description` text COLLATE utf8_unicode_ci NOT NULL,
`location` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`date` date NOT NULL,
`time_from` time NOT NULL,
`time_to` time NOT NULL,
`google_calendar_event_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`created` datetime NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Google provides a PHP client library to make Calendar API calls, but it contains many additional services that come with a huge number of files and are large in size. To make the process simple, we build a custom library to handle the Google Calendar API calls with PHP.
Our Google API Library helps to authenticate with Google account and access the Calendar API using PHP. This custom PHP library will use Google Calendar v3 API to handle the event add process.
<?php
/**
*
* This Google Calendar API handler class is a custom PHP library to handle the Google Calendar API calls.
*
* @class GoogleCalendarApi
* @author CodexWorld
* @link http://www.codexworld.com
* @version 1.0
*/
class GoogleCalendarApi {
const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';
const CALENDAR_TIMEZONE_URI = 'https://www.googleapis.com/calendar/v3/users/me/settings/timezone';
const CALENDAR_LIST = 'https://www.googleapis.com/calendar/v3/users/me/calendarList';
const CALENDAR_EVENT = 'https://www.googleapis.com/calendar/v3/calendars/';
function __construct($params = array()) {
if (count($params) > 0){
$this->initialize($params);
}
}
function initialize($params = array()) {
if (count($params) > 0){
foreach ($params as $key => $val){
if (isset($this->$key)){
$this->$key = $val;
}
}
}
}
public function GetAccessToken($client_id, $redirect_uri, $client_secret, $code) {
$curlPost = 'client_id=' . $client_id . '&redirect_uri=' . $redirect_uri . '&client_secret=' . $client_secret . '&code='. $code . '&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::OAUTH2_TOKEN_URI);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if ($http_code != 200) {
$error_msg = 'Failed to receieve access token';
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
throw new Exception('Error '.$http_code.': '.$error_msg);
}
return $data;
}
public function GetUserCalendarTimezone($access_token) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::CALENDAR_TIMEZONE_URI);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if ($http_code != 200) {
$error_msg = 'Failed to fetch timezone';
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
throw new Exception('Error '.$http_code.': '.$error_msg);
}
return $data['value'];
}
public function GetCalendarsList($access_token) {
$url_parameters = array();
$url_parameters['fields'] = 'items(id,summary,timeZone)';
$url_parameters['minAccessRole'] = 'owner';
$url_calendars = self::CALENDAR_LIST.'?'. http_build_query($url_parameters);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_calendars);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if ($http_code != 200) {
$error_msg = 'Failed to get calendars list';
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
throw new Exception('Error '.$http_code.': '.$error_msg);
}
return $data['items'];
}
public function CreateCalendarEvent($access_token, $calendar_id, $event_data, $all_day, $event_datetime, $event_timezone) {
$apiURL = self::CALENDAR_EVENT . $calendar_id . '/events';
$curlPost = array();
if(!empty($event_data['summary'])){
$curlPost['summary'] = $event_data['summary'];
}
if(!empty($event_data['location'])){
$curlPost['location'] = $event_data['location'];
}
if(!empty($event_data['description'])){
$curlPost['description'] = $event_data['description'];
}
$event_date = !empty($event_datetime['event_date'])?$event_datetime['event_date']:date("Y-m-d");
$start_time = !empty($event_datetime['start_time'])?$event_datetime['start_time']:date("H:i:s");
$end_time = !empty($event_datetime['end_time'])?$event_datetime['end_time']:date("H:i:s");
if($all_day == 1){
$curlPost['start'] = array('date' => $event_date);
$curlPost['end'] = array('date' => $event_date);
}else{
$timezone_offset = $this->getTimezoneOffset($event_timezone);
$timezone_offset = !empty($timezone_offset)?$timezone_offset:'07:00';
$dateTime_start = $event_date.'T'.$start_time.$timezone_offset;
$dateTime_end = $event_date.'T'.$end_time.$timezone_offset;
$curlPost['start'] = array('dateTime' => $dateTime_start, 'timeZone' => $event_timezone);
$curlPost['end'] = array('dateTime' => $dateTime_end, 'timeZone' => $event_timezone);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token, 'Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($curlPost));
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if ($http_code != 200) {
$error_msg = 'Failed to create event';
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
throw new Exception('Error '.$http_code.': '.$error_msg);
}
return $data['id'];
}
private function getTimezoneOffset($timezone = 'America/Los_Angeles'){
$current = timezone_open($timezone);
$utcTime = new \DateTime('now', new \DateTimeZone('UTC'));
$offsetInSecs = timezone_offset_get($current, $utcTime);
$hoursAndSec = gmdate('H:i', abs($offsetInSecs));
return stripos($offsetInSecs, '-') === false ? "+{$hoursAndSec}" : "-{$hoursAndSec}";
}
}
?>
In the config.php
file, database settings and Google API configuration constant variables are defined.
Database constants:
Google API constants:
https://www.googleapis.com/auth/calendar
).Google OAuth URL:
$googleOauthURL
– The URL that allows the user to authenticate with Google account.<?php
// Database configuration
define('DB_HOST', 'MySQL_Database_Host');
define('DB_USERNAME', 'MySQL_Database_Username');
define('DB_PASSWORD', 'MySQL_Database_Password');
define('DB_NAME', 'MySQL_Database_Name');
// Google API configuration
define('GOOGLE_CLIENT_ID', 'Google_Project_Client_ID');
define('GOOGLE_CLIENT_SECRET', 'Google_Project_Client_Secret');
define('GOOGLE_OAUTH_SCOPE', 'https://www.googleapis.com/auth/calendar');
define('REDIRECT_URI', 'https://www.example.com/google_calendar_event_sync.php');
// Start session
if(!session_id()) session_start();
// Google OAuth URL
$googleOauthURL = 'https://accounts.google.com/o/oauth2/auth?scope=' . urlencode(GOOGLE_OAUTH_SCOPE) . '&redirect_uri=' . REDIRECT_URI . '&response_type=code&client_id=' . GOOGLE_CLIENT_ID . '&access_type=online';
?>
Note that: You’ll find the Client ID and Client Secret on the Google API Manager page of the API Console project.
The dbConfig.php
file is used to connect and select the MySQL database using PHP.
<?php
// Include configuration file
require_once 'config.php';
// Create database connection
$db = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Check connection
if ($db->connect_error) {
die("Connection failed: " . $db->connect_error);
}
Create an HTML form to input the event details (title, description, location, date, and time). On submit, the event data is posted to the server-side script (addEvent.php
) for further processing.
<?php
// Include configuration file
include_once 'config.php';
$postData = '';
if(!empty($_SESSION['postData'])){
$postData = $_SESSION['postData'];
unset($_SESSION['postData']);
}
$status = $statusMsg = '';
if(!empty($_SESSION['status_response'])){
$status_response = $_SESSION['status_response'];
$status = $status_response['status'];
$statusMsg = $status_response['status_msg'];
}
?>
<!-- Status message -->
<?php if(!empty($statusMsg)){ ?>
<div class="alert alert-<?php echo $status; ?>"><?php echo $statusMsg; ?></div>
<?php } ?>
<div class="col-md-12">
<form method="post" action="addEvent.php" class="form">
<div class="form-group">
<label>Event Title</label>
<input type="text" class="form-control" name="title" value="<?php echo !empty($postData['title'])?$postData['title']:''; ?>" required="">
</div>
<div class="form-group">
<label>Event Description</label>
<textarea name="description" class="form-control"><?php echo !empty($postData['description'])?$postData['description']:''; ?></textarea>
</div>
<div class="form-group">
<label>Location</label>
<input type="text" name="location" class="form-control" value="<?php echo !empty($postData['location'])?$postData['location']:''; ?>">
</div>
<div class="form-group">
<label>Date</label>
<input type="date" name="date" class="form-control" value="<?php echo !empty($postData['date'])?$postData['date']:''; ?>" required="">
</div>
<div class="form-group time">
<label>Time</label>
<input type="time" name="time_from" class="form-control" value="<?php echo !empty($postData['time_from'])?$postData['time_from']:''; ?>">
<span>TO</span>
<input type="time" name="time_to" class="form-control" value="<?php echo !empty($postData['time_to'])?$postData['time_to']:''; ?>">
</div>
<div class="form-group">
<input type="submit" class="form-control btn-primary" name="submit" value="Add Event"/>
</div>
</form>
</div>
The addEvent.php
file handles the event data insertion process to the MySQL database.
<?php
// Include database configuration file
require_once 'dbConfig.php';
$postData = $statusMsg = $valErr = '';
$status = 'danger';
// If the form is submitted
if(isset($_POST['submit'])){
// Get event info
$_SESSION['postData'] = $_POST;
$title = !empty($_POST['title'])?trim($_POST['title']):'';
$description = !empty($_POST['description'])?trim($_POST['description']):'';
$location = !empty($_POST['location'])?trim($_POST['location']):'';
$date = !empty($_POST['date'])?trim($_POST['date']):'';
$time_from = !empty($_POST['time_from'])?trim($_POST['time_from']):'';
$time_to = !empty($_POST['time_to'])?trim($_POST['time_to']):'';
// Validate form input fields
if(empty($title)){
$valErr .= 'Please enter event title.<br/>';
}
if(empty($date)){
$valErr .= 'Please enter event date.<br/>';
}
// Check whether user inputs are empty
if(empty($valErr)){
// Insert data into the database
$sqlQ = "INSERT INTO events (title,description,location,date,time_from,time_to,created) VALUES (?,?,?,?,?,?,NOW())";
$stmt = $db->prepare($sqlQ);
$stmt->bind_param("ssssss", $db_title, $db_description, $db_location, $db_date, $db_time_from, $db_time_to);
$db_title = $title;
$db_description = $description;
$db_location = $location;
$db_date = $date;
$db_time_from = $time_from;
$db_time_to = $time_to;
$insert = $stmt->execute();
if($insert){
$event_id = $stmt->insert_id;
unset($_SESSION['postData']);
// Store event ID in session
$_SESSION['last_event_id'] = $event_id;
header("Location: $googleOauthURL");
exit();
}else{
$statusMsg = 'Something went wrong, please try again after some time.';
}
}else{
$statusMsg = '<p>Please fill all the mandatory fields:</p>'.trim($valErr, '<br/>');
}
}else{
$statusMsg = 'Form submission failed!';
}
$_SESSION['status_response'] = array('status' => $status, 'status_msg' => $statusMsg);
header("Location: index.php");
exit();
?>
This script is set as Redirect URI in Google API settings. This means after authentication with Google account, the user will be redirected to this script that handles the Google Calendar event creation process with PHP.
GetAccessToken()
function of the GoogleCalendarApi class.GetUserCalendarTimezone()
function of the GoogleCalendarApi class.CreateCalendarEvent()
function of the GoogleCalendarApi class.<?php
// Include Google calendar api handler class
include_once 'GoogleCalendarApi.class.php';
// Include database configuration file
require_once 'dbConfig.php';
$statusMsg = '';
$status = 'danger';
if(isset($_GET['code'])){
// Initialize Google Calendar API class
$GoogleCalendarApi = new GoogleCalendarApi();
// Get event ID from session
$event_id = $_SESSION['last_event_id'];
if(!empty($event_id)){
// Fetch event details from database
$sqlQ = "SELECT * FROM events WHERE id = ?";
$stmt = $db->prepare($sqlQ);
$stmt->bind_param("i", $db_event_id);
$db_event_id = $event_id;
$stmt->execute();
$result = $stmt->get_result();
$eventData = $result->fetch_assoc();
if(!empty($eventData)){
$calendar_event = array(
'summary' => $eventData['title'],
'location' => $eventData['location'],
'description' => $eventData['description']
);
$event_datetime = array(
'event_date' => $eventData['date'],
'start_time' => $eventData['time_from'],
'end_time' => $eventData['time_to']
);
// Get the access token
$access_token_sess = $_SESSION['google_access_token'];
if(!empty($access_token_sess)){
$access_token = $access_token_sess;
}else{
$data = $GoogleCalendarApi->GetAccessToken(GOOGLE_CLIENT_ID, REDIRECT_URI, GOOGLE_CLIENT_SECRET, $_GET['code']);
$access_token = $data['access_token'];
$_SESSION['google_access_token'] = $access_token;
}
if(!empty($access_token)){
try {
// Get the user's calendar timezone
$user_timezone = $GoogleCalendarApi->GetUserCalendarTimezone($access_token);
// Create an event on the primary calendar
$google_event_id = $GoogleCalendarApi->CreateCalendarEvent($access_token, 'primary', $calendar_event, 0, $event_datetime, $user_timezone);
//echo json_encode([ 'event_id' => $event_id ]);
if($google_event_id){
// Update google event reference in the database
$sqlQ = "UPDATE events SET google_calendar_event_id=? WHERE id=?";
$stmt = $db->prepare($sqlQ);
$stmt->bind_param("si", $db_google_event_id, $db_event_id);
$db_google_event_id = $google_event_id;
$db_event_id = $event_id;
$update = $stmt->execute();
unset($_SESSION['last_event_id']);
unset($_SESSION['google_access_token']);
$status = 'success';
$statusMsg = '<p>Event #'.$event_id.' has been added to Google Calendar successfully!</p>';
$statusMsg .= '<p><a href="https://calendar.google.com/calendar/" target="_blank">Open Calendar</a>';
}
} catch(Exception $e) {
//header('Bad Request', true, 400);
//echo json_encode(array( 'error' => 1, 'message' => $e->getMessage() ));
$statusMsg = $e->getMessage();
}
}else{
$statusMsg = 'Failed to fetch access token!';
}
}else{
$statusMsg = 'Event data not found!';
}
}else{
$statusMsg = 'Event reference not found!';
}
$_SESSION['status_response'] = array('status' => $status, 'status_msg' => $statusMsg);
header("Location: index.php");
exit();
}
?>
Google Application Verification:
Google requires application verification to use Calendar API. You need to submit the application for verification to make Google project public.
In the development mode, you can test it by adding Test Users in the OAuth consent screen of the Google application.
HTTPS Protocol:
HTTPS is required for Google Calendar API authentication. So, the URL of the web script should be HTTPS enabled.
Login with Google Account using PHP
Adding website events to Google calendar is very helpful to notify application users effectively. If your web application has an event calendar, you can sync the events to the user’s Google calendar. This script helps to add events to Google calendar programmatically from the website using PHP. The Google calendar event create functionality is the best option to synchronize the events between the application and the user’s Google calendar.
Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request
Hello,
How would I get authentication code from GCP?
Will this run with PHP 5.6
Hi bought the code and works well, is there any script that can sync all event data in database as some are manually created from other applications.
Do you have the CSS for this one? thank you
is it possible to modify the script to add events without oauth screen (Using OAuth 2.0 for Server to Server)
Adding events to google calendar using php without login by more than one user
how to add guest in the meet using this code?
Hello,
thanks for the script. How can I add multi-day event?
Best Regards,
Roland