$value)
+ {
+ $cleaned[$i][$name] = $GLOBALS['egw']->strip_html($dirty[$i][$name]);
+ }
+ }
+ else
+ {
+ $cleaned[$i] == $GLOBALS['egw']->strip_html($dirty[$i]);
+ }
+ }
+ return $cleaned;
+ }
+
+ // return array with all addressbook categories (for xmlrpc)
+ function categories($complete = False)
+ {
+ return $this->xmlrpc ? $GLOBALS['server']->categories($complete) : False;
+ }
+
+ // return array with all addressbook customfields (for xmlrpc)
+ function customfields($new_fields=False)
+ {
+ $fields = CreateObject('addressbook.bofields');
+
+ if(is_array($new_fields) && count($new_fields))
+ {
+ if(!$GLOBALS['egw_info']['user']['apps']['admin'])
+ {
+ $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
+ }
+ foreach($new_fields as $new)
+ {
+ $fields->_save('',$new);
+ }
+ }
+ $customfields = array();
+ foreach($fields->_read() as $data)
+ {
+ $customfields[$data['name']] = $data['title'];
+ }
+ if($this->xmlrpc && !isset($customfields['freebusy_url']))
+ {
+ $fields->_save('','freebusy URL');
+ $customfields['freebusy_url'] = 'freebusy URL';
+ }
+ return $customfields;
+ }
+
+ // translate array of internal datas to xmlrpc, eg. format bday as iso8601
+ function data2xmlrpc($datas)
+ {
+ if(is_array($datas))
+ {
+ foreach($datas as $n => $data)
+ {
+ // translate birthday to a iso8601 date
+ if(isset($data['bday']))
+ {
+ if(strlen($data['bday']) > 2)
+ {
+ list($m,$d,$y) = explode('/',$data['bday']);
+ }
+ else
+ {
+ $y = $m = $d = 0;
+ }
+ $datas[$n]['bday'] = $GLOBALS['server']->date2iso8601(array('year'=>$y,'month'=>$m,'mday'=>$d));
+ }
+ // translate modification time
+ if(isset($data['last_mod']))
+ {
+ $datas[$n]['last_mod'] = $GLOBALS['server']->date2iso8601($data['last_mod']);
+ }
+ // translate categories-id-list to array with id-name pairs
+ if(isset($data['cat_id']))
+ {
+ $datas[$n]['cat_id'] = $GLOBALS['server']->cats2xmlrpc(explode(',',$data['cat_id']));
+ }
+ }
+ }
+ return $datas;
+ }
+
+ // retranslate from xmlrpc / iso8601 to internal format
+ function xmlrpc2data($data)
+ {
+ if(isset($data['bday']))
+ {
+ $arr = $GLOBALS['server']->iso86012date($data['bday']);
+ $data['bday'] = $arr['year'] && $arr['month'] && $arr['mday'] ? sprintf('%d/%02d/%04d',$arr['month'],$arr['mday'],$arr['year']) : '';
+ }
+ if(isset($data['last_mod']))
+ {
+ $data['last_mod'] = $GLOBALS['server']->iso86012date($data['last_mod'],True);
+ }
+ if(isset($data['cat_id']))
+ {
+ $cats = $GLOBALS['server']->xmlrpc2cats($data['cat_id']);
+ $data['cat_id'] = count($cats) > 1 ? ','.implode(',',$cats).',' : (int)$cats[0];
+ }
+ return $data;
+ }
+
+ // return a pseudo addressbook-entry for a user
+ function user_pseudo_entry($account)
+ {
+ static $prefs=False;
+ if(!is_object($prefs))
+ {
+ $prefs = CreateObject('phpgwapi.preferences'); // wie need a new copy, as wie change the user
+ }
+ if(!is_array($account))
+ {
+ $GLOBALS['egw']->accounts->account_id = $account;
+ $account = $GLOBALS['egw']->accounts->read_repository();
+ }
+ $prefs->account_id = $account['account_id'];
+ $prefs->read_repository();
+ $freebusy_url = $GLOBALS['egw_info']['server']['webserver_url'].'/calendar/freebusy.php?user='.$account['account_lid'];
+ if($freebusy_url[0] == '/')
+ {
+ $freebusy_url = ($_SERVER['HTTPS'] ? 'https://' : 'http://').$_SERVER['HTTP_HOST'].$freebusy_url;
+ }
+ $firstname = $account['account_firstname'] ? $account['account_firstname'] : $account['firstname'];
+ $lastname = $account['account_lastname'] ? $account['account_lastname'] : $account['lastname'];
+ $ret = array(
+ 'n_family' => $lastname,
+ 'n_given' => $firstname,
+ 'fn' => $GLOBALS['egw']->common->display_fullname($account['account_lid'],$firstname,$lastname),
+ 'email' => $prefs->email_address($account['account_id']),
+ 'freebusy_url' => $freebusy_url,
+ 'rights' => PHPGW_ACL_READ, // readonly access
+ 'id' => -$account['account_id'],
+ 'tid' => 'p', // Profil
+ );
+ //echo "user_pseudo_entry(".print_r($account,True).")=".print_r($ret,True)."
";
+ return $ret;
+ }
+
+ function get_users($type='all')
+ {
+ $users = array();
+ switch($type)
+ {
+ case 'all': // all
+ $accounts = $GLOBALS['egw']->accounts->get_list('accounts');
+ break;
+ case 'calendar': // Calendar users
+ $accounts = $GLOBALS['egw']->acl->get_ids_for_location('run',1,'calendar');
+ break;
+ case 'groupmates': // Groupmates
+ $accounts = array();
+ foreach($GLOBALS['egw']->accounts->membership() as $group)
+ {
+ $accounts[] = $group['account_id'];
+ }
+ break;
+ }
+ foreach($accounts as $key => $account)
+ {
+ if($type == 'calendar' && $GLOBALS['egw']->accounts->get_type($account) == 'g' || $type == 'groupmates')
+ {
+ // $account is a group
+ unset($accounts[$key]);
+ $members = $GLOBALS['egw']->accounts->member($account);
+ if(is_array($members))
+ {
+ foreach($members as $member)
+ {
+ $accounts[] = $member['account_id'];
+ }
+ }
+ }
+ }
+ if($type != 'all')
+ {
+ $accounts = array_unique($accounts); // remove doubles
+ }
+ $prefs = CreateObject('phpgwapi.preferences'); // wie need a new copy, as wie change the user
+ foreach($accounts as $account)
+ {
+ $users[] = $this->user_pseudo_entry($account);
+ }
+ return $users;
+ }
+
+ function read_entries($data)
+ {
+ if($this->xmlrpc && !isset($data['fields']))
+ {
+ $data['fields'] = array_keys(array_merge($this->so->contacts->non_contact_fields,$this->so->contacts->stock_contact_fields,$this->customfields()));
+ }
+ $entries = $this->so->read_entries($data);
+ $this->total = $this->so->contacts->total_records;
+ if(!is_array($entries))
+ {
+ $entries = array();
+ }
+ else
+ {
+ $entries = $this->strip_html($entries);
+ }
+ // evtl. get uses as read-only addressbook entries, just with Name, Firstname, Email
+ if(@$data['include_users'])
+ {
+ $entries = array_merge($entries,$this->get_users($data['include_users']));
+ }
+ if($this->xmlrpc)
+ {
+ $entries = $this->data2xmlrpc($entries);
+ }
+ if($this->debug) { echo '
Total records="' . $this->total . '"'; }
+ return $entries;
+ }
+
+ function read_entry($data)
+ {
+ if($this->xmlrpc && !isset($data['fields']))
+ {
+ $data['fields'] = array_keys(array_merge($this->so->contacts->non_contact_fields,$this->so->contacts->stock_contact_fields,$this->customfields()));
+ }
+ if($data['id'] < 0)
+ {
+ $entry = array($this->user_pseudo_entry(-$data['id']));
+ if($this->xmlrpc)
+ {
+ $entry = $this->data2xmlrpc($entry);
+ }
+ return $entry;
+ }
+ if($this->check_perms($data,PHPGW_ACL_READ))
+ {
+ $entry = $this->so->read_entry($data['id'],$data['fields']);
+ $entry = $this->strip_html($entry);
+ if($this->xmlrpc)
+ {
+ $entry = $this->data2xmlrpc($entry);
+ }
+ return $entry;
+ }
+ if($this->xmlrpc)
+ {
+ $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
+ }
+ return False;
+ }
+
+ function read_last_entry($fields)
+ {
+ if($this->check_perms($fields,PHPGW_ACL_READ))
+ {
+ $entry = $this->so->read_last_entry($fields);
+ $entry = $this->strip_html($entry);
+ if($this->xmlrpc)
+ {
+ $entry = $this->data2xmlrpc($entry);
+ }
+ return $entry;
+ }
+ if($this->xmlrpc)
+ {
+ $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
+ }
+ return False;
+ }
+
+ function add_vcard($uploadedfile='')
+ {
+ if($uploadedfile == 'none' || $uploadedfile == '' || substr($uploadedfile['name'],-4) != '.vcf')
+ {
+ return False;
+ }
+ else
+ {
+ $filename = $uploadedfile['tmp_name'];
+
+ $vcard = CreateObject('phpgwapi.vcard');
+ $entry = $vcard->in_file($filename);
+ /* _debug_array($entry);exit; */
+ $entry['owner'] = (int)$GLOBALS['egw_info']['user']['account_id'];
+ $entry['access'] = 'private';
+ $entry['tid'] = 'n';
+ /* _debug_array($entry);exit; */
+
+ $this->so->add_entry($entry);
+ $ab_id = $this->get_lastid();
+
+ return(int)$ab_id;
+ }
+ }
+
+ function add_email()
+ {
+ global $name,$referer;
+
+ $named = explode(' ', $name);
+ for($i=count($named);$i>=0;$i--) { $names[$i] = $named[$i]; }
+ if($names[2])
+ {
+ $fields['n_given'] = $names[0];
+ $fields['n_middle'] = $names[1];
+ $fields['n_family'] = $names[2];
+ }
+ else
+ {
+ $fields['n_given'] = $names[0];
+ $fields['n_family'] = $names[1];
+ }
+ $fields['email'] = $add_email;
+ $referer = urlencode($referer);
+
+ $this->so->add_entry($GLOBALS['egw_info']['user']['account_id'],$fields,'private','','n');
+ $ab_id = $this->get_lastid();
+
+ Header('Location: '
+ . $GLOBALS['egw']->link('/index.php',"menuaction=addressbook.uiaddressbook.view&ab_id=$ab_id&referer=$referer"));
+ }
+
+ function add_entry($fields)
+ {
+ // setting some defaults, if not set eg. via xmlrpc
+ $fields['tid'] = trim($fields['tid']);
+ if(empty($fields['tid']))
+ {
+ $fields['tid'] = 'n';
+ }
+ if(!@$fields['owner'])
+ {
+ $fields['owner'] = (int)$GLOBALS['egw_info']['user']['account_id'];
+ }
+ if(empty($fields['access']))
+ {
+ $fields['access'] = 'public';
+ }
+ if($this->xmlrpc)
+ {
+ $fields = $this->xmlrpc2data($fields);
+ }
+ $id = $this->so->add_entry($fields);
+
+ if($id)
+ {
+ $GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $id, 'add', time());
+ }
+
+ if($this->xmlrpc && !$id)
+ {
+ $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
+ }
+ return $id;
+ }
+
+ function get_lastid()
+ {
+ return $this->so->get_lastid();
+ }
+
+ function update_entry($fields)
+ {
+ if(!$fields['id'] && !$fields['ab_id'])
+ {
+ return $this->add_entry($fields);
+ }
+ $ok = False;
+ if($this->check_perms($fields,PHPGW_ACL_EDIT))
+ {
+ if($this->xmlrpc)
+ {
+ $fields = $this->xmlrpc2data($fields);
+ }
+ $ok = $this->so->update_entry($fields);
+ if($ok)
+ {
+ $GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $fields['ab_id'], 'modify', time());
+ }
+ }
+ if($this->xmlrpc && !$ok)
+ {
+ $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
+ }
+ return $ok;
+ }
+
+ function delete_entry($addr)
+ {
+ if(!is_array($addr))
+ {
+ $id = (int)$addr;
+ }
+ else
+ {
+ if(is_numeric($addr[0])) // xmlrpc liefert array($id)
+ {
+ $id = (int)$addr[0];
+ }
+ else
+ {
+ $id = isset($addr['id']) ? $addr['id'] : $addr['ab_id'];
+ }
+ }
+ if($this->check_perms($id,PHPGW_ACL_DELETE))
+ {
+ $this->so->delete_entry($id);
+ $GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $id, 'delete', time());
+ }
+ elseif($this->xmlrpc)
+ {
+ $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
+ }
+ }
+
+ /*!
+ @function check_perms
+ @abstract checks if user has the necessary rights on the given address or address-id
+ @syntax check_perms($addr,$rights)
+ @param $addr mixed address-record with id and owner or addr-id
+ @param $rights integer PHPGW_ACL_{READ|EDIT|ADD|DELETE}
+ @return True if the user has the requested rights, else False
+ */
+ function check_perms($addr,$rights)
+ {
+ $id = (int) (!is_array($addr) ? $addr : (isset($addr['id']) ? $addr['id'] : $addr['ab_id']));
+
+ if($id < 0)
+ {
+ return $rights == PHPGW_ACL_READ;
+ }
+ if(!is_array($addr) || !isset($addr['rights']) && !isset($addr['owner']))
+ {
+ $addr = $this->so->read_entry($id,array('owner'));
+ if(!$addr && $this->xmlrpc)
+ {
+ $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_exist'],$GLOBALS['xmlrpcstr']['not_exist']);
+ }
+ $addr = $addr[0];
+ }
+ $ret = $this->so->contacts->check_perms(False,$rights,$addr);
+ //echo "boaddressbook::check_perms(".print_r($addr,True).",$rights) = ".($ret?'True':'False')."
\n";
+ return $ret;
+ }
+
+ function save_preferences($prefs,$other,$qfields,$fcat_id)
+ {
+ $GLOBALS['egw']->preferences->read_repository();
+ if(is_array($prefs))
+ {
+ /* _debug_array($prefs);exit; */
+ while(list($pref,$x) = each($qfields))
+ {
+ /* echo '
checking: ' . $pref . '=' . $prefs[$pref]; */
+ if($prefs[$pref] == 'on')
+ {
+ $GLOBALS['egw']->preferences->add('addressbook',$pref,'addressbook_on');
+ }
+ else
+ {
+ $GLOBALS['egw']->preferences->delete('addressbook',$pref);
+ }
+ }
+ }
+ if(is_array($other))
+ {
+ $GLOBALS['egw']->preferences->delete('addressbook','mainscreen_showbirthdays');
+ if($other['mainscreen_showbirthdays'])
+ {
+ $GLOBALS['egw']->preferences->add('addressbook','mainscreen_showbirthdays',True);
+ }
+
+ $GLOBALS['egw']->preferences->delete('addressbook','default_filter');
+ if($other['default_filter'])
+ {
+ $GLOBALS['egw']->preferences->add('addressbook','default_filter',$other['default_filter']);
+ }
+
+ $GLOBALS['egw']->preferences->delete('addressbook','autosave_category');
+ if($other['autosave_category'])
+ {
+ $GLOBALS['egw']->preferences->add('addressbook','autosave_category',True);
+ }
+ }
+
+ $GLOBALS['egw']->preferences->delete('addressbook','default_category');
+ $GLOBALS['egw']->preferences->add('addressbook','default_category',$fcat_id);
+
+ $GLOBALS['egw']->preferences->save_repository(True);
+ }
+
+ function list_methods($_type='xmlrpc')
+ {
+ /*
+ This handles introspection or discovery by the logged in client,
+ in which case the input might be an array. The server always calls
+ this function to fill the server dispatch map using a string.
+ */
+ if(is_array($_type))
+ {
+ $_type = $_type['type'] ? $_type['type'] : $_type[0];
+ }
+ switch($_type)
+ {
+ case 'xmlrpc':
+ $xml_functions = array(
+ 'read' => array(
+ 'function' => 'read_entry',
+ 'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+ 'docstring' => lang('Read a single entry by passing the id and fieldlist.')
+ ),
+ 'add' => array(
+ 'function' => 'add_entry',
+ 'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+ 'docstring' => lang('Add a single entry by passing the fields.')
+ ),
+ 'save' => array(
+ 'function' => 'update_entry',
+ 'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+ 'docstring' => lang('Update a single entry by passing the fields.')
+ ),
+ 'write' => array( // alias for consistent nameing
+ 'function' => 'update_entry',
+ 'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+ 'docstring' => lang('Write (update or add) a single entry by passing the fields.')
+ ),
+ 'delete' => array(
+ 'function' => 'delete_entry',
+ 'signature' => array(array(xmlrpcString,xmlrpcString)),
+ 'docstring' => lang('Delete a single entry by passing the id.')
+ ),
+ 'read_list' => array(
+ 'function' => 'read_entries',
+ 'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+ 'docstring' => lang('Read a list / search for entries.')
+ ),
+ 'search' => array( // alias for consitent nameing
+ 'function' => 'read_entries',
+ 'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+ 'docstring' => lang('Read a list / search for entries.')
+ ),
+ 'categories' => array(
+ 'function' => 'categories',
+ 'signature' => array(array(xmlrpcBoolean,xmlrpcBoolean)),
+ 'docstring' => lang('List all categories')
+ ),
+ 'customfields' => array(
+ 'function' => 'customfields',
+ 'signature' => array(array(xmlrpcArray,xmlrpcArray)),
+ 'docstring' => lang('List all customfields')
+ ),
+ 'list_methods' => array(
+ 'function' => 'list_methods',
+ 'signature' => array(array(xmlrpcStruct,xmlrpcString)),
+ 'docstring' => lang('Read this list of methods.')
+ )
+ );
+ return $xml_functions;
+ break;
+ case 'soap':
+ return $this->soap_functions;
+ break;
+ default:
+ return array();
+ break;
+ }
+ }
+ }
+?>