Zend Framework

Google Contacts API support

Details

  • Type: New Feature New Feature
  • Status: In Progress In Progress
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: 1.5.2
  • Fix Version/s: None
  • Component/s: Zend_Gdata
  • Labels:
    None

Description

This is more of a heads-up than a request.

I'm currently working on some code to work with the new Zend Contacts API for managing things like Gmail contacts. I anticipate having something in an alpha peer-review state sometime this week.

http://code.google.com/apis/contacts/

I'm starting this issue so I'll have somewhere to post the code and to "stake out" the area to avoid having multiple people unknowingly working on the same task.

Stuff that currently works:

  • Listing contacts
  • Emails
  • Phone data & subtype (mobile, pager, fax) information
  • IM data
  • Organization data
  • Label/categorization for data types
  • Altering primary e-mail
  • Notes about the current user

Activity

Hide
Darien Hager added a comment -

I signed the indivdual CLA before, but this one is something on company time so as soon as I get a Corporate CLA done I'll post what I have. Current classes:

Contacts/Extension/Categorized.php (abstract superclass)
Contacts/Extension/Email.php
Contacts/Extension/Im.php
Contacts/Extension/Name.php
Contacts/Extension/Notes.php
Contacts/Extension/Organization.php
Contacts/Extension/OrgName.php
Contacts/Extension/OrgTitle.php
Contacts/Extension/PhoneNumber.php
Contacts/Extension/PostalAddress.php
Contacts/ListEntry.php
Contacts/ListFeed.php

Show
Darien Hager added a comment - I signed the indivdual CLA before, but this one is something on company time so as soon as I get a Corporate CLA done I'll post what I have. Current classes: Contacts/Extension/Categorized.php (abstract superclass) Contacts/Extension/Email.php Contacts/Extension/Im.php Contacts/Extension/Name.php Contacts/Extension/Notes.php Contacts/Extension/Organization.php Contacts/Extension/OrgName.php Contacts/Extension/OrgTitle.php Contacts/Extension/PhoneNumber.php Contacts/Extension/PostalAddress.php Contacts/ListEntry.php Contacts/ListFeed.php
Hide
Jeffrey Scudder added a comment -

Very cool Darien, sounds like a fantastic start! I'd like to help in some way if you're interested. Unit tests, sample application, etc. Are there any data model classes that you need? I have some code for Contacts/Extension/GroupMembershipInfo.php and Deleted.php if you are interested.

Show
Jeffrey Scudder added a comment - Very cool Darien, sounds like a fantastic start! I'd like to help in some way if you're interested. Unit tests, sample application, etc. Are there any data model classes that you need? I have some code for Contacts/Extension/GroupMembershipInfo.php and Deleted.php if you are interested.
Hide
Darien Hager added a comment -

Thanks, I'm currently waiting on The Powers That Be to authorize me sending CLA application. Once I can post actual code things should be clearer.

I'm afraid my development model has been fairly haphazard, partially because this is my first time delving into the Gdata component works internally. So I don't have any unit tests. (How do you unit test against a monolithic external service anyway?) Right now the general structure is similar to the Calendar/ListEntry.php class.

Stuff I don't plan to implement any time soon:

  • Photos
  • Bulk updates (a broader issue than just Contacts)
  • Group or Membership data and queries

Misc concerns:

Show
Darien Hager added a comment - Thanks, I'm currently waiting on The Powers That Be to authorize me sending CLA application. Once I can post actual code things should be clearer. I'm afraid my development model has been fairly haphazard, partially because this is my first time delving into the Gdata component works internally. So I don't have any unit tests. (How do you unit test against a monolithic external service anyway?) Right now the general structure is similar to the Calendar/ListEntry.php class. Stuff I don't plan to implement any time soon:
  • Photos
  • Bulk updates (a broader issue than just Contacts)
  • Group or Membership data and queries
Misc concerns:
Hide
Darien Hager added a comment -

What the test contact looks like in GMail...

Show
Darien Hager added a comment - What the test contact looks like in GMail...
Hide
Darien Hager added a comment -

...Shows a GMail contact as retrieved and displayed by PHP code.

The [1] designates the primary e-mail. "

