Skip to content

Commit

Permalink
wrap up initial read-only carddav contacts support
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonmunro committed Nov 9, 2018
1 parent 2f2a8a0 commit 66637a8
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 10 deletions.
16 changes: 16 additions & 0 deletions lib/webdav_formats.php
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,25 @@ protected function parse_adr($vals) {
'postal_code' => $flds[5],
'country' => $flds[6]
);
$vals[$index]['formatted'] = $this->format_addr($vals[$index]);
}
return $vals;
}

protected function format_addr($vals) {
$name = 'address';
if (array_key_exists('type', $vals)) {
$name = sprintf('%s_address', strtolower($vals['type']));
}
$vals = $vals['value'];
$street = $vals['street'];
if (!$street && $vals['po']) {
$steet = $vals['po'];
}
$value = sprintf('%s, %s, %s, %s, %s', $street, $vals['locality'], $vals['region'],
$vals['country'], $vals['postal_code']);
return array('name' => $name, 'value' => $value);
}
}

/**
Expand Down
3 changes: 1 addition & 2 deletions modules/carddav_contacts/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
## CardDav module set

Not functional yet, just a work in progress. Will eventually add support for
CardDav servers for contacts.
Initial support for contacts from a CardDav server. Servers must be defined in the carddav.ini file. As of right now support is read-only.
2 changes: 1 addition & 1 deletion modules/carddav_contacts/carddav.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

; Create one section for each CardDav backend you want to support. The section
; name will be used in the UI for the name of this addressbook
[CardDav]
[Personal]

; CardDav Server URL + port
server="http://localhost:5232"
36 changes: 34 additions & 2 deletions modules/carddav_contacts/hm-carddav.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,36 @@ private function convert_to_contact($data) {
$phone = '';
$dn = array_key_exists('n', $data) ? sprintf('%s %s', $data['n']['firstname'], $data['n']['lastname']) : '';
$phone = array_key_exists('tel', $data) && count($data['tel']) > 0 ? $data['tel'][0]['value']: '';
$all_flds = $this->parse_extr_flds($data);

foreach ($data['email'] as $email) {
$res[] = array(
'source' => $this->src,
'display_name' => $dn,
'phone_number' => $phone,
'email_address' => $email['value']
'email_address' => $email['value'],
'all_fields' => $all_flds
);
}
return $res;
}

private function parse_extr_flds($data) {
$all_flds = array();
foreach ($data as $name => $vals) {
if (in_array($name, array('n', 'tel', 'email'))) {
continue;
}
if (is_array($vals) && array_key_exists('formatted', $vals)) {
$all_flds[$vals['formatted']['name']] = $vals['formatted']['value'];
}
if (is_string($vals)) {
$all_flds[$name] = $vals;
}
}
return $all_flds;
}

private function discover() {
$path = $this->xml_find($this->principal_discover(), $this->principal_path);
if ($path === false) {
Expand All @@ -89,8 +107,22 @@ private function discover() {
return true;
}

private function parse_xml($xml) {
try {
$data = new SimpleXMLElement($xml);
return $data;
}
catch (Exception $oops) {
Hm_Msgs::add('ERRUnable to access CardDav server');
}
return false;
}

private function xml_find($xml, $path, $multi=false) {
$data = new SimpleXMLElement($xml);
$data = $this->parse_xml($xml);
if (!$data) {
return false;
}
foreach ($data->getDocNamespaces() as $pre => $ns) {
if (!$pre) {
$pre = 'a';
Expand Down
88 changes: 87 additions & 1 deletion modules/carddav_contacts/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,99 @@ public function process() {
$pass = 'testpass';

$contacts = $this->get('contact_store');
$auths = $this->user_config->get('carddav_contacts_auth_setting', array());
$details = get_ini($this->config, 'carddav.ini', true);

foreach ($details as $name => $vals) {
$carddav = new Hm_Carddav($name, $vals['server'], $user, $pass);
if (!array_key_exists($name, $auths)) {
continue;
}
$carddav = new Hm_Carddav($name, $vals['server'], $auths[$name]['user'], $auths[$name]['pass']);
$contacts->import($carddav->addresses);
$this->append('contact_sources', 'carddav');
}
$this->out('contact_store', $contacts, false);
}
}


/**
* @subpackage carddav_contacts/handler
*/
class Hm_Handler_load_carddav_settings extends Hm_Handler_Module {
public function process() {
$this->out('carddav_settings', get_ini($this->config, 'carddav.ini', true));
$this->out('carddav_auth', $this->user_config->get('carddav_contacts_auth_setting', array()));
}
}

/**
* @subpackage carddav_contacts/handler
*/
class Hm_Handler_process_carddav_auth_settings extends Hm_Handler_Module {
public function process() {
$settings = $this->get('carddav_settings', array());
$users = array();
$passwords = array();
$results = array();
if (array_key_exists('carddav_usernames', $this->request->post)) {
$users = $this->request->post['carddav_usernames'];
}
if (array_key_exists('carddav_passwords', $this->request->post)) {
$passwords = $this->request->post['carddav_passwords'];
}
foreach ($settings as $name => $vals) {
$creds = array();
if (array_key_exists($name, $users)) {
$results[$name]['user'] = $users[$name];
}
if (array_key_exists($name, $passwords)) {
$results[$name]['pass'] = $passwords[$name];
}
}
if (count($results) > 0) {
$new_settings = $this->get('new_user_settings');
$new_settings['carddav_contacts_auth_setting'] = $results;
$this->out('new_user_settings', $new_settings, false);
}
}
}

