diff options
Diffstat (limited to 'webmail/plugins/google_contacts/google_contacts.php')
| -rw-r--r-- | webmail/plugins/google_contacts/google_contacts.php | 722 |
1 files changed, 722 insertions, 0 deletions
diff --git a/webmail/plugins/google_contacts/google_contacts.php b/webmail/plugins/google_contacts/google_contacts.php new file mode 100644 index 0000000..11a684e --- /dev/null +++ b/webmail/plugins/google_contacts/google_contacts.php @@ -0,0 +1,722 @@ +<?php +/* +Google Contacts for RoundCube 0.6 and above. + +@version 2.12 - 08/04/2013 +@author Les Fenison /-- Original code by Roland 'rosali' Liebl +@licence GNU GPL + +Questions, problems, or suggestions? Email me rc@deltatechnicalservices.com + +Will sync Google contacts both directions including all the new contacts +fields in RoundCube 0.6 + + +Usage: + + Create the db table using the SQL in SQL directory. The table is the same +exact format as the contacts table. If you are upgrading from 0.5.2 you +will need to add the words column of type text. + +copy ./config/config.inc.php.dist to ./config/config.inc.php and configure +as needed. The only parameter worth messing with is the +$rcmail_config['google_contacts_max_results'] which defaults to 1000. + + + Requirements: * Get Zend GData APIs + + /http://framework.zend.com/download/webservices + Copy and paste "Zend" /folder into ./program/lib + + File structure must be: ./program/lib/Zend + + +TODO / bugs + +If you get Google's over quota errors with this version, look at line 684 and increase the number. +The higher the number, the slower the load is. If the number is too small, +google will complain because you are hitting their server too fast. +*/ + +class google_contacts extends rcube_plugin +{ + public $task = "mail|addressbook|settings"; + private $abook_id = 'google_contacts'; + private $user = false; + private $pass = false; + private $contacts; + private $error = false; + private $results = null; + + function init() + { + $this->add_texts('localization/', false); + + if(file_exists("./plugins/google_contacts/config/config.inc.php")) + $this->load_config('config/config.inc.php'); + else + $this->load_config('config/config.inc.php.dist'); + $rcmail = rcmail::get_instance(); + + $this->user = $rcmail->config->get('googleuser'); + $this->pass = $rcmail->config->get('googlepass'); + + if($this->user && $this->pass){ + $this->pass = $rcmail->decrypt($this->pass); + $this->add_hook('addressbooks_list', array($this, 'addressbooks_list')); + $this->add_hook('addressbook_get', array($this, 'addressbook_get')); + $this->add_hook('contact_create', array($this, 'contact_create')); + $this->add_hook('contact_update', array($this, 'contact_update')); + $this->add_hook('contact_delete', array($this, 'contact_delete')); + $this->add_hook('render_page', array($this, 'render_page')); + // use this address book for autocompletion queries + $config = $rcmail->config; + $sources = $config->get('autocomplete_addressbooks', array('sql')); + + if (!in_array($this->abook_id, $sources)){ + $sources[] = $this->abook_id; + $config->set('autocomplete_addressbooks', $sources); + } + } +// $this->add_hook('preferences_sections_list', array($this, 'addressbooksLink')); + $this->add_hook('preferences_list', array($this, 'settings_table')); + $this->add_hook('preferences_save', array($this, 'save_prefs')); + + $dir = INSTALL_PATH . 'program/lib/'; + if(!file_exists($dir . 'Zend/Loader.php')){ + write_log('errors', 'Plugin google_contacts: Zend GData API not installed (http://framework.zend.com/download/webservices)'); + $this->results = array(); + return; + } + require_once $dir . 'Zend/Loader.php'; + Zend_Loader::loadClass('Zend_Gdata'); + Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); + Zend_Loader::loadClass('Zend_Http_Client'); + Zend_Loader::loadClass('Zend_Gdata_Query'); + Zend_Loader::loadClass('Zend_Gdata_Feed'); + + if( !empty($this->user) && !empty($this->pass) ){ + // perform login and set protocol version to 3.0 + try { + $client = Zend_Gdata_ClientLogin::getHttpClient( $this->user, $this->pass, 'cp'); + $client->setHeaders('If-Match: *'); + $this->gdata = new Zend_Gdata($client); + $this->gdata->setMajorProtocolVersion(3); + } catch (Exception $e) { + $this->error = $e->getMessage(); + write_log('google_contacts', $this->error); + if(method_exists($rcmail->output, 'show_message')) + $rcmail->output->show_message($this->error,'error'); + } + } + } + + function render_page($p){ + if($p['template']== 'addressbook'){ + $rcmail = rcmail::get_instance(); + $rcmail->output->command('enable_command','import',false); + $rcmail->output->command('enable_command','add',true); + $script = "rcmail.add_onload(\"rcmail.command('list',rcmail.env.source,false);\");"; + $rcmail->output->add_script($script,'foot'); + } + return $p; + } + + function contact_create($a){ + if( is_null($a['record']) ){ + write_log('google_contacts','null record in create'); + write_log('google_contacts',$a); + $a['abort'] = true; + return $a; + } + + if($a['source'] == $this->abook_id){ + $this->put_contact($a); + $a['record']['edit']=$this->results->google_id; + $a['abort'] = false; + } + + return $a; + } + + function contact_update($a){ + if($a['source'] == $this->abook_id){ + $rcmail = rcmail::get_instance(); + rcmail_overwrite_action('show'); + + $this->put_contact($a, $this->get_google_id($a['id'])) ; + $a['record']['edit']=$this->results->google_id; + + $a['abort'] = false; + } + return $a; + } + + function contact_delete($a){ + if($a['source'] == $this->abook_id){ + foreach( $a['id'] as $id ) { + $this->delete_contact($id); + } + $a['abort'] = false; + } + return $a; + } + + function addressbooks_list($p) + { + $rcmail = rcmail::get_instance(); + if ($rcmail->config->get('use_google_abook')) + $p['sources'][$this->abook_id] = array('id' => $this->abook_id, 'name' => Q($this->gettext('googlecontacts')), 'readonly' => false, 'groups' => false); + $rcmail->output->command('enable_command','import',false); + $rcmail->output->command('enable_command','add',true); + return $p; + } + + function addressbook_get($p) + { + $rcmail = rcmail::get_instance(); + if (($p['id'] === $this->abook_id) && $rcmail->config->get('use_google_abook')) { + require_once(dirname(__FILE__) . '/google_contacts_backend.php'); + $p['instance'] = new google_contacts_backend($rcmail->db, $rcmail->user->ID); + $p['instance']->groups = false; + $this->sync_contacts(); + $rcmail->output->command('enable_command','import',false); + $rcmail->output->command('enable_command','add',true); + } + else{ + if ($p['id'] == $rcmail->config->get('default_addressbook')){ +// $rcmail->output->command('enable_command','import',false); + } + } + return $p; + } + +/* function addressbooksLink($args) + { + $temp = $args['list']['server']; + unset($args['list']['server']); + $args['list']['addressbooks']['id'] = 'addressbook'; + $args['list']['addressbooks']['section'] = $this->gettext('addressbook'); + $args['list']['server'] = $temp; + + return $args; + } +*/ + function settings_table($args) + { + if ($args['section'] == 'addressbook') { + $rcmail = rcmail::get_instance(); + $use_google_abook = $rcmail->config->get('use_google_abook'); + $field_id = 'rcmfd_use_google_abook'; + $checkbox = new html_checkbox(array('name' => '_use_google_abook', 'id' => $field_id, 'value' => 1)); + $args['blocks']['googlecontacts']['name'] = $this->gettext('googlecontacts'); + $args['blocks']['googlecontacts']['options']['use_google_abook'] = array( + 'title' => html::label($field_id, Q($this->gettext('usegoogleabook'))), + 'content' => $checkbox->show($use_google_abook?1:0), + ); + + $field_id = 'rcmfd_google_user'; + $input_googleuser = new html_inputfield(array('name' => '_googleuser', 'id' => $field_id, 'size' => 35)); + $args['blocks']['googlecontacts']['options']['googleuser'] = array( + 'title' => html::label($field_id, Q($this->gettext('googleuser'))), + 'content' => $input_googleuser->show($rcmail->config->get('googleuser')), + ); + + $field_id = 'rcmfd_google_pass'; + if($rcmail->config->get('googlepass')) + $title = $this->gettext('googlepassisset'); + else + $title = $this->gettext('googlepassisnotset'); + $input_googlepass = new html_passwordfield(array('name' => '_googlepass', 'id' => $field_id, 'size' => 35, 'title' => $title)); + $args['blocks']['googlecontacts']['options']['googlepass'] = array('title' => html::label($field_id, Q($this->gettext('googlepass'))),'content' => $input_googlepass->show(),); + } + return $args; + } + + function save_prefs($args) + { + if ($args['section'] == 'addressbook') { + $rcmail = rcmail::get_instance(); + $args['prefs']['use_google_abook'] = isset($_POST['_use_google_abook']) ? true : false; + $args['prefs']['googleuser'] = get_input_value('_googleuser', RCUBE_INPUT_POST); + $pass = get_input_value('_googlepass', RCUBE_INPUT_POST); + if($pass){ + $args['prefs']['googlepass'] = $rcmail->encrypt($pass); + } + if( $args['prefs']['use_google_abook'] && !empty($args['prefs']['googleuser']) && !empty($args['prefs']['googlepass']) ) { + if( $this->user != $args['prefs']['googleuser'] || $this->pass != $args['prefs']['googlepass'] ) { + // sync + $_SESSION['google_contacts_sync'] = false; + } + } else { + // delete + $db_table = $rcmail->config->get('db_table_google_contacts'); + $query = "DELETE FROM $db_table WHERE user_id=?"; + $res = $rcmail->db->query($query, $rcmail->user->ID); + $obj = (array) $this->results; + } + } + return $args; + } + + + + function get_google_id( $recid ) { + $rcmail = rcmail::get_instance(); + require_once(dirname(__FILE__) . '/google_contacts_backend.php'); + $CONTACTS = new google_contacts_backend($rcmail->db, $rcmail->user->ID); + $a_record = $CONTACTS->get_record($recid, true); + + //@ ToDo: roundcube MUST have a function to extract a value from a vcard.. Someday we will find it after they document the code. + // For now, this works fine. + $vcardlines = explode("\n",$a_record['vcard']); + foreach ( $vcardlines as $k=>$v) { + if( strstr($v,'X-AB-EDIT:') ){ + $id=trim(substr($v,strpos($v,':')+1)); + return $id; + } + } + return false; + } + + + /* + NOTE: There is a bug in /Zend/Gdata/App.php. This code will NOT work until the following is applied + for details see http://www.google.com/support/forum/p/apps-apis/thread?tid=11ddcc0df1a25c0a&hl=en + + This code needs to be added to /Zend/Gdata/App.php on line 500 + + if ($data == null && $method == 'DELETE') + { $headers['If-Match'] = '*'; } + */ + function delete_contact( $recid ) + { + $id=$this->get_google_id($recid); + spl_autoload_unregister('rcube_autoload'); + try { + // version 1 method, does not require the zend mod but may change in the future because it is old + $this->gdata->setMajorProtocolVersion(1); + $query = new Zend_Gdata_Query($id); + $entry = $this->gdata->getEntry($query); + $entry->delete($id); + + // version 3 method, newer but requires mod to zend +// $this->gdata->delete($id); + $this->gdata->setMajorProtocolVersion(3); + + } catch (Exception $e) { + $this->error = $e->getMessage(); + write_log('google_contacts', $this->error); + if(method_exists($rcmail->output, 'show_message')) + $rcmail->output->show_message($this->error,'error'); + } + spl_autoload_register('rcube_autoload'); + $this->results = $results; + } + + + // if edit id is supplied, we are updateing an existing contact, if empty, create new contact + function put_contact( $a , $edit_id='') + { + $phonetypes=array('home'=>'home', + 'home2'=>'home', + 'work'=>'work', + 'work2'=> 'work', + 'mobile'=>'mobile', + 'main'=>'main', + 'homefax'=>'home_fax', + 'workfax'=>'work_fax', + 'pager'=>'pager', + 'assistant'=>'assistant', + 'other'=>'other'); + + // google does not have OTHER and rc does not have GOOGLE_TALK. and there is a good probability that if someone specifies other, that it is google_talk. + $imtypes=array('aim'=>'AIM', + 'msn'=>'MSN', + 'icq'=>'ICQ', + 'yahoo'=>'YAHOO', + 'skype'=>'SKYPE', + 'jabber'=>'JABBER', + 'other'=>'GOOGLE_TALK'); + + // google has types that we don't such as profile, home, and ftp + $urltypes=array('homepage'=>'home-page', + 'work'=>'work', + 'other'=>'other', + 'blog'=>'blog'); + + $rcmail = rcmail::get_instance(); + // set credentials for ClientLogin authentication + $user = $this->user; + $pass = $this->pass; + spl_autoload_unregister('rcube_autoload'); + try { + $doc = new DOMDocument(); + $doc->formatOutput = true; + $entry = $doc->createElement('atom:entry'); + $entry->setAttributeNS('http://www.w3.org/2000/xmlns/' , 'xmlns:atom', 'http://www.w3.org/2005/Atom'); + $entry->setAttributeNS('http://www.w3.org/2000/xmlns/' , 'xmlns:gd', 'http://schemas.google.com/g/2005'); + $entry->setAttributeNS('http://www.w3.org/2000/xmlns/' , 'xmlns:gContact', 'http://schemas.google.com/contact/2008'); + $doc->appendChild($entry); + + // Add to the My Contacts Group for now, my contacts are /base/6 This may change some day! + $grp = $doc->createElement('gContact:groupMembershipInfo'); + $grp->setAttribute('href' , "http://www.google.com/m8/feeds/groups/". $user ."/base/6"); + $grp->setAttribute('deleted','false'); + $entry->appendChild($grp); + + // add name element + $name = $doc->createElement('gd:name'); + $entry->appendChild($name); + $fullName = $doc->createElement('gd:fullName', $a['record']['name']); + $name->appendChild($fullName); + + // add org name element + if( isset($a['record']['organization']) ){ + $org = $doc->createElement('gd:organization'); + $org->setAttribute('rel' ,'http://schemas.google.com/g/2005#work'); + $entry->appendChild($org); + $orgName = $doc->createElement('gd:orgName', flatten_array($a['record']['organization'])); + $org->appendChild($orgName); + if( isset($a['record']['jobtitle']) ){ + $orgTitle = $doc->createElement('gd:orgTitle', flatten_array($a['record']['jobtitle'])); + $org->appendChild($orgTitle); + } + } + + // add notes + if( !empty( $a['record']['notes'] ) ){ + // sometimes rc returns this as an array and sometimes not + if( is_array($a['record']['notes']) ){ + $note = implode("\n",$a['record']['notes']); + } else { + $note = $a['record']['notes']; + } + $notes = $doc->createElement('atom:content'); + $notes->setAttribute('type' , "text"); + $notes->appendChild($doc->createTextNode($note)); + $entry->appendChild($notes); + } + + if( !empty($a['record']['nickname']) ){ + $nickname = $doc->createElement('gContact:nickname'); + $nickname->appendChild($doc->createTextNode(flatten_array($a['record']['nickname']))); + $entry->appendChild($nickname); + } + if( !empty($a['record']['gender']) ){ + $gender = $doc->createElement('gContact:gender'); + $gender->setAttribute('value', flatten_array($a['record']['gender'])); + $entry->appendChild($gender); + } + if( !empty($a['record']['maidenname']) ){ + $mname = $doc->createElement('gContact:maidenName'); + $mname->appendChild($doc->createTextNode(flatten_array($a['record']['maidenname']))); + $entry->appendChild($mname); + } + if( !empty($a['record']['birthday']) ){ + $birthday = $doc->createElement('gContact:birthday'); + $birthday->setAttribute('when', date('Y-m-d',strtotime(flatten_array($a['record']['birthday'])))); + $entry->appendChild($birthday); + } + if( !empty($a['record']['anniversary']) ){ + $av = $doc->createElement('gContact:event'); + $av->setAttribute('rel', 'anniversary'); + $wh = $doc->createElement('gd:when'); + $wh->setAttribute('startTime',date('Y-m-d',strtotime(flatten_array($a['record']['anniversary'])))); + $av->appendChild($wh); + $entry->appendChild($av); + } + + // loop thru the rest of the data that could have multiples + foreach( $a['record'] as $key=>$val ) { + if( strstr($key,'phone:') ){ + list($junk,$ptype) = explode(':',$key); + foreach ($val as $phnum ) { + if( !empty($phnum) ){ + // add phone number element + $phoneNumber = $doc->createElement('gd:phoneNumber'); + $phoneNumber->setAttribute('rel', 'http://schemas.google.com/g/2005#'. $phonetypes[$ptype]); + // $phoneNumber->setAttribute('primary', 'true'); + $phoneNumber->appendChild($doc->createTextNode($phnum)); + $entry->appendChild($phoneNumber); + } + } + } + if( strstr($key,'email:') ){ + list($junk,$etype) = explode(':',$key); + foreach( $val as $addr ) { + if( !empty($addr) ) { + // add email element + $email = $doc->createElement('gd:email'); + $email->setAttribute('address' ,$addr); + $email->setAttribute('rel' ,'http://schemas.google.com/g/2005#'.$etype); + $entry->appendChild($email); + } + } + } + if( strstr($key,'im:') ){ + list($junk,$imtype) = explode(':',$key); + foreach( $val as $addr ) { + if( !empty($addr) ){ + // add IM element + $im = $doc->createElement('gd:im'); + $im->setAttribute('address' ,$addr); + $im->setAttribute('protocol' ,'http://schemas.google.com/g/2005#'.$imtypes[$imtype]); + $im->setAttribute('rel' ,'http://schemas.google.com/g/2005#home'); + // $im->setAttribute('primary', 'true'); + $entry->appendChild($im); + } + } + } + if( strstr($key,'website:') ){ + list($junk,$urltype) = explode(':',$key); + foreach( $val as $addr ) { + if( !empty($addr) ){ + // add website element + + $website = $doc->createElement('gContact:website'); + $website->setAttribute('href', $addr); + $website->setAttribute('rel', $urltypes[$urltype]); + $website->setAttribute('xmlns' , "http://schemas.google.com/contact/2008"); + $entry->appendChild($website); + } + } + } + + if( strstr($key,'address:') ){ + list($junk,$addrtype) = explode(':',$key); + foreach( $val as $addr ) { + if( !empty($addr['street']) || !empty($addr['locality']) || !empty($addr['region']) || !empty($addr['zipcode']) || !empty($addr['country']) ){ + $postal = $doc->createElement('gd:structuredPostalAddress'); + $postal->setAttribute('mailClass', 'http://schemas.google.com/g/2005#letters'); + $postal->setAttribute('rel', 'http://schemas.google.com/g/2005#'. $addrtype); + if( !empty($addr['street']) ){ + $street=$doc->createElement('gd:street',$addr['street']); + $postal->appendChild($street); + } + if( !empty($addr['locality']) ){ + $city=$doc->createElement('gd:city',$addr['locality']); + $postal->appendChild($city); + } + if( !empty($addr['region']) ){ + $region=$doc->createElement('gd:region',$addr['region']); + $postal->appendChild($region); + } + if( !empty($addr['zipcode']) ){ + $zip=$doc->createElement('gd:postcode',$addr['zipcode']); + $postal->appendChild($zip); + } + if( !empty($addr['country']) ){ + $country=$doc->createElement('gd:country',$addr['country']); + $postal->appendChild($country); + } + $entry->appendChild($postal); + } + } + } + } + if( empty($edit_id) ) { + // insert entry + $entryResult = $this->gdata->insertEntry($doc->saveXML(), 'http://www.google.com/m8/feeds/contacts/default/full'); + $results->google_id = $entryResult->getEditLink()->href; + } else { + // update entry + $extra_header = array('If-Match'=>'*'); + $entryResult = $this->gdata->updateEntry($doc->saveXML(),$edit_id,null,$extra_header); + $results->google_id = $edit_id; + } + } + catch (Exception $e) { + $this->error = $e->getMessage(); + write_log('google_contacts', $this->error); + if(method_exists($rcmail->output, 'show_message')) + $rcmail->output->show_message($this->error,'error'); + } + spl_autoload_register('rcube_autoload'); + $this->results = $results; + } + + + function sync_contacts() + { + if($_SESSION['google_contacts_sync'] && $_SESSION['google_contacts']->lastuser == $this->user && $_SESSION['google_contacts']->lastpass == $this->pass ) + return; + + $rcmail = rcmail::get_instance(); + require_once(dirname(__FILE__) . '/google_contacts_backend.php'); + $CONTACTS = new google_contacts_backend($rcmail->db, $rcmail->user->ID); + + + $urltypes=array('home' => 'homepage', + 'home-page' => 'homepage', + 'homepage' => 'homepage', + 'work'=>'work', + 'other'=>'other', + 'blog'=>'blog', + ); + + $ptypes=array('home'=>'home', + 'work'=>'work', + 'mobile'=>'mobile', + 'main'=>'main', + 'home_fax'=>'homefax', + 'work_fax'=>'workfax', + 'pager'=>'pager', + 'assistant'=>'assistant', + 'other'=>'other', + ); + + // set credentials for ClientLogin authentication + $user = $this->user; + $pass = $this->pass; + + $_SESSION['google_contacts']->lastuser = $this->user; + $_SESSION['google_contacts']->lastpass = $this->pass; + + try { + // perform login and set protocol version to 3.0 + $client = Zend_Gdata_ClientLogin::getHttpClient( $user, $pass, 'cp'); + $gdata = new Zend_Gdata($client); + $gdata->setMajorProtocolVersion(3); + + $max = $rcmail->config->get('google_contacts_max_results'); + if(empty($max)) + $max = 1000; + // perform query and get result feed. NOTE: using $user here instead of default gives a lot more data, including notes! + $query = new Zend_Gdata_Query('http://www.google.com/m8/feeds/contacts/'. $user .'/full?max-results=' . $max ); + + $feed = $gdata->getFeed($query); + $title = $feed->title; + $totals = $feed->totalResults; + + // delete the cached contents + $db_table = $rcmail->config->get('db_table_google_contacts'); + $query = "DELETE FROM $db_table WHERE user_id=?"; + $res = $rcmail->db->query($query, $rcmail->user->ID); + $obj = (array) $this->results; + + // parse feed and extract contact information + // into simpler objects + foreach($feed as $entry){ + $xml = simplexml_load_string($entry->getXML()); + + $a_record=array(); + $badrec=false; + + $name = (array) $xml->name; + $orgName = (string) $xml->organization->orgName; + if( !empty($name)){ + $a_record['name']= $name['fullName']; + $a_record['firstname'] = $name['givenName']; + $a_record['surname'] = $name['familyName']; + $a_record['middlename'] = $name['additionalName']; + $a_record['prefix'] = $name['namePrefix']; + $a_record['suffix'] = $name['nameSuffix']; + } elseif( !empty($orgName) ) { + $a_record['name'] = $orgName; + } else { + $badrec=true; + } + + $a_record['jobtitle'] = (string) $xml->organization->orgTitle; + $a_record['organization'] = $orgName; + $a_record['birthday'] = (string) @$xml->birthday->attributes()->when; + $a_record['nickname'] = (string) $xml->nickname; + $a_record['gender'] = $xml->gender['value']; + foreach ($xml->im as $e) { + $prot = str_replace('http://schemas.google.com/g/2005#','',$e['protocol']); + $a_record['im:'.strtolower($prot) ] = (string) $e['address']; + } + + // Zend doesn't specify phone number types in $xml, but it is specified in the $entry object.. Dig it out... + $ext=$entry->getExtensionElements(); + foreach( $ext as $key=>$val ){ + if( $val->rootElement == 'phoneNumber' ){ + $ptype=str_replace('http://schemas.google.com/g/2005#','',$val->extensionAttributes['rel']['value']); + $a_record['phone:'. $ptypes[$ptype]] = $val->text; + } + } + + foreach ($xml->email as $e) { + $emtype = str_replace('http://schemas.google.com/g/2005#','',$e['rel']); + $a_record['email:'. $emtype][] = (string) $e['address']; + } + + foreach ($xml->structuredPostalAddress as $a) { + $atype= str_replace('http://schemas.google.com/g/2005#','', (string) $a['rel']); + $address['formatted'] = (string) $a->formattedAddress; + $address['street'] = (string) $a->street; + $address['postcode'] = (string) $a->postcode; + $address['city'] = (string) $a->city; + $address['region'] = (string) $a->region; + $address['country'] = (string) $a->country; + + // if we have all address components, use them, otherwise let vcard figure it out from the formatted address + if( !empty($address['city']) && !empty($address['postcode']) && !empty($address['region']) && !empty($address['street']) ){ + $adr['street'] = $address['street']; + $adr['locality'] = $address['city']; + $adr['zipcode'] = $address['postcode']; + $adr['region'] = $address['region']; + $adr['country'] = $address['country']; + } else { + // Its not a structured address so try to split it up + $addressblk = explode("\n",$address['formatted']); + $adr['street'] = $addressblk[0]; + $adr['locality'] = $address[1]; + $adr['region'] = $address[2]; + $adr['zipcode'] = $address[3]; + $adr['country'] = $address[4]; + } + $a_record['address:'. $atype][]=$adr; + } + + foreach ($xml->website as $w) { + $w = (array) $w; + if( isset( $urltypes[ $w['rel'] ] )) + $stype = $urltypes[ $w['rel'] ]; + else + $stype='other'; + $a_record['website:'. $stype][] = (string) $w['href']; + } + $a_record['edit'] = $entry->getEditLink()->href; + $a_record['notes'] = (string) $entry->content; + +usleep(5000); + + if( !$badrec ) +// start photo + $photoLink = (object) $entry->getLink('http://schemas.google.com/contacts/2008/rel#photo'); + if ( !empty($photoLink) and !empty($photoLink->extensionAttributes) ) { +//write_log('google_contacts',$a_record); +//write_log('google_contacts',$photolink); + $photo = $gdata->get($photoLink->getHref()); // fetch image + $a_record['photoetag'] = $photo->getHeader('ETag'); + $a_record['photo'] = $photo->getBody(); // we have a jpg image + } + +// end photo + $CONTACTS->insert($a_record,false); + } + $_SESSION['google_contacts_sync'] = true; + } + catch (Exception $e) { + $this->error = $e->getMessage(); + write_log('google_contacts', $this->error); + if(method_exists($rcmail->output, 'show_message')) + $rcmail->output->show_message($this->error,'error'); + } + $this->results = $results; + } +} + +// Sometimes rc passes values as arrays that should be flat values. rc is NOT consistant even on the +// same variables. sometimes they are an array, sometimes they are flat. This takes the vars +// that SHOULD be flat and flattens them if they aren't alraady. +function flatten_array( $v ) { + if( is_array($v) ){ + return implode(' ',$v); + } else { + return $v; + } +} +?>
\ No newline at end of file |
