Google Calendar API using Zend Library - php

I'm following the tutorial on http://www.ibm.com/developerworks/library/x-googleclndr/ for working with the Google Calendar API, but I'm running into some strange problems. My PHP code looks like this
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');
Zend_Loader::loadClass('Zend_Http_Client');
//create authenticated HTTP client for Calendar service
$gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
$user = "daniel.lieberman610#gmail.com";
$pass = "*******";
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $gcal);
$gcal = new Zend_Gdata_Calendar($client);
//generate query to get event list
$query = $gcal->newEventQuery();
$query->setUser($user);
$query->setVisibility('private');
$query->setProjection('basic');
//get and parse calendar feed
//print output
try {
$feed = $gcal->getCalendarEventFeed($query);
echo "<!--comment-->\n";
} catch (Exception $e) {
echo "<!--different comment-->\n";
}
Some kind of exception is occurring inside the try block, but not the Zend_Gdata_App_Exception because the error message is not being displayed. I can't figure out what I'm doing wrong.
Also, I am learning PHP as I go along here. Thanks a lot for your help.

Move the try code to the beginning of the file. Is there an error shown? Here you will find a working example which I'm using in my Joomla extension https://github.com/Digital-Peak/GCalendar/blob/master/com_gcalendar/admin/libraries/GCalendar/GCalendarZendHelper.php
By the way I suggest to move to the new google calendar API v3 because they shut down version 2 (which uses Zend) probably next year. Here is the link to the libs https://developers.google.com/google-apps/calendar/downloads

Related

Accessing GDrive from Google App Engine with domain-wide delegation service account

This is my first time using Google App Engine, so some of my terminology might be a bit off, bear with me.
I had some php code running in a web app outside of GAE that was using the google-api-php-client library to access gdrive folders and create files. It was working wonderfully.
I'm trying to migrate to GAE with a project that has domain-wide delegation so that my app can access/create files in my gdrive account. For example, let's say my domain is kennywyland.com and my Google account that I'm using is kenny#kennywyland.com.
I create my Google Client like this, which I got from https://developers.google.com/api-client-library/php/auth/service-accounts:
$client = new Google_Client();
$client->setAuth(new Google_Auth_AppIdentity($client));
$client->getAuth()->authenticateForScope('https://www.googleapis.com/auth/drive');
Then I create the gdrive service like this:
$service = new Google_Service_Drive($client);
I didn't get any errors from this and I am able to perform queries without error messages being thrown, however, I'm getting back completely empty result sets. I've got plenty of files in my gdrive account, so I would assume that I should see them when I publish the following code to GAE and run it (the retreiveAllFiles() function is from Google's code example found here: https://developers.google.com/drive/v2/reference/files/list#try-it):
$allfiles = retrieveAllFiles($service);
print_r($allfiles);
function retrieveAllFiles($service) {
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array();
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$files = $service->files->listFiles($parameters);
$result = array_merge($result, $files->getItems());
$pageToken = $files->getNextPageToken();
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
return $result;
}
However, I get an empty result set. The print_r() prints an empty array:
Array ( )
What am I missing? I feel like my project/app is able to successfully access the gdrive server, but it's just not able to see any files in my account associated with this work domain.
The solution involved one primary change which required one further change. The primary change was that I was using the google-api-php-client v1 but I needed to be using the v2 release candidate (which is oddly located in the https://github.com/google/google-api-php-client/tree/v1-master branch).
They have a list of code changes needed to upgrade from 1.0 to 2.0 (thank you, very handy githubers!)
https://github.com/google/google-api-php-client/blob/master/UPGRADING.md
I ended up configuring my client with the following code and then it was immediately able to access gdrive as if it were the currently logged in person (assuming 'kenny#kennywyland.com' in my example, who is part of my special domain with domain-wide delegation).
require_once('vendor/autoload.php');
$client = new Google_Client();
$client->setAuthConfig('myapp-xxxxxxxx.json');
$user_to_impersonate = "kenny#kennywyland.com";
$client->setSubject($user_to_impersonate);
$client->addScope('https://www.googleapis.com/auth/drive');
$service = new Google_Service_Drive($client);
The myapp-xxxxxxx.json file was generated in my Developer Console for my App's Service Account.

Auto loading zendGdata files & accessing data

I am trying to connect my website with my blog on blogger using the zendGdata API and am having 2 issues:
Firstly the Zend_Loader:: functions do not appear to be loading anything and just result in a blank screen. my code so far is as below:
require_once('../Includes/ZendGdata-1.12.11/library/Zend/Loader.php');
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
I am then attempting to connect with:
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, 'blogger');
$gdClient = new Zend_Gdata($client);
But as I say I am getting a blank screen.
For my 2nd query, is the $user and $pass meant to be the email address and client secret generated from the google developer console for my website?
Thanks

How can I have my server add events to a google calendar using the client library for PHP?

