I’m using a module in Drupal that imports contacts from Gmail. The script works fine when it retrieves the default 25 contacts. However, when I try to fetch more contacts by modifying the Google API URL with a max-results parameter, it results in an error.
Issue: When I change the API feed URL by adding ?max-results=1000, I encounter a fatal error:
Fatal error: Call to a member function getAttribute() on a non-object
This error occurs at the line where the code attempts to acquire the email address: $emailAddr = $emailNode->getAttribute('address');
class ContactImporter {
static $login_url = 'https://www.google.com/accounts/ClientLogin';
static $contacts_feed = 'http://www.google.com/m8/feeds/contacts/default/thin?max-results=65535';
function createCurlConnection($endpoint, $authToken = null) {
$ch = curl_init();
$options = array(
CURLOPT_URL => $endpoint,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false,
);
if ($authToken != null) {
$options[CURLOPT_HTTPHEADER] = array(
'Authorization: GoogleLogin auth='.$authToken,
);
}
curl_setopt_array($ch, $options);
return $ch;
}
function setupPostRequest($curlHandle, $postData) {
curl_setopt($curlHandle, CURLOPT_POST, true);
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $postData);
return $curlHandle;
}
function authenticate($username, $pass) {
$ch = $this->setupPostRequest($this->createCurlConnection(self::$login_url), array(
'accountType' => 'HOSTED_OR_GOOGLE',
'Email' => $username,
'Passwd' => $pass,
'service' => 'cp',
'source' => 'ContactImporter',
));
$response = curl_exec($ch);
preg_match_all('/Auth=([^\s]*)/si', $response, $authMatches);
if (isset($authMatches[1][0])) {
return $authMatches[1][0];
}
return false;
}
function fetchContacts($username, $pass) {
$authToken = $this->authenticate($username, $pass);
if (!$authToken) {
return false;
}
$ch = $this->createCurlConnection(self::$contacts_feed, $authToken);
$xmlData = curl_exec($ch);
$document = new DOMDocument();
$document->loadXML($xmlData);
$xpath = new DOMXPath($document);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$xpath->registerNamespace('gdata', 'http://schemas.google.com/g/2005');
$entryList = $xpath->query('//atom:entry');
$totalEntries = $entryList->length;
$contactList = array();
for ($i = 0; $i < $totalEntries; $i++) {
$currentEntry = $entryList->item($i);
$titleNodes = $xpath->query('atom:title', $currentEntry);
$nameNode = $titleNodes->item(0);
$contactName = $nameNode->textContent;
$emailNodes = $xpath->query('gdata:email', $currentEntry);
$emailNode = $emailNodes->item(0);
$emailAddr = $emailNode->getAttribute('address');
if (empty($contactName)) {
$contactList[] = $emailAddr;
} else {
$contactList[$contactName] = $emailAddr;
}
}
return $contactList;
}
}
The error happens on the getAttribute('address') line. It appears that $emailNode is null when dealing with larger sets of results. How can I resolve this issue to retrieve all contacts instead of just 25?