MyCat" is a custom category for information, parallel to "Work" and "Personal".

Phone numbers may have a subtype like "Fax".

For organizations, the title is in square brackets.

Show
Darien Hager added a comment - ...Shows a GMail contact as retrieved and displayed by PHP code. The [1] designates the primary e-mail. " MyCat" is a custom category for information, parallel to "Work" and "Personal". Phone numbers may have a subtype like "Fax". For organizations, the title is in square brackets.
Hide
Darien Hager added a comment -

Okay, so those last two screenshots are at least proof-of-concept. (Yes, the custom output is ugly, but it was easier when writing a bunch of throwaway echo statements.)

More musings and API uncertainties:

  • Can you have multiple "Fax" or "Mobile" phone numbers for a single category for a single contact? Right now there's no clientside code for checking that kind of situation.
  • It seems you can make a custom category called "work" that parallels the built-in "work" category. Is this a bug? How can we distinguish between them? The current implementation just assumes such name collision is not possible.
  • I haven't tested any sort of "advanced searching" or listing--just pulling back a small but complete list of test contacts.
Show
Darien Hager added a comment - Okay, so those last two screenshots are at least proof-of-concept. (Yes, the custom output is ugly, but it was easier when writing a bunch of throwaway echo statements.) More musings and API uncertainties:
  • Can you have multiple "Fax" or "Mobile" phone numbers for a single category for a single contact? Right now there's no clientside code for checking that kind of situation.
  • It seems you can make a custom category called "work" that parallels the built-in "work" category. Is this a bug? How can we distinguish between them? The current implementation just assumes such name collision is not possible.
  • I haven't tested any sort of "advanced searching" or listing--just pulling back a small but complete list of test contacts.
Hide
Jeffrey Scudder added a comment -