/**
* @subpackage carddav_contacts/output
*/
class Hm_Output_carddav_auth_settings extends Hm_Output_Module {
protected function output() {
$settings = $this->get('carddav_settings', array());
$auths = $this->get('carddav_auth', array());
if (count($settings) == 0) {
return;
}
$res = '<tr><td data-target=".carddav_settings" colspan="2" class="settings_subtitle">'.
'<img alt="" src="'.Hm_Image_Sources::$people.'" width="16" height="16" />'.
$this->trans('CardDav Addressbooks').'</td></tr>';
foreach ($settings as $name => $vals) {
$user = '';
$pass = false;
if (array_key_exists($name, $auths)) {
$user = $auths[$name]['user'];
if (array_key_exists('pass', $auths[$name]) && $auths[$name]['pass']) {
$pass = true;
}
}
$res .= '<tr class="carddav_settings"><td>'.$this->html_safe($name).'</td><td>';
$res .= '<input autocomplete="username" type="text" value="'.$user.'" name="carddav_usernames['.$this->html_safe($name).']" ';
$res .= 'placeholder="'.$this->trans('Username').'" /> <input type="password" ';
if ($pass) {
$res .= 'disabled="disabled" placeholder="'.$this->trans('Password saved').'" ';
$res .= 'name="carddav_passwords['.$this->html_safe($name).']" /> <input type="button" ';
$res .= 'value="'.$this->trans('Unlock').'" class="carddav_password_change" /></td></tr>';
}
else {
$res .= 'autocomplete="new-password" placeholder="'.$this->trans('Password').'" ';
$res .= 'name="carddav_passwords['.$this->html_safe($name).']" /></td></tr>';
}
}
return $res;
}
}
11 changes: 10 additions & 1 deletion modules/carddav_contacts/setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,13 @@
add_handler('ajax_delete_contact', 'load_carddav_contacts', true, 'carddav_contacts', 'load_contacts', 'after');
add_handler('ajax_add_contact', 'load_carddav_contacts', true, 'carddav_contacts', 'load_contacts', 'after');

return array();
add_handler('settings', 'load_carddav_settings', true, 'carddav_contacts', 'load_user_data', 'after');
add_handler('settings', 'process_carddav_auth_settings', true, 'carddav_contacts', 'save_user_settings', 'before');
add_output('settings', 'carddav_auth_settings', true, 'carddav_contacts', 'end_settings_form', 'before');

return array(
'allowed_post' => array(
'carddav_usernames' => array('filter' => FILTER_SANITIZE_STRING, 'flags' => FILTER_FORCE_ARRAY),
'carddav_passwords' => array('filter' => FILTER_UNSAFE_RAW, 'flags' => FILTER_FORCE_ARRAY)
)
);
1 change: 1 addition & 0 deletions modules/carddav_contacts/site.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.carddav_settings { display: none; }
8 changes: 8 additions & 0 deletions modules/carddav_contacts/site.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

$(function() {
$('.carddav_password_change').click(function() {
$(this).prev().prop('disabled', false);
$(this).prev().attr('placeholder', '');
});
});
12 changes: 10 additions & 2 deletions modules/contacts/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ protected function output() {
'<span class="contact_src">'.($contact->value('source') ? $this->html_safe($contact->value('source')) : $this->trans('local')).'</span>'.
'<td>'.$this->html_safe($contact->value('display_name')).'</td>'.
'<td><div class="contact_fld">'.$this->html_safe($contact->value('email_address')).'</div></td>'.
'<td class="contact_fld">'.$this->html_safe($contact->value('phone_number')).'</td>'.
'<td class="contact_fld"><a href="tel:'.$this->html_safe($contact->value('phone_number')).'">'.
$this->html_safe($contact->value('phone_number')).'</a></td>'.
'<td class="contact_controls">';
if (in_array($contact->value('source'), $editable, true)) {
$res .= '<a data-id="'.$this->html_safe($id).'" data-source="'.$this->html_safe($contact->value('source')).
Expand Down Expand Up @@ -293,7 +294,14 @@ function name_map($val) {
'employeenumber' => 'Employee Number',
'employeetype' => 'Employee Type',
'preferredlanguage' => 'Preferred Language',
'labeleduri' => 'Homepage URL'
'labeleduri' => 'Homepage URL',
'home_address' => 'Home Address',
'work_address' => 'Work Address',
'nickname' => 'Nickname',
'url' => 'Website',
'org' => 'Company',
'fn' => 'Full Name',
'uid' => 'Uid',
);
if (array_key_exists($val, $names)) {
return $names[$val];
Expand Down
2 changes: 1 addition & 1 deletion modules/ldap_contacts/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ protected function output() {
if (count($connections) > 0) {
$res = '<tr><td data-target=".ldap_settings" colspan="2" class="settings_subtitle">'.
'<img alt="" src="'.Hm_Image_Sources::$people.'" width="16" height="16" />'.
$this->trans('Addressbooks').'</td></tr>';
$this->trans('LDAP Addressbooks').'</td></tr>';
foreach ($connections as $name => $con) {
$user = '';
$pass = false;
Expand Down

0 comments on commit 66637a8

Please sign in to comment.