aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Zotlabs/Module/Connedit.php53
-rw-r--r--include/connections.php222
-rwxr-xr-xview/tpl/abook_edit.tpl279
3 files changed, 553 insertions, 1 deletions
diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php
index 5968ccde6..3aaa2a874 100644
--- a/Zotlabs/Module/Connedit.php
+++ b/Zotlabs/Module/Connedit.php
@@ -86,6 +86,12 @@ class Connedit extends \Zotlabs\Web\Controller {
call_hooks('contact_edit_post', $_POST);
+ $vc = get_abconfig(local_channel(),$orig_record['abook_xchan'],'system','vcard');
+ $vcard = (($vc) ? \Sabre\VObject\Reader::read($vc) : null);
+ $serialised_vcard = update_vcard($_REQUEST,$vcard);
+ if($serialised_vcard)
+ set_abconfig(local_channel(),$orig_record['abook_xchan'],'system','vcard',$serialised_vcard);
+
if(intval($orig_record[0]['abook_self'])) {
$autoperms = intval($_POST['autoperms']);
$is_self = true;
@@ -647,6 +653,14 @@ class Connedit extends \Zotlabs\Web\Controller {
$abook_prev = $abook_next = 0;
}
+ $vc = get_abconfig(local_channel(),$contact['abook_xchan'],'system','vcard');
+logger('vc: ' . $vc);
+
+ $vctmp = (($vc) ? \Sabre\VObject\Reader::read($vc) : null);
+ $vcard = (($vctmp) ? get_vcard_array($vctmp) : [] );
+
+logger('vcard: ' . print_r($vcard,true));
+
$tpl = get_markup_template("abook_edit.tpl");
if(feature_enabled(local_channel(),'affinity')) {
@@ -781,6 +795,7 @@ class Connedit extends \Zotlabs\Web\Controller {
'$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('Connection requests will be approved without your interaction'), $yes_no),
'$addr' => $contact['xchan_addr'],
'$section' => $section,
+ '$vcard' => $vcard,
'$addr_text' => t('This connection\'s primary address is'),
'$loc_text' => t('Available locations:'),
'$locstr' => $locstr,
@@ -823,7 +838,43 @@ class Connedit extends \Zotlabs\Web\Controller {
'$contact_id' => $contact['abook_id'],
'$name' => $contact['xchan_name'],
'$abook_prev' => $abook_prev,
- '$abook_next' => $abook_next
+ '$abook_next' => $abook_next,
+ '$vcard_label' => t('Details'),
+ '$displayname' => $displayname,
+ '$name_label' => t('Name'),
+ '$org_label' => t('Organisation'),
+ '$title_label' => t('Title'),
+ '$tel_label' => t('Phone'),
+ '$email_label' => t('Email'),
+ '$impp_label' => t('Instant messenger'),
+ '$url_label' => t('Website'),
+ '$adr_label' => t('Address'),
+ '$note_label' => t('Note'),
+ '$mobile' => t('Mobile'),
+ '$home' => t('Home'),
+ '$work' => t('Work'),
+ '$other' => t('Other'),
+ '$add_card' => t('Add Contact'),
+ '$add_field' => t('Add Field'),
+ '$create' => t('Create'),
+ '$update' => t('Update'),
+ '$delete' => t('Delete'),
+ '$cancel' => t('Cancel'),
+ '$po_box' => t('P.O. Box'),
+ '$extra' => t('Additional'),
+ '$street' => t('Street'),
+ '$locality' => t('Locality'),
+ '$region' => t('Region'),
+ '$zip_code' => t('ZIP Code'),
+ '$country' => t('Country')
+
+
+
+
+
+
+
+
));
$arr = array('contact' => $contact,'output' => $o);
diff --git a/include/connections.php b/include/connections.php
index b08d046b3..3d52d1a48 100644
--- a/include/connections.php
+++ b/include/connections.php
@@ -630,3 +630,225 @@ function random_profile() {
return '';
}
+function update_vcard($arr,$vcard = null) {
+
+ $fn = $arr['fn'];
+
+ if(! $vcard) {
+ $vcard = new \Sabre\VObject\Component\VCard([
+ 'FN' => $fn,
+ 'N' => array_reverse(explode(' ', $fn))
+ ]);
+ }
+ $org = $arr['org'];
+ if($org) {
+ $vcard->ORG = $org;
+ }
+
+ $title = $arr['title'];
+ if($title) {
+ $vcard->TITLE = $title;
+ }
+
+ $tel = $arr['tel'];
+ $tel_type = $arr['tel_type'];
+ if($tel) {
+ $i = 0;
+ foreach($tel as $item) {
+ if($item) {
+ $vcard->add('TEL', $item, ['type' => $tel_type[$i]]);
+ }
+ $i++;
+ }
+ }
+
+ $email = $arr['email'];
+ $email_type = $arr['email_type'];
+ if($email) {
+ $i = 0;
+ foreach($email as $item) {
+ if($item) {
+ $vcard->add('EMAIL', $item, ['type' => $email_type[$i]]);
+ }
+ $i++;
+ }
+ }
+
+ $impp = $arr['impp'];
+ $impp_type = $arr['impp_type'];
+ if($impp) {
+ $i = 0;
+ foreach($impp as $item) {
+ if($item) {
+ $vcard->add('IMPP', $item, ['type' => $impp_type[$i]]);
+ }
+ $i++;
+ }
+ }
+
+ $url = $arr['url'];
+ $url_type = $arr['url_type'];
+ if($url) {
+ $i = 0;
+ foreach($url as $item) {
+ if($item) {
+ $vcard->add('URL', $item, ['type' => $url_type[$i]]);
+ }
+ $i++;
+ }
+ }
+
+ $adr = $arr['adr'];
+ $adr_type = $arr['adr_type'];
+
+ if($adr) {
+ $i = 0;
+ foreach($adr as $item) {
+ if($item) {
+ $vcard->add('ADR', $item, ['type' => $adr_type[$i]]);
+ }
+ $i++;
+ }
+ }
+
+ $note = $arr['note'];
+ if($note) {
+ $vcard->NOTE = $note;
+ }
+
+ return $vcard->serialize();
+
+}
+
+function get_vcard_array($vc) {
+
+ $photo = '';
+ if($vc->PHOTO) {
+ $photo_value = strtolower($vc->PHOTO->getValueType()); // binary or uri
+ if($photo_value === 'binary') {
+ $photo_type = strtolower($vc->PHOTO['TYPE']); // mime jpeg, png or gif
+ $photo = 'data:image/' . $photo_type . ';base64,' . base64_encode((string)$vc->PHOTO);
+ }
+ else {
+ $url = parse_url((string)$vc->PHOTO);
+ $photo = 'data:' . $url['path'];
+ }
+ }
+
+ $fn = '';
+ if($vc->FN) {
+ $fn = (string) escape_tags($vc->FN);
+ }
+
+ $org = '';
+ if($vc->ORG) {
+ $org = (string) escape_tags($vc->ORG);
+ }
+
+ $title = '';
+ if($vc->TITLE) {
+ $title = (string) escape_tags($vc->TITLE);
+ }
+
+ $tels = [];
+ if($vc->TEL) {
+ foreach($vc->TEL as $tel) {
+ $type = (($tel['TYPE']) ? vcard_translate_type((string)$tel['TYPE']) : '');
+ $tels[] = [
+ 'type' => $type,
+ 'nr' => (string) escape_tags($tel)
+ ];
+ }
+ }
+ $emails = [];
+ if($vc->EMAIL) {
+ foreach($vc->EMAIL as $email) {
+ $type = (($email['TYPE']) ? vcard_translate_type((string)$email['TYPE']) : '');
+ $emails[] = [
+ 'type' => $type,
+ 'address' => (string) escape_tags($email)
+ ];
+ }
+ }
+
+ $impps = [];
+ if($vc->IMPP) {
+ foreach($vc->IMPP as $impp) {
+ $type = (($impp['TYPE']) ? vcard_translate_type((string)$impp['TYPE']) : '');
+ $impps[] = [
+ 'type' => $type,
+ 'address' => (string) escape_tags($impp)
+ ];
+ }
+ }
+
+ $urls = [];
+ if($vc->URL) {
+ foreach($vc->URL as $url) {
+ $type = (($url['TYPE']) ? vcard_translate_type((string)$url['TYPE']) : '');
+ $urls[] = [
+ 'type' => $type,
+ 'address' => (string) escape_tags($url)
+ ];
+ }
+ }
+
+ $adrs = [];
+ if($vc->ADR) {
+ foreach($vc->ADR as $adr) {
+ $type = (($adr['TYPE']) ? vcard_translate_type((string)$adr['TYPE']) : '');
+ $adrs[] = [
+ 'type' => $type,
+ 'address' => escape_tags($adr->getParts())
+ ];
+ }
+ }
+
+ $note = '';
+ if($vc->NOTE) {
+ $note = (string) escape_tags($vc->NOTE);
+ }
+
+ $card = [
+ 'photo' => $photo,
+ 'fn' => $fn,
+ 'org' => $org,
+ 'title' => $title,
+ 'tels' => $tels,
+ 'emails' => $emails,
+ 'impps' => $impps,
+ 'urls' => $urls,
+ 'adrs' => $adrs,
+ 'note' => $note
+ ];
+
+ return $card;
+
+}
+
+
+function vcard_translate_type($type) {
+
+ if(!$type)
+ return;
+
+ $type = strtoupper($type);
+
+ $map = [
+ 'CELL' => t('Mobile'),
+ 'HOME' => t('Home'),
+ 'HOME,VOICE' => t('Home, Voice'),
+ 'HOME,FAX' => t('Home, Fax'),
+ 'WORK' => t('Work'),
+ 'WORK,VOICE' => t('Work, Voice'),
+ 'WORK,FAX' => t('Work, Fax'),
+ 'OTHER' => t('Other')
+ ];
+
+ if (array_key_exists($type, $map)) {
+ return [$type, $map[$type]];
+ }
+ else {
+ return [$type, t('Other') . ' (' . $type . ')'];
+ }
+}
diff --git a/view/tpl/abook_edit.tpl b/view/tpl/abook_edit.tpl
index 2e02de33b..c36eca6ff 100755
--- a/view/tpl/abook_edit.tpl
+++ b/view/tpl/abook_edit.tpl
@@ -87,6 +87,285 @@
</div>
</div>
{{/if}}
+ <div class="panel">
+ <div class="section-subtitle-wrapper" role="tab" id="vcard-tool">
+ <h3>
+ <a data-toggle="collapse" data-parent="#contact-edit-tools" href="#vcard-tool-collapse" aria-expanded="true" aria-controls="vcard-tool-collapse">
+ {{$vcard_label}}
+ </a>
+ </h3>
+ </div>
+
+ <div id="vcard-tool-collapse" class="panel-collapse collapse{{if !$is_pending || $section == 'vcard'}} in{{/if}}" role="tabpanel" aria-labelledby="vcard-tool">
+
+<script>
+$(document).ready(function() {
+
+ $(document).on('click', '.vcard-header, .vcard-cancel-btn', updateView);
+ $(document).on('click', '.add-field', doAdd);
+ $(document).on('click', '.remove-field', doRemove);
+
+ function updateView() {
+ var id = $(this).data('id');
+ var action = $(this).data('action');
+ var header = $('#vcard-header-' + id);
+ var cancel = $('#vcard-cancel-' + id);
+ var addField = $('#vcard-add-field-' + id);
+ var info = $('#vcard-info-' + id);
+ var vcardPreview = $('#vcard-preview-' + id);
+ var fn = $('#vcard-fn-' + id);
+
+ if(action === 'open') {
+ $(header).addClass('active');
+ $(cancel).show();
+ $(addField).show();
+ $(info).show();
+ $(fn).show();
+ $(vcardPreview).hide();
+ }
+ else {
+ $(header).removeClass('active');
+ $(cancel).hide();
+ $(addField).hide();
+ $(info).hide();
+ $(fn).hide();
+ $(vcardPreview).show();
+ }
+ }
+
+ function doAdd() {
+ var what = $(this).data('add');
+ var id = $(this).data('id');
+ var element = '#template-form-' + what;
+ var where = '#card_form_' + id;
+
+ $(element + ' .remove-field').attr('data-id', id)
+
+ if(what === 'vcard-adr') {
+ var adrCount = $(where + ' .form-' + what).length;
+ var attrName = 'adr[' + adrCount + '][]';
+ $(element + ' input').attr('name', attrName);
+ }
+
+ if(what === 'vcard-org' || what === 'vcard-title' || what === 'vcard-note') {
+ $(where + ' .add-' + what).hide()
+ }
+
+ $(element).clone().removeAttr('id').appendTo(where + ' .form-' + what + '-wrapper');
+ }
+
+ function doRemove() {
+ var what = $(this).data('remove');
+ var element = $(this).parents('div.form-' + what);
+ var where = '#card_form_' + $(this).data('id');
+
+ if(what === 'vcard-org' || what === 'vcard-title' || what === 'vcard-note') {
+ $(where + ' .add-' + what).show()
+ }
+
+ $(element).remove();
+ }
+
+});
+</script>
+
+
+
+ <div class="dropdown pull-right">
+ <button data-toggle="dropdown" type="button" class="btn btn-default btn-sm dropdown-toggle"><i class="fa fa-plus"></i> {{$add_field}}</button>
+ <ul class="dropdown-menu">
+ <li class="add-vcard-org" style="display: none"><a href="#" data-add="vcard-org" data-id="new" class="add-field" onclick="return false;">{{$org_label}}</a></li>
+ <li class="add-vcard-title" style="display: none"><a href="#" data-add="vcard-title" data-id="new" class="add-field" onclick="return false;">{{$title_label}}</a></li>
+ <li class="add-vcard-tel"><a href="#" data-add="vcard-tel" data-id="new" class="add-field" onclick="return false;">{{$tel_label}}</a></li>
+ <li class="add-vcard-email"><a href="#" data-add="vcard-email" data-id="new" class="add-field" onclick="return false;">{{$email_label}}</a></li>
+ <li class="add-vcard-impp"><a href="#" data-add="vcard-impp" data-id="new" class="add-field" onclick="return false;">{{$impp_label}}</a></li>
+ <li class="add-vcard-url"><a href="#" data-add="vcard-url" data-id="new" class="add-field" onclick="return false;">{{$url_label}}</a></li>
+ <li class="add-vcard-adr"><a href="#" data-add="vcard-adr" data-id="new" class="add-field" onclick="return false;">{{$adr_label}}</a></li>
+ <li class="add-vcard-note"><a href="#" data-add="vcard-note" data-id="new" class="add-field" onclick="return false;">{{$note_label}}</a></li>
+ </ul>
+ </div>
+
+ <div class="vcard-fn-create form-group">
+ <div class="form-vcard-fn-wrapper">
+ <div class="form-group form-vcard-fn">
+ <div class="vcard-nophoto"><i class="fa fa-user"></i></div><input type="text" name="fn" value="" placeholder="{{$name_label}}">
+ </div>
+ </div>
+ </div>
+
+ <div class="vcard-org form-group">
+ <div class="form-vcard-org-wrapper">
+ <div class="form-group form-vcard-org">
+ <input type="text" name="org" value="" placeholder="{{$org_label}}">
+ <i data-remove="vcard-org" data-id="new" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+ </div>
+ </div>
+ </div>
+
+ <div class="vcard-title form-group">
+ <div class="form-vcard-title-wrapper">
+ <div class="form-group form-vcard-title">
+ <input type="text" name="title" value="" placeholder="{{$title_label}}">
+ <i data-remove="vcard-title" data-id="new" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+ </div>
+ </div>
+ </div>
+
+ <div class="vcard-tel form-group">
+ <div class="form-vcard-tel-wrapper">
+ <div class="form-group form-vcard-tel">
+ <select name="tel_type[]">
+ <option value="CELL">{{$mobile}}</option>
+ <option value="HOME">{{$home}}</option>
+ <option value="WORK">{{$work}}</option>
+ <option value="OTHER">{{$other}}</option>
+ </select>
+ <input type="text" name="tel[]" value="" placeholder="{{$tel_label}}">
+ <i data-remove="vcard-tel" data-id="new" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+ </div>
+ </div>
+ </div>
+
+
+ <div class="vcard-email form-group">
+ <div class="form-vcard-email-wrapper">
+ <div class="form-group form-vcard-email">
+ <select name="email_type[]">
+ <option value="HOME">{{$home}}</option>
+ <option value="WORK">{{$work}}</option>
+ <option value="OTHER">{{$other}}</option>
+ </select>
+ <input type="text" name="email[]" value="" placeholder="{{$email_label}}">
+ <i data-remove="vcard-email" data-id="new" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+ </div>
+ </div>
+ </div>
+
+ <div class="vcard-impp form-group">
+ <div class="form-vcard-impp-wrapper">
+ </div>
+ </div>
+
+ <div class="vcard-url form-group">
+ <div class="form-vcard-url-wrapper">
+ </div>
+ </div>
+
+ <div class="vcard-adr form-group">
+ <div class="form-vcard-adr-wrapper">
+ </div>
+ </div>
+
+ <div class="vcard-note form-group">
+ <div class="form-vcard-note-wrapper">
+ </div>
+ </div>
+
+ <div class="clear"></div>
+
+
+
+<div id="template-form-vcard-org" class="form-group form-vcard-org">
+ <div class="form-group form-vcard-org">
+ <input type="text" name="org" value="" placeholder="{{$org_label}}">
+ <i data-remove="vcard-org" data-id="" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+ </div>
+</div>
+
+<div id="template-form-vcard-title" class="form-group form-vcard-title">
+ <div class="form-group form-vcard-title">
+ <input type="text" name="title" value="" placeholder="{{$title_label}}">
+ <i data-remove="vcard-title" data-id="" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+ </div>
+</div>
+
+<div id="template-form-vcard-tel" class="form-group form-vcard-tel">
+ <select name="tel_type[]">
+ <option value="CELL">{{$mobile}}</option>
+ <option value="HOME">{{$home}}</option>
+ <option value="WORK">{{$work}}</option>
+ <option value="OTHER">{{$other}}</option>
+ </select>
+ <input type="text" name="tel[]" value="" placeholder="{{$tel_label}}">
+ <i data-remove="vcard-tel" data-id="" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+</div>
+
+<div id="template-form-vcard-email" class="form-group form-vcard-email">
+ <select name="email_type[]">
+ <option value="HOME">{{$home}}</option>
+ <option value="WORK">{{$work}}</option>
+ <option value="OTHER">{{$other}}</option>
+ </select>
+ <input type="text" name="email[]" value="" placeholder="{{$email_label}}">
+ <i data-remove="vcard-email" data-id="" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+</div>
+
+<div id="template-form-vcard-impp" class="form-group form-vcard-impp">
+ <select name="impp_type[]">
+ <option value="HOME">{{$home}}</option>
+ <option value="WORK">{{$work}}</option>
+ <option value="OTHER">{{$other}}</option>
+ </select>
+ <input type="text" name="impp[]" value="" placeholder="{{$impp_label}}">
+ <i data-remove="vcard-impp" data-id="" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+</div>
+
+<div id="template-form-vcard-url" class="form-group form-vcard-url">
+ <select name="url_type[]">
+ <option value="HOME">{{$home}}</option>
+ <option value="WORK">{{$work}}</option>
+ <option value="OTHER">{{$other}}</option>
+ </select>
+ <input type="text" name="url[]" value="" placeholder="{{$url_label}}">
+ <i data-remove="vcard-url" data-id="" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+</div>
+
+<div id="template-form-vcard-adr" class="form-group form-vcard-adr">
+ <div class="form-group">
+ <select name="adr_type[]">
+ <option value="HOME">{{$home}}</option>
+ <option value="WORK">{{$work}}</option>
+ <option value="OTHER">{{$other}}</option>
+ </select>
+ <label>{{$adr_label}}</label>
+ <i data-remove="vcard-adr" data-id="" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+ </div>
+ <div class="form-group">
+ <input type="text" name="" value="" placeholder="{{$po_box}}">
+ </div>
+ <div class="form-group">
+ <input type="text" name="" value="" placeholder="{{$extra}}">
+ </div>
+ <div class="form-group">
+ <input type="text" name="" value="" placeholder="{{$street}}">
+ </div>
+ <div class="form-group">
+ <input type="text" name="" value="" placeholder="{{$locality}}">
+ </div>
+ <div class="form-group">
+ <input type="text" name="" value="" placeholder="{{$region}}">
+ </div>
+ <div class="form-group">
+ <input type="text" name="" value="" placeholder="{{$zip_code}}">
+ </div>
+ <div class="form-group">
+ <input type="text" name="" value="" placeholder="{{$country}}">
+ </div>
+</div>
+
+<div id="template-form-vcard-note" class="form-group form-vcard-note">
+ <label>{{$note_label}}</label>
+ <i data-remove="vcard-note" data-id="" class="fa fa-trash-o remove-field drop-icons fakelink"></i>
+ <textarea name="note" class="form-control"></textarea>
+</div>
+
+
+ </div>
+ </div>
+
+
+
+
{{if $affinity }}
<div class="panel">