Add support for IMPP properties.

remotes/origin/stable45
Thomas Tanghus 13 years ago
parent 885b8c481b
commit 61c7700ce6
  1. 14
      apps/contacts/ajax/contact/addproperty.php
  2. 26
      apps/contacts/ajax/contact/saveproperty.php
  3. 16
      apps/contacts/css/contacts.css
  4. 8
      apps/contacts/index.php
  5. 73
      apps/contacts/js/contacts.js
  6. 78
      apps/contacts/lib/app.php
  7. 24
      apps/contacts/lib/vcard.php
  8. 26
      apps/contacts/templates/part.contact.php

@ -108,7 +108,17 @@ switch($name) {
$value = strtolower($value);
break;
case 'TEL':
case 'ADR': // should I delete the property if empty or throw an error?
case 'ADR':
break;
case 'IMPP':
if(is_null($parameters) || !isset($parameters['X-SERVICE-TYPE'])) {
bailOut(OC_Contacts_App::$l10n->t('Missing IM parameter.'));
}
$impp = OC_Contacts_App::getIMOptions($parameters['X-SERVICE-TYPE']);
if(is_null($impp)) {
bailOut(OC_Contacts_App::$l10n->t('Unknown IM: '.$parameters['X-SERVICE-TYPE']));
}
$value = $impp['protocol'] . ':' . $value;
break;
}
@ -126,7 +136,7 @@ $line = count($vcard->children) - 1;
// Apparently Sabre_VObject_Parameter doesn't do well with
// multiple values or I don't know how to do it. Tanghus.
foreach ($parameters as $key=>$element) {
if(is_array($element) && strtoupper($key) == 'TYPE') {
if(is_array($element) /*&& strtoupper($key) == 'TYPE'*/) {
// NOTE: Maybe this doesn't only apply for TYPE?
// And it probably shouldn't be done here anyways :-/
foreach($element as $e) {

@ -88,6 +88,16 @@ switch($element) {
case 'EMAIL':
$value = strtolower($value);
break;
case 'IMPP':
if(is_null($parameters) || !isset($parameters['X-SERVICE-TYPE'])) {
bailOut(OC_Contacts_App::$l10n->t('Missing IM parameter.'));
}
$impp = OC_Contacts_App::getIMOptions($parameters['X-SERVICE-TYPE']);
if(is_null($impp)) {
bailOut(OC_Contacts_App::$l10n->t('Unknown IM: '.$parameters['X-SERVICE-TYPE']));
}
$value = $impp['protocol'] . ':' . $value;
break;
}
if(!$value) {
@ -112,7 +122,8 @@ if(!$value) {
break;
case 'EMAIL':
case 'TEL':
case 'ADR': // should I delete the property if empty or throw an error?
case 'ADR':
case 'IMPP':
debug('Setting element: (EMAIL/TEL/ADR)'.$element);
$vcard->children[$line]->setValue($value);
$vcard->children[$line]->parameters = array();
@ -120,11 +131,18 @@ if(!$value) {
debug('Setting parameters: '.$parameters);
foreach($parameters as $key => $parameter) {
debug('Adding parameter: '.$key);
foreach($parameter as $val) {
debug('Adding parameter: '.$key.'=>'.$val);
if(is_array($parameter)) {
foreach($parameter as $val) {
debug('Adding parameter: '.$key.'=>'.$val);
$vcard->children[$line]->add(new Sabre_VObject_Parameter(
$key,
strtoupper(strip_tags($val)))
);
}
} else {
$vcard->children[$line]->add(new Sabre_VObject_Parameter(
$key,
strtoupper(strip_tags($val)))
strtoupper(strip_tags($parameter)))
);
}
}

@ -33,7 +33,7 @@
#card input[type="text"].contacts_property,input[type="email"].contacts_property,input[type="url"].contacts_property { width: 14em; float: left; font-weight: bold; }
.categories { float: left; width: 16em; }
#card input[type="checkbox"].contacts_property,input[type="text"],input[type="email"],input[type="url"],input[type="tel"],input[type="date"], select, textarea { background-color: #fefefe; border: 0 !important; -moz-appearance:none !important; -webkit-box-sizing:none !important; -moz-box-sizing:none !important; box-sizing:none !important; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; float: left; }
#card input[type="text"]:hover, input[type="text"]:focus, input[type="text"]:active,input[type="email"]:hover,input[type="url"]:hover,input[type="tel"]:hover,input[type="date"]:hover,input[type="date"],input[type="date"]:hover,input[type="date"]:active,input[type="date"]:active,input[type="date"]:active,input[type="email"]:active,input[type="url"]:active,input[type="tel"]:active, select:hover, select:focus, select:active, textarea:focus, textarea:hover { border: 0 !important; -webkit-appearance:textfield; -moz-appearance:textfield; -webkit-box-sizing:content-box; -moz-box-sizing:content-box; box-sizing:content-box; background:#fff; color:#333; border:1px solid #ddd; -moz-box-shadow:0 1px 1px #ddd, 0 2px 0 #bbb inset; -webkit-box-shadow:0 1px 1px #ddd, 0 1px 0 #bbb inset; box-shadow:0 1px 1px #ddd, 0 1px 0 #bbb inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em; outline:none; float: left; }
#card input[type="text"]:hover, input[type="text"]:focus, input[type="text"]:active,input[type="email"]:hover,input[type="url"]:hover,input[type="tel"]:hover,input[type="date"]:hover,input[type="date"],input[type="date"]:hover,input[type="date"]:active,input[type="date"]:active,input[type="date"]:active,input[type="email"]:active,input[type="url"]:active,input[type="tel"]:active, textarea:focus, textarea:hover { border: 0 !important; -webkit-appearance:textfield; -moz-appearance:textfield; -webkit-box-sizing:content-box; -moz-box-sizing:content-box; box-sizing:content-box; background:#fff; color:#333; border:1px solid #ddd; -moz-box-shadow:0 1px 1px #ddd, 0 2px 0 #bbb inset; -webkit-box-shadow:0 1px 1px #ddd, 0 1px 0 #bbb inset; box-shadow:0 1px 1px #ddd, 0 1px 0 #bbb inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em; outline:none; float: left; }
textarea { width: 80%; min-height: 5em; min-width: 30em; margin: 0 !important; padding: 0 !important; outline: 0 !important;}
dl.form { width: 100%; float: left; clear: right; margin: 0; padding: 0; cursor: normal; }
.form dt { display: table-cell; clear: left; float: left; width: 7em; margin: 0; padding: 0.8em 0.5em 0 0; text-align:right; text-overflow:ellipsis; o-text-overflow: ellipsis; vertical-align: text-bottom; color: #bbb;/* white-space: pre-wrap; white-space: -moz-pre-wrap !important; white-space: -pre-wrap; white-space: -o-pre-wrap;*/ }
@ -117,13 +117,21 @@ input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
.big { font-weight:bold; font-size:1.2em; }
.huge { font-weight:bold; font-size:1.5em; }
.propertycontainer dd { float: left; width: 25em; }
.propertylist { clear: none; max-width: 28em; }
.propertylist li.propertycontainer { white-space: nowrap; min-width: 35em; /*max-width: 30em;*/ display: block; clear: right; }
/*.propertylist { clear: none; max-width: 33em; }*/
.propertylist li.propertycontainer { white-space: nowrap; min-width: 35em; display: block; clear: both; }
.propertycontainer[data-element="EMAIL"] > input[type="email"],.propertycontainer[data-element="TEL"] > input[type="text"] { min-width: 12em !important; float: left; }
.propertylist li > input[type="checkbox"],input[type="radio"] { float: left; clear: left; width: 16px; height: 16px; vertical-align: middle; padding: 0; }
.propertylist li > select { float: left; max-width: 8em; }
.propertylist li > .select_wrapper { float: left; overflow: hidden; color: #bbb; font-size: 0.8em; }
.propertylist li > .select_wrapper select { float: left; overflow: hidden; color: #bbb; }
.propertylist li > .select_wrapper select option { color: #777; }
.propertylist li > .select_wrapper select:hover,.propertylist li > select:focus,.propertylist li > select:active { color: #777; }
.propertylist li > .select_wrapper select.impp { margin-left: -2.3em; direction: rtl; }
.propertylist li > .select_wrapper select.types { margin-right: -2em; }
.propertylist li > input[type="checkbox"].impp { clear: none; }
.propertylist li > label.xab { display: block; color: #bbb; float:left; clear: both; padding: 0.5em 0 0 2.5em; }
.typelist[type="button"] { float: left; max-width: 10em; border: 0; background-color: #fff; color: #bbb; box-shadow: none; } /* for multiselect */
.propertylist li > label.xab:hover { color: #777; }
.typelist[type="button"] { float: left; max-width: 8em; border: 0; background-color: #fff; color: #bbb; box-shadow: none; } /* for multiselect */
.typelist[type="button"]:hover { color: #777; } /* for multiselect */
.addresslist { clear: both; font-weight: bold; }
#ninjahelp { position: absolute; bottom: 0; left: 0; right: 0; padding: 1em; margin: 1em; opacity: 0.9; }

@ -28,8 +28,14 @@ OCP\App::setActiveNavigationEntry('contacts_index');
// Load a specific user?
$id = isset( $_GET['id'] ) ? $_GET['id'] : null;
$impp_types = OC_Contacts_App::getTypesOfProperty('IMPP');
$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
$email_types = OC_Contacts_App::getTypesOfProperty('EMAIL');
$ims = OC_Contacts_App::getIMOptions();
$im_protocols = array();
foreach($ims as $name => $values) {
$im_protocols[$name] = $values['displayname'];
}
$categories = OC_Contacts_App::getCategories();
$upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize'));
@ -60,7 +66,9 @@ $tmpl->assign('uploadMaxHumanFilesize',
OCP\Util::humanFileSize($maxUploadFilesize), false);
$tmpl->assign('phone_types', $phone_types, false);
$tmpl->assign('email_types', $email_types, false);
$tmpl->assign('impp_types', $impp_types, false);
$tmpl->assign('categories', $categories, false);
$tmpl->assign('im_protocols', $im_protocols, false);
$tmpl->assign('has_contacts', $has_contacts, false);
$tmpl->assign('id', $id, false);
$tmpl->printPage();

@ -533,6 +533,7 @@ OC.Contacts={
this.loadPhoto();
this.loadMails();
this.loadPhones();
this.loadIMs();
this.loadAddresses();
this.loadSingleProperties();
OC.Contacts.loadListHandlers();
@ -802,6 +803,12 @@ OC.Contacts={
}
OC.Contacts.Card.addPhone();
break;
case 'IMPP':
if($('#imlist>li').length == 1) {
$('#ims').show();
}
OC.Contacts.Card.addIM();
break;
case 'ADR':
if($('addresses>dl').length == 1) {
$('#addresses').show();
@ -1289,8 +1296,72 @@ OC.Contacts={
});
OC.Contacts.Contacts.refreshThumbnail(this.id);
},
addIM:function() {
//alert('addMail');
var imlist = $('#imlist');
imlist.find('li.template:first-child').clone(true).appendTo(imlist).show().find('a .tip').tipsy();
imlist.find('li.template:last-child').find('select').addClass('contacts_property');
imlist.find('li.template:last-child').removeClass('template').addClass('propertycontainer');
imlist.find('li:last-child').find('input[type="text"]').focus();
return false;
},
loadIMs:function() {
//console.log('loadIMs');
$('#ims').hide();
$('#imlist li.propertycontainer').remove();
var imlist = $('#imlist');
for(var im in this.data.IMPP) {
this.addIM();
var curim = imlist.find('li.propertycontainer:last-child');
if(typeof this.data.IMPP[im].label != 'undefined') {
curim.prepend('<label class="xab">'+this.data.IMPP[im].label+'</label>');
}
curim.data('checksum', this.data.IMPP[im]['checksum'])
curim.find('input[type="text"]').val(this.data.IMPP[im]['value'].split(':').pop());
for(var param in this.data.IMPP[im]['parameters']) {
if(param.toUpperCase() == 'PREF') {
curim.find('input[type="checkbox"]').attr('checked', 'checked')
}
else if(param.toUpperCase() == 'TYPE') {
if(typeof this.data.IMPP[im]['parameters'][param] == 'string') {
var found = false;
var imt = this.data.IMPP[im]['parameters'][param];
curim.find('select.types option').each(function(){
if($(this).val().toUpperCase() == imt.toUpperCase()) {
$(this).attr('selected', 'selected');
found = true;
}
});
if(!found) {
curim.find('select.type option:last-child').after('<option value="'+imt+'" selected="selected">'+imt+'</option>');
}
} else if(typeof this.data.IMPP[im]['parameters'][param] == 'object') {
for(imtype in this.data.IMPP[im]['parameters'][param]) {
var found = false;
var imt = this.data.IMPP[im]['parameters'][param][imtype];
curim.find('select.types option').each(function(){
if($(this).val().toUpperCase() == imt.toUpperCase().split(',')) {
$(this).attr('selected', 'selected');
found = true;
}
});
if(!found) {
curim.find('select.type option:last-child').after('<option value="'+imt+'" selected="selected">'+imt+'</option>');
}
}
}
}
else if(param.toUpperCase() == 'X-SERVICE-TYPE') {
curim.find('select.impp').val(this.data.IMPP[im]['parameters'][param].toLowerCase());
}
}
}
if($('#imlist li').length > 1) {
$('#ims').show();
}
return false;
},
addMail:function() {
console.log('addMail');
var emaillist = $('#emaillist');
emaillist.find('li.template:first-child').clone(true).appendTo(emaillist).show().find('a .tip').tipsy();
emaillist.find('li.template:last-child').find('select').addClass('contacts_property');

@ -109,14 +109,77 @@ class OC_Contacts_App {
/**
* @return array of vcard prop => label
*/
public static function getAddPropertyOptions() {
public static function getIMOptions($im = null) {
$l10n = self::$l10n;
return array(
'ADR' => $l10n->t('Address'),
'TEL' => $l10n->t('Telephone'),
'EMAIL' => $l10n->t('Email'),
'ORG' => $l10n->t('Organization'),
);
$ims = array(
'jabber' => array(
'displayname' => (string)$l10n->t('Jabber'),
'xname' => 'X-JABBER',
'protocol' => 'xmpp',
),
'aim' => array(
'displayname' => (string)$l10n->t('AIM'),
'xname' => 'X-AIM',
'protocol' => 'aim',
),
'msn' => array(
'displayname' => (string)$l10n->t('MSN'),
'xname' => 'X-MSN',
'protocol' => 'msn',
),
'twitter' => array(
'displayname' => (string)$l10n->t('Twitter'),
'xname' => 'X-TWITTER',
'protocol' => null,
),
'googletalk' => array(
'displayname' => (string)$l10n->t('GoogleTalk'),
'xname' => null,
'protocol' => 'xmpp',
),
'facebook' => array(
'displayname' => (string)$l10n->t('Facebook'),
'xname' => null,
'protocol' => 'xmpp',
),
'xmpp' => array(
'displayname' => (string)$l10n->t('XMPP'),
'xname' => null,
'protocol' => 'xmpp',
),
'icq' => array(
'displayname' => (string)$l10n->t('ICQ'),
'xname' => 'X-ICQ',
'protocol' => 'icq',
),
'yahoo' => array(
'displayname' => (string)$l10n->t('Yahoo'),
'xname' => 'X-YAHOO',
'protocol' => 'ymsgr',
),
'skype' => array(
'displayname' => (string)$l10n->t('Skype'),
'xname' => 'X-SKYPE',
'protocol' => 'skype',
),
'qq' => array(
'displayname' => (string)$l10n->t('QQ'),
'xname' => 'X-SKYPE',
'protocol' => 'x-apple',
),
'gadugadu' => array(
'displayname' => (string)$l10n->t('GaduGadu'),
'xname' => 'X-SKYPE',
'protocol' => 'x-apple',
),
);
if(is_null($im)) {
return $ims;
} else {
$ims['ymsgr'] = $ims['yahoo'];
$ims['gtalk'] = $ims['googletalk'];
return isset($ims[$im]) ? $ims[$im] : null;
}
}
/**
@ -126,6 +189,7 @@ class OC_Contacts_App {
$l = self::$l10n;
switch($prop) {
case 'ADR':
case 'IMPP':
return array(
'WORK' => $l->t('Work'),
'HOME' => $l->t('Home'),

@ -559,20 +559,36 @@ class OC_Contacts_VCard{
*/
public static function structureContact($object) {
$details = array();
foreach($object->children as $property){
$addIM = function($name, $temp, &$details) {
if(!array_key_exists('IMPP', $details)) {
$details['IMPP'] = array();
}
foreach($details['IMPP'] as $im) {
if(strtolower($im['value']) == strtolower($temp['value']) && $im['name'] == $name) {
return;
}
}
$details['IMPP'][] = $temp;
};
foreach($object->children as $property) {
$pname = $property->name;
$temp = self::structureProperty($property);
if(!is_null($temp)) {
// Get Apple X-ABLabels
if(isset($object->{$property->group . '.X-ABLABEL'})) {
$temp['label'] = $object->{$property->group . '.X-ABLABEL'}->value;
if($temp['label'] == '_$!<Other>!$_') {
$temp['label'] = OC_Contacts_App::$l10n->t('Other');
}
}
if(array_key_exists($property->name, $details)) {
$details[$property->name][] = $temp;
if(array_key_exists($pname, $details)) {
$details[$pname][] = $temp;
}
else{
$details[$property->name] = array($temp);
$details[$pname] = array($temp);
}
}
}

@ -71,7 +71,8 @@ $id = isset($_['id']) ? $_['id'] : '';
<ul id="phonelist" class="propertylist">
<li class="template hidden" data-element="TEL">
<input type="checkbox" class="contacts_property tip" name="parameters[TYPE][]" value="PREF" title="<?php echo $l->t('Preferred'); ?>" />
<input type="text" required="required" class="nonempty contacts_property" name="value" value="" placeholder="<?php echo $l->t('Enter phone number'); ?>" />
<input type="text" required="required" class="nonempty contacts_property" name="value" value=""
placeholder="<?php echo $l->t('Enter phone number'); ?>" />
<select multiple="multiple" name="parameters[TYPE][]">
<?php echo OCP\html_select_options($_['phone_types'], array()) ?>
</select>
@ -79,6 +80,28 @@ $id = isset($_['id']) ? $_['id'] : '';
</ul>
</div> <!-- Phone numbers -->
<!-- IMPP -->
<div id="ims" class="hidden contactsection">
<ul id="imlist" class="propertylist">
<li class="template hidden" data-element="IMPP">
<div class="select_wrapper">
<select class="impp" name="parameters[X-SERVICE-TYPE]">
<?php echo OCP\html_select_options($_['im_protocols'], array()) ?>
</select>
</div>
<div class="select_wrapper">
<select class="types" name="parameters[TYPE][]">
<option></option>
<?php echo OCP\html_select_options($_['impp_types'], array()) ?>
</select>
</div>
<input type="checkbox" class="contacts_property impp tip" name="parameters[TYPE][]" value="PREF" title="<?php echo $l->t('Preferred'); ?>" />
<input type="text" required="required" class="nonempty contacts_property" name="value" value=""
placeholder="<?php echo $l->t('Instant Messenger'); ?>" />
<a role="button" class="action delete" title="<?php echo $l->t('Delete IM'); ?>"></a></li>
</ul>
</div> <!-- IMPP -->
<!-- Addresses -->
<div id="addresses" class="hidden contactsection">
<dl class="addresscard template hidden" data-element="ADR"><dt>
@ -105,6 +128,7 @@ $id = isset($_['id']) ? $_['id'] : '';
<li><a role="menuitem" data-type="BDAY"><?php echo $l->t('Birthday'); ?></a></li>
<li><a role="menuitem" data-type="TEL"><?php echo $l->t('Phone'); ?></a></li>
<li><a role="menuitem" data-type="EMAIL"><?php echo $l->t('Email'); ?></a></li>
<li><a role="menuitem" data-type="IMPP"><?php echo $l->t('Instant Messaging'); ?></a></li>
<li><a role="menuitem" data-type="ADR"><?php echo $l->t('Address'); ?></a></li>
<li><a role="menuitem" data-type="NOTE"><?php echo $l->t('Note'); ?></a></li>
<li><a role="menuitem" data-type="URL"><?php echo $l->t('Web site'); ?></a></li>

Loading…
Cancel
Save