I have very little experience working with the google api and I'm finding it difficult to find relevant information on certain subjects.
What I'm trying to do is create a calendar that requires no log in information from the user. I want my server to add events to the calendar based off of information in a database.
I have gone into my google calendars, created a new one, and worked up some code to add events to the calendar. Then I use the iframe code that google provides to embed the calendar into my site.
The problem I'm running into is that the server wants the user to be logged in as me to add events to the calendar. Since the server is the one adding the events, I'm not really sure how to work around this. I know I need to make/use a service account so my server can "delegate domain-wide authority", but I'm not sure how to do this using the client library for PHP. No examples are provided by google. I had to download a p12 file that my server needs to make these api calls, but I'm not sure how to point to the file using the client library. Is it possible to use the php client library to hook into a service account to make these api calls? If so, how?
Any help is greatly appreciated.
I had the same problem and found the solution (in a round about way) here:
Inserting Google Calendar Entries with Service Account
First thing is to set up your Google calendar correctly (see above mentioned post which describes it very well), then download the API code for the Calendar from here https://github.com/google/google-api-php-client
It's the Download ZIP link on the right of that page.
Then here is some sample code which works for me (private keys replaced with xxxx where appropriate, but otherwise it's exactly what I'm using).
I'm now trying to find out how to read & clear a Google Calendar, which is proving even more challenging!
<?php
//
// built from example at:
// https://stackoverflow.com/questions/26064095/inserting-google-calendar-entries-with-service-account
//
$startdate = new DateTime('2015-01-29 10:00', new DateTimeZone('Europe/London'));
$startdate = $startdate->format('c');
$enddate = new DateTime('2015-01-29 10:00', new DateTimeZone('Europe/London'));
$enddate = $enddate->format('c');
//
// call function to add one event to the calendar (xxxxxxxxxxx#googlemail.com = the calendar owner)
//
calendarize('Test Appointment','Test appt description',$startdate,$enddate,'xxxxxxxxxxx#googlemail.com');
//-----------------------------------------------//
// funtion to add an event to my Google calendar //
//-----------------------------------------------//
function calendarize ($title, $desc, $start_ev_datetime, $end_ev_datetime, $cal_id) {
session_start();
require_once '../google-api-php-client-master/autoload.php';
//Google credentials
$client_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
$service_account_name = 'xxxxxxxxxxxxxxxxxxxxxxxxxx#developer.gserviceaccount.com';
$key_file_location = '../google-api-php-client-master/API Project-xxxxxxxxxx.p12';
if (!strlen($service_account_name) || !strlen($key_file_location))
echo missingServiceAccountDetailsWarning();
$client = new Google_Client();
$client->setApplicationName("Whatever the name of your app is");
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/calendar'),
$key
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
try {
$client->getAuth()->refreshTokenWithAssertion($cred);
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
$_SESSION['service_token'] = $client->getAccessToken();
$calendarService = new Google_Service_Calendar($client);
$calendarList = $calendarService->calendarList;
//Set the Event data
$event = new Google_Service_Calendar_Event();
$event->setSummary($title);
$event->setDescription($desc);
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime($start_ev_datetime);
$start->setTimeZone('Europe/London');
$event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime($end_ev_datetime);
$end->setTimeZone('Europe/London');
$event->setEnd($end);
try {
$createdEvent = $calendarService->events->insert($cal_id, $event);
} catch (Exception $e) {
var_dump($e->getMessage());
}
echo 'Event Successfully Added with ID: '.$createdEvent->getId();
}
?>
Using OAuth2 to login and give your server rights to access your calendar account is really simple and well documented (with the google api php client). If you request offline access and store the refresh token, you can log in "as you" server-side at any time.
See Google Accounts Authentication and Authorization: Offline access

Creating event with Google Calendar fatal errors

I'm having a complete nightmare with this. I'm using the latest version of the PHP API from Github and just want to create events in a google calendar. There are tons of examples out there but many from a different version of the API where the calendar functions were in a contrib folder when now they're not. I've set everything up in the google developer console as guides state.
Using code I've found from a recent example here is what I'm using at the moment:
require_once './google-api/src/Google/Client.php';
require_once './google-api/src/Google/Service/Calendar.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Google Calendar");
$client->setClientId('#');
$client->setClientSecret('#');
$client->setRedirectUri('#');
$client->setDeveloperKey('#');
$calendar_id = "#";
$cal = new Google_CalendarService($client);
if ($client->getAccessToken()){
echo "<hr><font size=+1>I have access to your calendar</font>";
$event = new Google_Event();
$event->setSummary('Halloween');
$event->setLocation('The Neighbourhood');
$start = new Google_EventDateTime();
$start->setDateTime('2013-9-29T10:00:00.000-05:00');
$event->setStart($start);
$end = new Google_EventDateTime();
$end->setDateTime('2013-9-29T10:25:00.000-05:00');
$event->setEnd($end);
$createdEvent = $cal->events->insert($calendarid, $event);
echo "<br><font size=+1>Event created</font>";
}
But I keep getting this error PHP Fatal error: Class 'Google_CalendarService' not found and the same for 'Google_Event' if I remove the CalendarService line.
The official documentation for this seems very inconsistent and inaccurate and so any help would be much appreciated.
I would recommend trying the example at: https://github.com/google/google-api-php-client/blob/master/examples/simple-query.php and then replacing the books service with the calendar service.
Google_CalendarService should be Google_Service_Calendar based on the latest version in github.
I think Google_Event should be Google_Service_Calendar_Event as well.

Authentication with Google Calendar API using Server Account and PHP

I'm struggling with this one: I am trying to create an event in a Google Calendar from a PHP script, using a Service Account.
Here’s what I’ve done:
Created a Google Cloud Project
Enabled the Calendar API
Created an OAuth 2.0 Service Account, with Client ID, Email address and Public Key
Downloaded the keyfile and saved this in my website
Shared my Calendar with the Email address created in the Service Account (with Manage Sharing rights)
And here is my code:
<?php
require_once 'google_api_src/Google_Client.php';
require_once 'google_api_src/contrib/Google_CalendarService.php';
const CLIENT_ID = 'xxxxxxxxxxxxx.apps.googleusercontent.com';
const SERVICE_ACCOUNT_NAME = 'xxxxxxxxxxxxx#developer.gserviceaccount.com';
// Make sure you keep your key.p12 file in a secure location, and isn't
// readable by others.
const KEY_FILE = 'google_api_src/xxxxxxxxx-privatekey.p12';
$client = new Google_Client();
$client->setApplicationName("Hall Booking");
session_start();
if (isset($_SESSION['token']))
{
$client->setAccessToken($_SESSION['token']);
}
// Load the key in PKCS 12 format
$key = file_get_contents(KEY_FILE);
$client->setClientId(CLIENT_ID);
$client->setAssertionCredentials(new Google_AssertionCredentials(
SERVICE_ACCOUNT_NAME,
array('https://www.googleapis.com/auth/calendar', "https://www.googleapis.com/auth/calendar.readonly"),
$key));
$service = new Google_CalendarService($client);
//Save token in session
if ($client->getAccessToken())
{
$_SESSION['token'] = $client->getAccessToken();
}
?>
I have debugged the code as far as I can, but the token is always set to null after the call to SetAssertionCredentials. There are no PHP errors.
Any idea what is wrong, or how to debug further please?
Do I have to make any changes to config.php in the api src folder (I haven’t so far)?
Is the Application Name important? What’s it used for?
OK - so it turns out that the above code is working fine. My misunderstanding was in thinking that the Google_CalendarService performed the authentication. In fact, the authentication is only performed when an actual call to the calendar is made (such as insert Event).
However, I think that saving the token in the session is in the wrong place - it should be after an action has been performed.
To answer my other questions: No, you don't have to make any changes to config.php. The Application Name can be set to anything (but I don't know what it's used for).
One other problem I came across: I was creating an event using a calendar ID of 'primary'. This sent back a success message, but I could not see the event in the calendar (I only have one calendar for that account). It was only when I changed 'primary' to 'mycalendarid#gmail.com' that it started working. Sounds like a bug in the API to me?
Checkout the demo: http://amazewebs.com/demo
Or get 1-to-1 help on this: http://amazewebs.com/go-premium
I have gotten this working with a service account, you are using the wrong URL in your code, or at least I have it working with no problems with my method...
See my code here: http://amazewebs.com
Or here:
<!-- language: php -->
<?php
ini_set('display_errors', 1);
require_once '../google-api/Google_Client.php';
require_once '../google-api/contrib/Google_CalendarService.php';
session_start();
const CLIENT_ID = '<YOUR-CLIENT-ID-HERE>.apps.googleusercontent.com';
const SERVICE_ACCOUNT_NAME = '<YOUR-SERVICE-EMAIL-HERE>#developer.gserviceaccount.com';
const KEY_FILE = '<YOUR-FINGERPRINT-HERE>-privatekey.p12';
$client = new Google_Client();
$client->setApplicationName("<PUT-YOUR-PROJECT-NAME-HERE");
$client->setUseObjects(true); //IF USING SERVICE ACCOUNT (YES)
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
/* This next snippet of code is commonly written wrong, be sure to use the correct URL specified as below: */
$key = file_get_contents(KEY_FILE);
$client->setClientId(CLIENT_ID);
$client->setAssertionCredentials(new Google_AssertionCredentials(
SERVICE_ACCOUNT_NAME, 'https://www.google.com/calendar/feeds/<YOUR-CALENDAR-ID-HERE-WITHOUT-THE-TRAILING"#group.calendar.google.com">/private/full/',
$key)
);
$client->setClientId(CLIENT_ID);
$cal = new Google_CalendarService($client);
$event = new Google_Event();
$event->setSummary('<PUT-AN-EVENT-TITLE-HERE-OR-PASSED-VARIABLE>');
$event->setLocation('<PUT-A-LOCATION-HERE-OR-PASSED-VARIABLE>');
...The Full script can be found # AmazeWebs.com
& Also I recommend downloading the older google api library as it doesn't seem to work with their latest 0.6.7!
...I have downloaded and packaged all the files in the correct path structure for you: http://amazewebs.com/downloads/google-api.zip
Alternatively, you can download every individual file and package it yourself if you want to download it from google directly:
http://google-api-php-client.googlecode.com/svn/trunk/src/
Good luck :)

Categories