In answer to your three questions:

  • yes, it is possible to have multiple phone numbers with rel set to fax (http://schemas.google.com/g/2005#fax)
  • when you say that you are making a custom category, do you mean that you are adding an Atom category element to the entry, or did you mean you are using a different rel value on a phoneNumber element (for example)?
  • the query capabilities for the API are listed here: http://code.google.com/apis/contacts/reference.html#Parameters . The items in the first box should already be included inf you inherit from the Gdata query class, the second set will require some new code. Please let me know if the descriptions in the documentation aren't clear.

If you have any questions, please ask

Show
Jeffrey Scudder added a comment - In answer to your three questions:
  • yes, it is possible to have multiple phone numbers with rel set to fax (http://schemas.google.com/g/2005#fax)
  • when you say that you are making a custom category, do you mean that you are adding an Atom category element to the entry, or did you mean you are using a different rel value on a phoneNumber element (for example)?
  • the query capabilities for the API are listed here: http://code.google.com/apis/contacts/reference.html#Parameters . The items in the first box should already be included inf you inherit from the Gdata query class, the second set will require some new code. Please let me know if the descriptions in the documentation aren't clear.
If you have any questions, please ask
Hide
Darien Hager added a comment -

Thanks for your reply. I'm still bugging the appropriate folks for official permission to contribute the code.

What I had meant about categories is what you can do with Gmail: You start with "Work", "Personal" and "Other".

You can make custom categories like "Secret Identity" to hold a similar corresponding set of postal/im/email/phone data.

However, it seems you can also make custom categories which (from just looking at the XML) are indistinguishable from the built-in ones.

Improvements:

  • Added features to set the "primary" flag among sets of phone, IM, email, and postal values. (AFAIK the "primary e-mail" scope includes all email items in all categories, not just "Primary for Home" and "Primary For Work", etc.)
  • Listing categories in use for an entry (Home, Work, Personal, Foo)
  • Retrieving data objects by category label
  • Contacts-API-specific query options mostly coded
Show
Darien Hager added a comment - Thanks for your reply. I'm still bugging the appropriate folks for official permission to contribute the code. What I had meant about categories is what you can do with Gmail: You start with "Work", "Personal" and "Other". You can make custom categories like "Secret Identity" to hold a similar corresponding set of postal/im/email/phone data. However, it seems you can also make custom categories which (from just looking at the XML) are indistinguishable from the built-in ones. Improvements:
  • Added features to set the "primary" flag among sets of phone, IM, email, and postal values. (AFAIK the "primary e-mail" scope includes all email items in all categories, not just "Primary for Home" and "Primary For Work", etc.)
  • Listing categories in use for an entry (Home, Work, Personal, Foo)
  • Retrieving data objects by category label
  • Contacts-API-specific query options mostly coded
Hide
Darien Hager added a comment -

Huzzah! Apparently a confluence of deadlines (some ending, some starting) have resulted in activity.

I anticipate having legally-postable svn diffs shortly. Hopefully in time for the 1.6 feature freeze. Mind you, my prior "anticipation" was misleading, but literally correct

Is there any particular branch or tag I should diff against? I'm currently working off of 1.5.2, although it shouldn't matter very much since most of the files are new.

Show
Darien Hager added a comment - Huzzah! Apparently a confluence of deadlines (some ending, some starting) have resulted in activity. I anticipate having legally-postable svn diffs shortly. Hopefully in time for the 1.6 feature freeze. Mind you, my prior "anticipation" was misleading, but literally correct Is there any particular branch or tag I should diff against? I'm currently working off of 1.5.2, although it shouldn't matter very much since most of the files are new.
Hide
Ryan Boyd added a comment -

Hi Darien,

I appreciate all your hard work to get contacts support in. However, I don't know if we're going to have time to get this in before midnight tonight for the 1.6 feature freeze. I believe all code reviews/testing/docs/etc need to be complete by tonight. Given that ZF strives to maintain backwards compatibility, I don't think we really want to rush through this process.

Perhaps we should work on getting this checked into trunk later this week and then push forward to having it included in the 1.7 release (which Wil promises will come shortly after 1.6).

We can then post info in the Google Group for Contacts and get people to test it out before the release?

Cheers,
-Ryan

Show
Ryan Boyd added a comment - Hi Darien, I appreciate all your hard work to get contacts support in. However, I don't know if we're going to have time to get this in before midnight tonight for the 1.6 feature freeze. I believe all code reviews/testing/docs/etc need to be complete by tonight. Given that ZF strives to maintain backwards compatibility, I don't think we really want to rush through this process. Perhaps we should work on getting this checked into trunk later this week and then push forward to having it included in the 1.7 release (which Wil promises will come shortly after 1.6). We can then post info in the Google Group for Contacts and get people to test it out before the release? Cheers, -Ryan
Hide
Darien Hager added a comment -

Ah, so it's more than just a freeze on feature scope, then. Darn.

Regarding backwards-compatibility...

The only changes that are not entirely new files are convenience functions which can be moved elsewhere. I could submit a changeset which shouldn't affect anybody who isn't specifically trying the new API.

Show
Darien Hager added a comment - Ah, so it's more than just a freeze on feature scope, then. Darn. Regarding backwards-compatibility... The only changes that are not entirely new files are convenience functions which can be moved elsewhere. I could submit a changeset which shouldn't affect anybody who isn't specifically trying the new API.
Hide
Ryan Boyd added a comment -

Hi Darien,

Yea, I'd love to get this in ASAP, but I want to make sure it's done right. The note from Wil:
"Just a reminder that the feature-complete (that means all code, unit tests, and documentation) deadline for all contributions targeted for the 1.6 release is 6/30. "

Re backwards-compat:
What I was referring to was that if we rush to get the contacts support added in the next couple hours, we could miss something in Contacts that we'd want to change, and end up regretting not being able to change it in the future

I'd love to get your code in.. I'm super excited that you're contributing it, but I just don't want to rush it the night of the freeze.

Can we work to get this reviewed this week, committed in trunk and then give the Google Group for contacts a chance to test it out before the 1.7 freeze?

Cheers,
-Ryan

Show
Ryan Boyd added a comment - Hi Darien, Yea, I'd love to get this in ASAP, but I want to make sure it's done right. The note from Wil: "Just a reminder that the feature-complete (that means all code, unit tests, and documentation) deadline for all contributions targeted for the 1.6 release is 6/30. " Re backwards-compat: What I was referring to was that if we rush to get the contacts support added in the next couple hours, we could miss something in Contacts that we'd want to change, and end up regretting not being able to change it in the future I'd love to get your code in.. I'm super excited that you're contributing it, but I just don't want to rush it the night of the freeze. Can we work to get this reviewed this week, committed in trunk and then give the Google Group for contacts a chance to test it out before the 1.7 freeze? Cheers, -Ryan
Hide
Darien Hager added a comment -

Sure, I have no particular objection to delaying it until 1.7, I just misunderstood the scope of the freeze.

On a unrelated note, I've been toying with is a Gdata adapter for Zend_Auth, but I'm running into some ambiguities since usernames are not necessarily unique due to context (service used, real gmail vs hosted corporate, etc.)

Show
Darien Hager added a comment - Sure, I have no particular objection to delaying it until 1.7, I just misunderstood the scope of the freeze. On a unrelated note, I've been toying with is a Gdata adapter for Zend_Auth, but I'm running into some ambiguities since usernames are not necessarily unique due to context (service used, real gmail vs hosted corporate, etc.)
Hide
Darien Hager added a comment -

The Not-Yet-Ready-For-Real-Review proposal is now up in the wiki...

http://framework.zend.com/wiki/display/ZFPROP/Zend_Gdata_Contacts+-+Darien+Hager

I'll focus on adding more skeleton examples while waiting for the corporate gears to grind.

Show
Darien Hager added a comment - The Not-Yet-Ready-For-Real-Review proposal is now up in the wiki... http://framework.zend.com/wiki/display/ZFPROP/Zend_Gdata_Contacts+-+Darien+Hager I'll focus on adding more skeleton examples while waiting for the corporate gears to grind.
Hide
Ryan Boyd added a comment -

Hi Darien,

Great - thanks for the proposal! We'll happily review it. As this is not a new component, but rather just some new classes for an existing component (Zend_Gdata), I don't believe it really needs a formalized proposal.

Good luck with the "corporate gears."

Cheers,
-Ryan

Show
Ryan Boyd added a comment - Hi Darien, Great - thanks for the proposal! We'll happily review it. As this is not a new component, but rather just some new classes for an existing component (Zend_Gdata), I don't believe it really needs a formalized proposal. Good luck with the "corporate gears." Cheers, -Ryan
Hide
Curt Larson added a comment -

Thanks for your great work on this Darien. I might need to get this implemented before Darien gets throught he legal gears, could anyone give me a hand on how to do this manually? I'd be fine if I could just extract the raw data from google, but not sure how to do it. Ideally actually I'd just like to get it in JSON.

Here is what I'm doing:
$contact = new Zend_Gdata($client);
$query = new Zend_Gdata_Query(
'http://www.google.com/m8/feeds/contacts/default/full');
$query->setMaxResults(2000);
$feed = $contact->getFeed($query);

foreach ($feed as $entry) {
print 'Title: ' . $entry->title->text;

I do get the names of the contacts out, but don't know how to get the other data I need (which is just phone number and email address).

Thanks for any help!

Curt

Show
Curt Larson added a comment - Thanks for your great work on this Darien. I might need to get this implemented before Darien gets throught he legal gears, could anyone give me a hand on how to do this manually? I'd be fine if I could just extract the raw data from google, but not sure how to do it. Ideally actually I'd just like to get it in JSON. Here is what I'm doing: $contact = new Zend_Gdata($client); $query = new Zend_Gdata_Query( 'http://www.google.com/m8/feeds/contacts/default/full'); $query->setMaxResults(2000); $feed = $contact->getFeed($query); foreach ($feed as $entry) { print 'Title: ' . $entry->title->text; I do get the names of the contacts out, but don't know how to get the other data I need (which is just phone number and email address). Thanks for any help! Curt
Hide
Ryan Boyd added a comment -

@Curt

This should get you the JSON version of the feed you're looking for...

<?php

require_once 'Zend/Gdata/ClientLogin.php';
require_once 'Zend/Gdata.php';

$client = Zend_Gdata_ClientLogin::getHttpClient('email address', 'password', 'cp');
$gd = new Zend_Gdata($client);

$response = $gd->get('http://www.google.com/m8/feeds/contacts/default/full?max-results=2000&alt=json');
echo $response->getBody();

Show
Ryan Boyd added a comment - @Curt This should get you the JSON version of the feed you're looking for... <?php require_once 'Zend/Gdata/ClientLogin.php'; require_once 'Zend/Gdata.php'; $client = Zend_Gdata_ClientLogin::getHttpClient('email address', 'password', 'cp'); $gd = new Zend_Gdata($client); $response = $gd->get('http://www.google.com/m8/feeds/contacts/default/full?max-results=2000&alt=json'); echo $response->getBody();
Hide
Darien Hager added a comment -

Here's some code that ought to work:

foreach($feed as $entry){
	print("<h1>".$entry->title."</h1>");		
	$parts = $entry->getExtensionElements();
	foreach($parts as $p){		
		$element = $p->getDOM();				
		switch($element->tagName){
			case 'email':
				print("Email: ".$element->getAttribute('address')."<br/>");
				break;
			case 'phoneNumber':
				print("Phone: ".$element->nodeValue."<br/>");
				break;
			default:
				continue;
		}
	}	
}
Show
Darien Hager added a comment - Here's some code that ought to work:
foreach($feed as $entry){
	print("<h1>".$entry->title."</h1>");		
	$parts = $entry->getExtensionElements();
	foreach($parts as $p){		
		$element = $p->getDOM();				
		switch($element->tagName){
			case 'email':
				print("Email: ".$element->getAttribute('address')."<br/>");
				break;
			case 'phoneNumber':
				print("Phone: ".$element->nodeValue."<br/>");
				break;
			default:
				continue;
		}
	}	
}
Hide
Darien Hager added a comment -

P.S.: If you want information about categories, e.g. "Work", "Personal", or phone-number subtypes such as "mobile" and "fax", I have a little rant about how that's painful:

http://groups.google.com/group/google-contacts-api/browse_thread/thread/d824900520a4d6f0#

Show
Darien Hager added a comment - P.S.: If you want information about categories, e.g. "Work", "Personal", or phone-number subtypes such as "mobile" and "fax", I have a little rant about how that's painful: http://groups.google.com/group/google-contacts-api/browse_thread/thread/d824900520a4d6f0#
Hide
Curt Larson added a comment -

Thanks guys for the very fast response - worked out well.

Thanks,

Curt

Show
Curt Larson added a comment - Thanks guys for the very fast response - worked out well. Thanks, Curt
Hide
Darien Hager added a comment -

Pfhew. Waiting for Zend response to the corporate CLA.

Show
Darien Hager added a comment - Pfhew. Waiting for Zend response to the corporate CLA.
Hide
Darien Hager added a comment -

Still waiting... But what's the procedure here, just toss up a zip of sources and someone else commits it to the right place in SVN?

Show
Darien Hager added a comment - Still waiting... But what's the procedure here, just toss up a zip of sources and someone else commits it to the right place in SVN?
Hide
Trevor Johns added a comment -

Hey Darien,
The preferred way is to upload a patch in unified diff format created by running 'svn diff'.

Once that's done, the community will have a chance to review the patch and provide feedback. Once everybody's happy with it, I can go ahead and check the code into SVN for you.

Thanks for all of your hard work on this.

Show
Trevor Johns added a comment - Hey Darien, The preferred way is to upload a patch in unified diff format created by running 'svn diff'. Once that's done, the community will have a chance to review the patch and provide feedback. Once everybody's happy with it, I can go ahead and check the code into SVN for you. Thanks for all of your hard work on this.
Hide
Darien Hager added a comment -

As diffed against the 1.5.3 release tag.

Only minor changes on existing code, otherwise new files.

Show
Darien Hager added a comment - As diffed against the 1.5.3 release tag. Only minor changes on existing code, otherwise new files.
Hide
Darien Hager added a comment -

Okay, there it is.

Caveats: I have not recently re-tested it. Google may have changed their API. In fact, I'm pretty sure the category stuff ("Work","Personal") is broken, or at the least a bit iffy.

Google might have cleaned up that aspect of their API, but last I checked that particular categorization feature was iffy.

Show
Darien Hager added a comment - Okay, there it is. Caveats: I have not recently re-tested it. Google may have changed their API. In fact, I'm pretty sure the category stuff ("Work","Personal") is broken, or at the least a bit iffy. Google might have cleaned up that aspect of their API, but last I checked that particular categorization feature was iffy.
Hide
Darien Hager added a comment -

Note to self: Proof-read more next time.

The following Google tickets/issues are probably germane:
http://code.google.com/p/gdata-issues/issues/detail?id=653
http://code.google.com/p/gdata-issues/issues/detail?id=639

It seems some of the docs may have been updated with more about possible 'rel' attribute values:
http://code.google.com/apis/gdata/elements.html

Turns out the patch I posted is already broken (broken assertion) when it encounters rel="http://schemas.google.com/g/2005#work_fax"

Show
Darien Hager added a comment - Note to self: Proof-read more next time. The following Google tickets/issues are probably germane: http://code.google.com/p/gdata-issues/issues/detail?id=653 http://code.google.com/p/gdata-issues/issues/detail?id=639 It seems some of the docs may have been updated with more about possible 'rel' attribute values: http://code.google.com/apis/gdata/elements.html Turns out the patch I posted is already broken (broken assertion) when it encounters rel="http://schemas.google.com/g/2005#work_fax"
Hide
Darien Hager added a comment -

Due to unexpected developments I will not be able to proactively develop this feature at this time, so I'm changing it to unassigned. I will however try to keep watching the issue and helping as time permits.

Show
Darien Hager added a comment - Due to unexpected developments I will not be able to proactively develop this feature at this time, so I'm changing it to unassigned. I will however try to keep watching the issue and helping as time permits.
Hide
Trevor Johns added a comment -

No worries Darren, I can help finish it up. Speaking of which, I'm hoping to finish going through the patch within the next week.

Show
Trevor Johns added a comment - No worries Darren, I can help finish it up. Speaking of which, I'm hoping to finish going through the patch within the next week.
Hide
Trevor Johns added a comment -

Err, Darien. Sorry about that.

Show
Trevor Johns added a comment - Err, Darien. Sorry about that.
Hide
Trevor Johns added a comment -

Increasing priority to major.

Show
Trevor Johns added a comment - Increasing priority to major.
Hide
Ian Service added a comment -

Are there any updates on progress with this? As Google has added domain-wide contacts, this is of much more use to me now. The patch above seems to work to an extent but there is now version 3 of the Google Contacts API which has new, more structured types.

I'd be glad to work with someone to get this Gdata addition working correctly.

Show
Ian Service added a comment - Are there any updates on progress with this? As Google has added domain-wide contacts, this is of much more use to me now. The patch above seems to work to an extent but there is now version 3 of the Google Contacts API which has new, more structured types. I'd be glad to work with someone to get this Gdata addition working correctly.
Hide
Trevor Johns added a comment -

Sorry, there hasn't been much work on this since my last update.

The core code exists, but I still need to sit down and write tests, sample code, and documentation. Especially tests.

Show
Trevor Johns added a comment - Sorry, there hasn't been much work on this since my last update. The core code exists, but I still need to sit down and write tests, sample code, and documentation. Especially tests.
Hide
Ian Service added a comment -

Does it exist somewhere where I can use it as-is? It doesn't have to be perfect, I don't really need docs as I've been going through the API over the last few days pretty intensively.

Show
Ian Service added a comment - Does it exist somewhere where I can use it as-is? It doesn't have to be perfect, I don't really need docs as I've been going through the API over the last few days pretty intensively.
Hide
Trevor Johns added a comment -

Nope. If it takes much longer, I might check it into the incubator, but for now there's no public copy.

Show
Trevor Johns added a comment - Nope. If it takes much longer, I might check it into the incubator, but for now there's no public copy.
Hide
Ingmar Heinrich added a comment -

Has there been any thoughts during the past fourteen months? I would love to see Google Contacts within ZF.

Show
Ingmar Heinrich added a comment - Has there been any thoughts during the past fourteen months? I would love to see Google Contacts within ZF.
Hide
Brady Emerson added a comment -

Second Ingmar's request. An update on support for Google Contacts seems way overdue.

Show
Brady Emerson added a comment - Second Ingmar's request. An update on support for Google Contacts seems way overdue.

People

Vote (10)
Watch (17)

Dates

  • Created:
    Updated: