diff options
| author | Tristan Zur <tzur@web.web.ccwn.org> | 2014-03-27 22:27:47 +0100 |
|---|---|---|
| committer | Tristan Zur <tzur@web.web.ccwn.org> | 2014-03-27 22:27:47 +0100 |
| commit | b62676ca5d3d6f6ba3f019ea3f99722e165a98d8 (patch) | |
| tree | 86722cb80f07d4569f90088eeaea2fc2f6e2ef94 /webmail/plugins/google_contacts | |
Diffstat (limited to 'webmail/plugins/google_contacts')
24 files changed, 1207 insertions, 0 deletions
diff --git a/webmail/plugins/google_contacts/CHANGELOG b/webmail/plugins/google_contacts/CHANGELOG new file mode 100644 index 0000000..bb03e27 --- /dev/null +++ b/webmail/plugins/google_contacts/CHANGELOG @@ -0,0 +1,43 @@ +2.12 08/04/2013 +- Added delay to prevent google errors due to loading too fast. Previous +versions would cause over quota errors. If you get these errors with this +version, look at line 684 in google-contacts.php 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. + +2.11 12/21/2011 +- Added photos to google contacts. It is one-way only. Photos on google +will show up in RC, new photos added to RC will not appear on google. + +2.10 11/12/2011 +- Fixed new bug which prevented deleting contacts on google. caused by changes to RC core + +2.09 11/11/2011 +- Fixed bug in backend which caused server error in newer releases of RC. + +2.08 06/29/2011 +- Drag and drop copy from other addressbooks to google contacts was broken by a rc revision. Fixed to be compatable + +2.07 06/28/2011 +- Made a change to keep up with new core svn revisions. Fixed duplicate address tab in settings +- Changed backend to have get_name function to be compatable with new svn revision + +2.06 06/05/2011 +- Corrected a bug that showed up on svn revision 4836 + +2.05 5/27/2011 +- Changed section for settings to match new SVN Revsion 4814 +- Added exception catching for bad google username/password combos + +2.04 5/24/2011 +- Modified delete function to use protocol version 1 so that modifications to Zend are no longer necessary +- Moved google authentication to init so it doesn't have to authenticate on each transaction which caused google to do CAPTCHA requests. + +2.03 5/23/2011 +- Added drag and drop functionality for dragging to or from other contact lists +- Added re-sync to occur when changing google user/pass in settings +- RC Version 4804 was releaseed today, modifications to core no longer necessary + +2.02 05/22/2011 +- Cleaned up data problems with some data going to google +- Changed update to actually update the google record instead of deleting and resending diff --git a/webmail/plugins/google_contacts/README b/webmail/plugins/google_contacts/README new file mode 100644 index 0000000..fd88348 --- /dev/null +++ b/webmail/plugins/google_contacts/README @@ -0,0 +1,31 @@ +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, my email address is in google_contacts.php + +Will sync Google contacts both directions including all the new contacts +fields in RoundCube 0.9 + + +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 + + diff --git a/webmail/plugins/google_contacts/SQL/mssql.initial.sql b/webmail/plugins/google_contacts/SQL/mssql.initial.sql new file mode 100644 index 0000000..6dfb4b4 --- /dev/null +++ b/webmail/plugins/google_contacts/SQL/mssql.initial.sql @@ -0,0 +1,34 @@ +CREATE TABLE [dbo].[google_contacts] (
+ [contact_id] [int] IDENTITY (1, 1) NOT NULL ,
+ [user_id] [int] NOT NULL ,
+ [changed] [datetime] NOT NULL ,
+ [del] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [name] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [email] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [firstname] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [surname] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [vcard] [text] COLLATE Latin1_General_CI_AI NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[google_contacts] WITH NOCHECK ADD
+ CONSTRAINT [PK_google_contacts_contact_id] PRIMARY KEY CLUSTERED
+ (
+ [contact_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[google_contacts] ADD
+ CONSTRAINT [DF_google_contacts_user_id] DEFAULT (0) FOR [user_id],
+ CONSTRAINT [DF_google_contacts_changed] DEFAULT (getdate()) FOR [changed],
+ CONSTRAINT [DF_google_contacts_del] DEFAULT ('0') FOR [del],
+ CONSTRAINT [DF_google_contacts_name] DEFAULT ('') FOR [name],
+ CONSTRAINT [DF_google_contacts_email] DEFAULT ('') FOR [email],
+ CONSTRAINT [DF_google_contacts_firstname] DEFAULT ('') FOR [firstname],
+ CONSTRAINT [DF_google_contacts_surname] DEFAULT ('') FOR [surname],
+ CONSTRAINT [CK_google_contacts_del] CHECK ([del] = '1' or [del] = '0')
+GO
+
+ CREATE INDEX [IX_google_contacts_user_id] ON [dbo].[google_contacts]([user_id]) ON [PRIMARY]
+GO
+
diff --git a/webmail/plugins/google_contacts/SQL/mysql.initial.sql b/webmail/plugins/google_contacts/SQL/mysql.initial.sql new file mode 100644 index 0000000..b57704c --- /dev/null +++ b/webmail/plugins/google_contacts/SQL/mysql.initial.sql @@ -0,0 +1,4 @@ +CREATE TABLE google_contacts LIKE contacts;
+
+ALTER TABLE `google_contacts`
+ ADD CONSTRAINT `google_contacts_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
diff --git a/webmail/plugins/google_contacts/SQL/postgres.initial.sql b/webmail/plugins/google_contacts/SQL/postgres.initial.sql new file mode 100644 index 0000000..d8dee00 --- /dev/null +++ b/webmail/plugins/google_contacts/SQL/postgres.initial.sql @@ -0,0 +1,30 @@ +--
+-- Sequence "collected_contact_ids"
+-- Name: collected_contact_ids; Type: SEQUENCE; Schema: public; Owner: postgres
+--
+
+CREATE SEQUENCE collected_contact_ids
+ START WITH 1
+ INCREMENT BY 1
+ NO MAXVALUE
+ NO MINVALUE
+ CACHE 1;
+
+--
+-- Table "google_contacts"
+-- Name: google_contacts; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE google_contacts (
+ contact_id integer DEFAULT nextval('collected_contact_ids'::text) PRIMARY KEY,
+ user_id integer NOT NULL REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ changed timestamp with time zone DEFAULT now() NOT NULL,
+ del smallint DEFAULT 0 NOT NULL,
+ name character varying(128) DEFAULT ''::character varying NOT NULL,
+ email character varying(128) DEFAULT ''::character varying NOT NULL,
+ firstname character varying(128) DEFAULT ''::character varying NOT NULL,
+ surname character varying(128) DEFAULT ''::character varying NOT NULL,
+ vcard text
+);
+
+CREATE INDEX google_contacts_user_id_idx ON google_contacts (user_id);
diff --git a/webmail/plugins/google_contacts/SQL/sqlite.initial.sql b/webmail/plugins/google_contacts/SQL/sqlite.initial.sql new file mode 100644 index 0000000..e775a00 --- /dev/null +++ b/webmail/plugins/google_contacts/SQL/sqlite.initial.sql @@ -0,0 +1,13 @@ +CREATE TABLE google_contacts (
+ contact_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL default '0',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ email varchar(128) NOT NULL default '',
+ firstname varchar(128) NOT NULL default '',
+ surname varchar(128) NOT NULL default '',
+ vcard text NOT NULL default ''
+);
+
+CREATE INDEX ix_google_contacts_user_id ON google_contacts(user_id);
diff --git a/webmail/plugins/google_contacts/config/config.inc.php b/webmail/plugins/google_contacts/config/config.inc.php new file mode 100644 index 0000000..a57cd43 --- /dev/null +++ b/webmail/plugins/google_contacts/config/config.inc.php @@ -0,0 +1,12 @@ +<?php + +/* Default addressbook source */ +$rcmail_config['default_addressbook'] = '0'; + +/* database table name */ +$rcmail_config['db_table_google_contacts'] = 'google_contacts'; + +/* max results */ +$rcmail_config['google_contacts_max_results'] = 1000; + +?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/config/config.inc.php.dist b/webmail/plugins/google_contacts/config/config.inc.php.dist new file mode 100644 index 0000000..a57cd43 --- /dev/null +++ b/webmail/plugins/google_contacts/config/config.inc.php.dist @@ -0,0 +1,12 @@ +<?php + +/* Default addressbook source */ +$rcmail_config['default_addressbook'] = '0'; + +/* database table name */ +$rcmail_config['db_table_google_contacts'] = 'google_contacts'; + +/* max results */ +$rcmail_config['google_contacts_max_results'] = 1000; + +?>
\ No newline at end of file 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 diff --git a/webmail/plugins/google_contacts/google_contacts_backend.php b/webmail/plugins/google_contacts/google_contacts_backend.php new file mode 100644 index 0000000..f88c2dd --- /dev/null +++ b/webmail/plugins/google_contacts/google_contacts_backend.php @@ -0,0 +1,33 @@ +<?php + +/** + * Google contacts backend + * + * Minimal backend for Google contacts + * + * @author Roland 'rosali' Liebl + * @version 1.0 + */ + +class google_contacts_backend extends rcube_contacts +{ + + public $name; + + function __construct($dbconn, $user) + { + $this->name = 'Google Contacts'; + $rcmail = rcmail::get_instance(); + parent::__construct($dbconn, $user); + $this->db_name = get_table_name('google_contacts'); + $this->ready = true; + } + + public function get_name() + { + return $this->name; + } + + +} +?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/bg_BG.inc b/webmail/plugins/google_contacts/localization/bg_BG.inc new file mode 100644 index 0000000..e231317 --- /dev/null +++ b/webmail/plugins/google_contacts/localization/bg_BG.inc @@ -0,0 +1,23 @@ +<?php + +/* ++-----------------------------------------------------------------------+ +| language/bg_BG/labels.inc | +| | +| Language file of the RoundCube Webmail client | +| Copyright (C) 2008-2009, RoundQube Dev. - Switzerland | +| Licensed under the GNU GPL | +| | ++-----------------------------------------------------------------------+ +| Author: | ++-----------------------------------------------------------------------+ + +*/ + +$labels = array(); +$labels['googlecontacts'] = 'Google контакт'; +$labels['usegoogleabook'] = 'Използвай адресна книга от Google'; +$labels['googleuser'] = 'Потребител'; +$labels['googlepass'] = 'Парола'; + +?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/cs_CZ.inc b/webmail/plugins/google_contacts/localization/cs_CZ.inc new file mode 100644 index 0000000..72d921a --- /dev/null +++ b/webmail/plugins/google_contacts/localization/cs_CZ.inc @@ -0,0 +1,25 @@ +<?php + +/* ++-----------------------------------------------------------------------+ +| language/cs_CZ/labels.inc | +| | +| Language file of the RoundCube Webmail client | +| Copyright (C) 2008-2009, RoundQube Dev. - Switzerland | +| Licensed under the GNU GPL | +| | ++-----------------------------------------------------------------------+ +| Author: Ales Pospichal <ales@pospichalales.info> | ++-----------------------------------------------------------------------+ + +*/ + +$labels = array(); +$labels['googlecontacts'] = 'Kontakty Google'; +$labels['usegoogleabook'] = 'Použít adresář Google'; +$labels['googleuser'] = 'Účet Google'; +$labels['googlepass'] = 'Heslo pro Google'; +$labels['googlepassisset'] = 'Heslo pro Google je stále k dispozici'; +$labels['googlepassisnotset'] = 'Heslo pro Google není k dispozici'; + +?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/da_DK.inc b/webmail/plugins/google_contacts/localization/da_DK.inc new file mode 100644 index 0000000..0f72627 --- /dev/null +++ b/webmail/plugins/google_contacts/localization/da_DK.inc @@ -0,0 +1,28 @@ +<?php
+
+/*
++-----------------------------------------------------------------------+
+| language/da_DK/labels.inc |
+| |
+| Language file of the RoundCube Webmail client |
+| Copyright (C) 2008-2009, RoundQube Dev. - Switzerland |
+| Licensed under the GNU GPL |
+| |
++-----------------------------------------------------------------------+
+| Author: |
++-----------------------------------------------------------------------+
+
+*/
+
+$labels = array();
+$labels['googlecontacts'] = 'Google kontakter';
+$labels['usegoogleabook'] = 'Brug Google adressebog';
+$labels['googleuser'] = 'Google konto';
+$labels['googlepass'] = 'Google password';
+$labels['googlepassisset'] = 'Google password er indtastet';
+$labels['googlepassisnotset'] = 'Google password er ikke indtastet';
+
+$messages = array();
+$messages['abookreadonly'] = 'Der kan ikke skrives i adressebogen.';
+
+?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/de_DE.inc b/webmail/plugins/google_contacts/localization/de_DE.inc new file mode 100644 index 0000000..0ab5c80 --- /dev/null +++ b/webmail/plugins/google_contacts/localization/de_DE.inc @@ -0,0 +1,12 @@ +<?php
+$labels = array();
+$labels['googlecontacts'] = 'Google Adressen';
+$labels['usegoogleabook'] = 'Verwende Google-Adressbuch';
+$labels['googleuser'] = 'Google Konto';
+$labels['googlepass'] = 'Google Passwort';
+$labels['googlepassisset'] = 'Google Passwort ist gesetzt';
+$labels['googlepassisnotset'] = 'Google Passwort ist nicht gesetzt';
+
+$messages = array();
+$messages['abookreadonly'] = 'Dieses Adressbuch ist nicht editierbar.';
+?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/en_US.inc b/webmail/plugins/google_contacts/localization/en_US.inc new file mode 100644 index 0000000..830e945 --- /dev/null +++ b/webmail/plugins/google_contacts/localization/en_US.inc @@ -0,0 +1,12 @@ +<?php
+$labels = array();
+$labels['googlecontacts'] = 'Google Contacts';
+$labels['usegoogleabook'] = 'Use Google address book';
+$labels['googleuser'] = 'Google Account';
+$labels['googlepass'] = 'Google Password';
+$labels['googlepassisset'] = 'Google Password is present';
+$labels['googlepassisnotset'] = 'Google Password is not present';
+
+$messages = array();
+$messages['abookreadonly'] = 'Addressbook is readonly.';
+?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/es_ES.inc b/webmail/plugins/google_contacts/localization/es_ES.inc new file mode 100644 index 0000000..0a85c29 --- /dev/null +++ b/webmail/plugins/google_contacts/localization/es_ES.inc @@ -0,0 +1,12 @@ +<?php
+$labels = array();
+$labels['googlecontacts'] = 'Contactos de Google';
+$labels['usegoogleabook'] = 'Usar la libreta de direciones de Google';
+$labels['googleuser'] = 'Cuenta de Google';
+$labels['googlepass'] = 'Contraseña de Google';
+$labels['googlepassisset'] = 'La contraseña de Google está configurada';
+$labels['googlepassisnotset'] = 'La contraseña de Google no está configurada';
+
+$messages = array();
+$messages['abookreadonly'] = 'La libreta de direcciones es de sólo lectura.';
+?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/fr_FR.inc b/webmail/plugins/google_contacts/localization/fr_FR.inc new file mode 100644 index 0000000..4606261 --- /dev/null +++ b/webmail/plugins/google_contacts/localization/fr_FR.inc @@ -0,0 +1,25 @@ +<?php + +/* ++-----------------------------------------------------------------------+ +| language/fr_FR/labels.inc | +| | +| Language file of the RoundCube Webmail client | +| Copyright (C) 2008-2010, RoundQube Dev. - Switzerland | +| Licensed under the GNU GPL | +| | ++-----------------------------------------------------------------------+ +| Author: | ++-----------------------------------------------------------------------+ + +*/ + +$labels = array(); +$labels['googlecontacts'] = 'Contacts Google'; +$labels['usegoogleabook'] = 'Utiliser le carnet d\'adresses Google'; +$labels['googleuser'] = 'Compte Google'; +$labels['googlepass'] = 'Mot de passe Google'; +$labels['googlepassisset'] = 'Le mot de passe Google est présent'; +$labels['googlepassisnotset'] = 'Le mot de passe Google est absent'; + +?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/gl_ES.inc b/webmail/plugins/google_contacts/localization/gl_ES.inc new file mode 100644 index 0000000..9cec917 --- /dev/null +++ b/webmail/plugins/google_contacts/localization/gl_ES.inc @@ -0,0 +1,12 @@ +<?php
+$labels = array();
+$labels['googlecontacts'] = 'Contactos de Google';
+$labels['usegoogleabook'] = 'Usar o caderno de enderezos de Google';
+$labels['googleuser'] = 'Conta de Google';
+$labels['googlepass'] = 'Contrasinal de Google';
+$labels['googlepassisset'] = 'O contrasinal de Google está configurado';
+$labels['googlepassisnotset'] = 'O contrasinal de Google non está configurado';
+
+$messages = array();
+$messages['abookreadonly'] = 'O caderno de enderezos é de só lectura.';
+?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/it_IT.inc b/webmail/plugins/google_contacts/localization/it_IT.inc new file mode 100644 index 0000000..c91b25e --- /dev/null +++ b/webmail/plugins/google_contacts/localization/it_IT.inc @@ -0,0 +1,12 @@ +<?php
+$labels = array();
+$labels['googlecontacts'] = 'Contatti Google';
+$labels['usegoogleabook'] = 'Usa rubrica Google';
+$labels['googleuser'] = 'Conto su Google';
+$labels['googlepass'] = 'Password di Google';
+$labels['googlepassisset'] = 'La password di Google è già presente';
+$labels['googlepassisnotset'] = 'La password di Google non è presente';
+
+$messages = array();
+$messages['abookreadonly'] = 'La rubrica è in sola lettura.';
+?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/nl_NL.inc b/webmail/plugins/google_contacts/localization/nl_NL.inc new file mode 100644 index 0000000..332de19 --- /dev/null +++ b/webmail/plugins/google_contacts/localization/nl_NL.inc @@ -0,0 +1,25 @@ +<?php + +/* ++-----------------------------------------------------------------------+ +| language/nl_NL/labels.inc | +| | +| Language file of the RoundCube Webmail client | +| Copyright (C) 2008-2009, RoundQube Dev. - Switzerland | +| Licensed under the GNU GPL | +| | ++-----------------------------------------------------------------------+ +| Author: | ++-----------------------------------------------------------------------+ + +*/ + +$labels = array(); +$labels['googlecontacts'] = 'Google Contacten'; +$labels['usegoogleabook'] = 'Gebruik Google adresboek'; +$labels['googleuser'] = 'Google Account'; +$labels['googlepass'] = 'Google Wachtwoord'; +$labels['googlepassisset'] = 'Google Wachtwoord is ingesteld'; +$labels['googlepassisnotset'] = 'Google Wachtwoord is niet ingesteld'; + +?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/pl_PL.inc b/webmail/plugins/google_contacts/localization/pl_PL.inc new file mode 100644 index 0000000..723e8e1 --- /dev/null +++ b/webmail/plugins/google_contacts/localization/pl_PL.inc @@ -0,0 +1,25 @@ +<?php + +/* ++-----------------------------------------------------------------------+ +| language/pl_PL/labels.inc | +| | +| Language file of the RoundCube Webmail client | +| Copyright (C) 2008-2009, RoundQube Dev. - Switzerland | +| Licensed under the GNU GPL | +| | ++-----------------------------------------------------------------------+ +| Author: Hedo77 g.rybicki|at|c2n.pl | ++-----------------------------------------------------------------------+ + +*/ + +$labels = array(); +$labels['googlecontacts'] = 'Kontakty Google'; +$labels['usegoogleabook'] = 'Użyj książki adresowej Google'; +$labels['googleuser'] = 'Konto Google'; +$labels['googlepass'] = 'Hasło Google'; +$labels['googlepassisset'] = 'Pokazuj hasło Google '; +$labels['googlepassisnotset'] = 'Nie pokazuj hasła Google'; + +?> diff --git a/webmail/plugins/google_contacts/localization/pt_BR.inc b/webmail/plugins/google_contacts/localization/pt_BR.inc new file mode 100644 index 0000000..d7cb9bd --- /dev/null +++ b/webmail/plugins/google_contacts/localization/pt_BR.inc @@ -0,0 +1,25 @@ +<?php + +/* ++-----------------------------------------------------------------------+ +| language/pt_BR/labels.inc | +| | +| Language file of the RoundCube Webmail client | +| Copyright (C) 2008-2009, RoundQube Dev. - Switzerland | +| Licensed under the GNU GPL | +| | ++-----------------------------------------------------------------------+ +| Author: trturino | ++-----------------------------------------------------------------------+ + +*/ + +$labels = array(); +$labels['googlecontacts'] = 'Contatos Google'; +$labels['usegoogleabook'] = 'Usar catálogo de endereços do Google'; +$labels['googleuser'] = 'Conta Google'; +$labels['googlepass'] = 'Senha Google'; +$labels['googlepassisset'] = 'Senha está preenchida'; +$labels['googlepassisnotset'] = 'Senha não está preenchida'; + +?>
\ No newline at end of file diff --git a/webmail/plugins/google_contacts/localization/sv_SE.inc b/webmail/plugins/google_contacts/localization/sv_SE.inc new file mode 100644 index 0000000..a1ce82f --- /dev/null +++ b/webmail/plugins/google_contacts/localization/sv_SE.inc @@ -0,0 +1,12 @@ +<?php
+$labels = array();
+$labels['googlecontacts'] = 'Google Kontakter';
+$labels['usegoogleabook'] = 'Använd Googles adressbok';
+$labels['googleuser'] = 'Google-konto';
+$labels['googlepass'] = 'Google-lösenord';
+$labels['googlepassisset'] = 'Google-lösenord är inställt';
+$labels['googlepassisnotset'] = 'Google-lösenord är inte inställt';
+
+$messages = array();
+$messages['abookreadonly'] = 'Adressboken går endast att läsa.';
+?>
diff --git a/webmail/plugins/google_contacts/localization/zh_TW.inc b/webmail/plugins/google_contacts/localization/zh_TW.inc new file mode 100644 index 0000000..285d665 --- /dev/null +++ b/webmail/plugins/google_contacts/localization/zh_TW.inc @@ -0,0 +1,25 @@ +<?php + +/* ++-----------------------------------------------------------------------+ +| language/zh_TW/labels.inc | +| | +| Language file of the RoundCube Webmail client | +| Copyright (C) 2008-2009, RoundQube Dev. - Switzerland | +| Licensed under the GNU GPL | +| | ++-----------------------------------------------------------------------+ +| Author: ysliuthomas | ++-----------------------------------------------------------------------+ + +*/ + +$labels = array(); +$labels['googlecontacts'] = 'Google聯絡人'; +$labels['usegoogleabook'] = '使用Google通訊錄'; +$labels['googleuser'] = 'Google帳號'; +$labels['googlepass'] = 'Google密碼'; +$labels['googlepassisset'] = 'Google密碼已填寫'; +$labels['googlepassisnotset'] = 'Google密碼未填寫'; + +?>
\ No newline at end of file |
