Add Event to Google Calendar using PHP

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.

  • Build an HTML form to collect event details (title, description, location, date, and time.
  • Create and insert event data in the database.
  • Add event to Google Calendar from PHP script.
  • Display event creation status with a link to open Google calendar.

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

Create Google Project and Enable Calendar API

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.

  • Go to the Google API Console.
  • Select an existing project from the projects list, or click NEW PROJECT to create a new project:
    google-api-console-project-create-codexworld
    • Type the Project Name.
    • The project ID will be created automatically under the Project Name field. (Optional) You can change this project ID by the Edit link, but it should be unique worldwide.
    • Click the CREATE button.
  • Select the newly created project and enable the Google Calendar API service.
    • In the sidebar, select Library under the APIs & Services section.
    • Search for the Google Calendar API service in the API list and select Google Calendar API.
    • Click the ENABLE button to make the Google Calendar API Library available.
  • In the sidebar, select Credentials under the APIs & Services section.
  • Select the OAuth consent screen tab, specify the consent screen settings.
    • Enter the Application name.
    • Choose a Support email.
    • Specify the Authorized domains which will be allowed to authenticate using OAuth.
    • Click the Save button.
  • Select the Credentials tab, click the Create credentials drop-down and select OAuth client ID.
    • In the Application type section, select Web application.
    • In the Authorized redirect URIs field, specify the redirect URL.
    • Click the Create button.

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.

google-api-console-project-oauth-api-key-client-id-secret-codexworld

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.

Create Database Table

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 Calendar API PHP Library

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.

  • GetAccessToken() – Fetch the access token from Google OAuth 2 API using authentication code.
  • GetUserCalendarTimezone() – Fetch the user’s timezone from Google calendar settings.
  • GetCalendarsList() – Get the calendar list of the user.
  • CreateCalendarEvent() – Create an event and add it to the users’ Google calendar.
<?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($chCURLOPT_URLself::OAUTH2_TOKEN_URI);        
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);        
        
curl_setopt($chCURLOPT_POST1);        
        
curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);
        
curl_setopt($chCURLOPT_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($chCURLOPT_URLself::CALENDAR_TIMEZONE_URI);        
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);    
        
curl_setopt($chCURLOPT_HTTPHEADER, array('Authorization: Bearer '$access_token));    
        
curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);    
        
$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($chCURLOPT_URL$url_calendars);        
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);    
        
curl_setopt($chCURLOPT_HTTPHEADER, array('Authorization: Bearer '$access_token));    
        
curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);    
        
$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($chCURLOPT_URL$apiURL);        
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);        
        
curl_setopt($chCURLOPT_POST1);        
        
curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);
        
curl_setopt($chCURLOPT_HTTPHEADER, array('Authorization: Bearer '$access_token'Content-Type: application/json'));    
        
curl_setopt($chCURLOPT_POSTFIELDSjson_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}";
    }
}
?>

Database and API Configuration (config.php)

In the config.php file, database settings and Google API configuration constant variables are defined.

Database constants:

  • DB_HOST – Specify the database host.
  • DB_USERNAME – Specify the database username.
  • DB_PASSWORD – Specify the database password.
  • DB_NAME – Specify the database name.

Google API constants:

  • GOOGLE_CLIENT_ID – Specify the Google Project Client ID.
  • GOOGLE_CLIENT_SECRET – Specify the Google Project Client Secret.
  • GOOGLE_OAUTH_SCOPE – Specify the OAuth scope for Google authentication (set to https://www.googleapis.com/auth/calendar).
  • REDIRECT_URI – Specify the Callback URL.

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.

Database Connection (dbConfig.php)

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_HOSTDB_USERNAMEDB_PASSWORDDB_NAME);

// Check connection
if ($db->connect_error) {
    die(
"Connection failed: " $db->connect_error);
}

Event Creation Form (index.php)

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>

Add Event to Database (addEvent.php)

The addEvent.php file handles the event data insertion process to the MySQL database.

  • Retrieve event info from the user’s input using PHP $_POST variable.
  • Validate input to check whether mandatory fields are empty.
  • Insert event data in the database using PHP and MySQL.
  • Redirect user to the OAuth URL for authentication with Google account.
<?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();
?>

Add Event to Google Calendar (google_calendar_event_sync.php)

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.

  • Get OAuth code from the query string of the URL using PHP $_GET variable.
  • Include and initialize the Google Calendar API handler class.
  • Get event reference ID of the local database from SESSION.
  • Fetch the event details from the database based on the reference ID.
  • Prepare event data (summary, description, location, date, start time, and end time) for Google calendar.
  • Get access token by authentication code using GetAccessToken() function of the GoogleCalendarApi class.
  • Get user’s timezone from Google calendar settings using GetUserCalendarTimezone() function of the GoogleCalendarApi class.
  • Create an event and add it to Google calendar using the CreateCalendarEvent() function of the GoogleCalendarApi class.
  • Update google event reference in the database.
  • Display event creation status with Google calendar access link.
<?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_IDREDIRECT_URIGOOGLE_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_event0$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();
}
?>

Checklist for Testing

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.

  • On the OAuth Client credentials page, click the OAuth consent screen link.
    google-api-console-oauth-client-credentials-codexworld
  • In the OAuth consent screen page, add users under the Test users section.
    google-api-console-oauth-consent-test-user-codexworld

HTTPS Protocol:
HTTPS is required for Google Calendar API authentication. So, the URL of the web script should be HTTPS enabled.

  • You can test the Google Calendar API integration on the localhost server with HTTP.

Login with Google Account using PHP

Conclusion

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

8 Comments

  1. Pankaj Said...
  2. GD Said...
  3. RW Said...
  4. Ymart Said...
  5. Monny Said...
  6. Hieu Said...
  7. Samuel Said...
  8. Roland Said...

Leave a reply

keyboard_double_arrow_up