diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/ConversationObject.php | 20 | ||||
-rw-r--r-- | include/ItemObject.php | 12 | ||||
-rw-r--r-- | include/bb2diaspora.php | 6 | ||||
-rw-r--r-- | include/chat.php | 11 | ||||
-rw-r--r-- | include/conversation.php | 199 | ||||
-rwxr-xr-x | include/diaspora.php | 93 | ||||
-rw-r--r-- | include/follow.php | 5 | ||||
-rwxr-xr-x | include/items.php | 66 | ||||
-rw-r--r-- | include/js_strings.php | 1 | ||||
-rw-r--r-- | include/menu.php | 10 | ||||
-rw-r--r-- | include/message.php | 63 | ||||
-rw-r--r-- | include/nav.php | 15 | ||||
-rw-r--r-- | include/notifier.php | 9 | ||||
-rw-r--r-- | include/onepoll.php | 2 | ||||
-rw-r--r-- | include/permissions.php | 2 | ||||
-rw-r--r-- | include/security.php | 13 | ||||
-rw-r--r-- | include/text.php | 16 | ||||
-rw-r--r-- | include/zot.php | 4 |
18 files changed, 354 insertions, 193 deletions
diff --git a/include/ConversationObject.php b/include/ConversationObject.php index 767ef7360..a02ba102f 100644 --- a/include/ConversationObject.php +++ b/include/ConversationObject.php @@ -52,14 +52,14 @@ class Conversation extends BaseObject { switch($mode) { case 'network': - if(array_key_exists('firehose',$a->data) && intval($a->data['firehose'])) { - $this->profile_owner = intval($a->data['firehose']); - $this->writable = false; - } - else { +// if(array_key_exists('firehose',$a->data) && intval($a->data['firehose'])) { +// $this->profile_owner = intval($a->data['firehose']); +// $this->writable = false; +// } +// else { $this->profile_owner = local_user(); $this->writable = true; - } +// } break; case 'channel': $this->profile_owner = $a->profile['profile_uid']; @@ -177,11 +177,11 @@ class Conversation extends BaseObject { } } require_once('include/identity.php'); - $sys = get_sys_channel(); +// $sys = get_sys_channel(); - if($sys && $item->get_data_value('uid') == $sys['channel_id']) { - $item->set_commentable(false); - } +// if($sys && $item->get_data_value('uid') == $sys['channel_id']) { +// $item->set_commentable(false); +// } $item->set_conversation($this); $this->threads[] = $item; diff --git a/include/ItemObject.php b/include/ItemObject.php index 96abe4df6..7c75e35bd 100644 --- a/include/ItemObject.php +++ b/include/ItemObject.php @@ -101,11 +101,19 @@ class Item extends BaseObject { else $edpost = false; + if($observer['xchan_hash'] == $this->get_data_value('author_xchan') || $observer['xchan_hash'] == $this->get_data_value('owner_xchan') || $this->get_data_value('uid') == local_user()) $dropping = true; + + if(array_key_exists('real_uid',$item)) { + $edpost = false; + $dropping = false; + } + + if($dropping) { $drop = array( 'dropping' => $dropping, @@ -119,7 +127,7 @@ class Item extends BaseObject { ); } - $filer = (($conv->get_profile_owner() == local_user()) ? t("Save to Folder") : false); + $filer = ((($conv->get_profile_owner() == local_user()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false); $profile_avatar = $item['author']['xchan_photo_m']; $profile_link = chanlink_url($item['author']['xchan_url']); @@ -163,7 +171,7 @@ class Item extends BaseObject { if($this->is_toplevel()) { // FIXME check this permission - if($conv->get_profile_owner() == local_user()) { + if(($conv->get_profile_owner() == local_user()) && (! array_key_exists('real_uid',$item))) { // FIXME we don't need all this stuff, some can be done in the template diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index e60f72add..089838e97 100644 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -131,10 +131,8 @@ function diaspora2bb($s,$use_zrl = false) { // $s = preg_replace('/\@\{(.+?)\; (.+?)\@(.+?)\}/','@[url=https://$3/u/$2]$1[/url]',$s); // first try plustags - // nope don't do it. This will cause mis-attributed messages and runaway delivery chains - - // Diaspora doesn't have sufficient delivery loop detection. - // Leave the next line commented and leave this description here so future readers will know why. - // $s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}\+/','diaspora_mention_callback',$s); + + $s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}\+/','diaspora_mention_callback',$s); $s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}/','diaspora_mention_callback',$s); diff --git a/include/chat.php b/include/chat.php index b8fb185df..5c3d0c9d9 100644 --- a/include/chat.php +++ b/include/chat.php @@ -189,6 +189,17 @@ function chatroom_list($uid) { return $r; } +function chatroom_list_count($uid) { + require_once('include/security.php'); + $sql_extra = permissions_sql($uid); + + $r = q("select count(*) as total from chatroom where cr_uid = %d $sql_extra", + intval($uid) + ); + + return $r[0]['total']; +} + /** * create a chat message via API. * It is the caller's responsibility to enter the room. diff --git a/include/conversation.php b/include/conversation.php index 05ae72d61..b0a388a68 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -440,7 +440,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ for($x = 0; $x < count($arr_blocked); $x ++) $arr_blocked[$x] = trim($arr_blocked[$x]); } - } @@ -458,59 +457,53 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ $profile_owner = local_user(); $page_writeable = true; - if(!$update) { - // The special div is needed for liveUpdate to kick in for this page. - // We only launch liveUpdate if you aren't filtering in some incompatible - // way and also you aren't writing a comment (discovered in javascript). - - $live_update_div = '<div id="live-network"></div>' . "\r\n" - . "<script> var profile_uid = " . $_SESSION['uid'] - . "; var netargs = '" . substr($a->cmd,8) - . '?f=' - . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : '') - . ((x($_GET,'search')) ? '&search=' . $_GET['search'] : '') - . ((x($_GET,'star')) ? '&star=' . $_GET['star'] : '') - . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : '') - . ((x($_GET,'bmark')) ? '&bmark=' . $_GET['bmark'] : '') - . ((x($_GET,'liked')) ? '&liked=' . $_GET['liked'] : '') - . ((x($_GET,'conv')) ? '&conv=' . $_GET['conv'] : '') - . ((x($_GET,'spam')) ? '&spam=' . $_GET['spam'] : '') - . ((x($_GET,'nets')) ? '&nets=' . $_GET['nets'] : '') - . ((x($_GET,'cmin')) ? '&cmin=' . $_GET['cmin'] : '') - . ((x($_GET,'cmax')) ? '&cmax=' . $_GET['cmax'] : '') - . ((x($_GET,'file')) ? '&file=' . $_GET['file'] : '') - . ((x($_GET,'uri')) ? '&uri=' . $_GET['uri'] : '') - - . "'; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; - } - - + if(!$update) { + // The special div is needed for liveUpdate to kick in for this page. + // We only launch liveUpdate if you aren't filtering in some incompatible + // way and also you aren't writing a comment (discovered in javascript). + + $live_update_div = '<div id="live-network"></div>' . "\r\n" + . "<script> var profile_uid = " . $_SESSION['uid'] + . "; var netargs = '" . substr($a->cmd,8) + . '?f=' + . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : '') + . ((x($_GET,'search')) ? '&search=' . $_GET['search'] : '') + . ((x($_GET,'star')) ? '&star=' . $_GET['star'] : '') + . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : '') + . ((x($_GET,'bmark')) ? '&bmark=' . $_GET['bmark'] : '') + . ((x($_GET,'liked')) ? '&liked=' . $_GET['liked'] : '') + . ((x($_GET,'conv')) ? '&conv=' . $_GET['conv'] : '') + . ((x($_GET,'spam')) ? '&spam=' . $_GET['spam'] : '') + . ((x($_GET,'nets')) ? '&nets=' . $_GET['nets'] : '') + . ((x($_GET,'cmin')) ? '&cmin=' . $_GET['cmin'] : '') + . ((x($_GET,'cmax')) ? '&cmax=' . $_GET['cmax'] : '') + . ((x($_GET,'file')) ? '&file=' . $_GET['file'] : '') + . ((x($_GET,'uri')) ? '&uri=' . $_GET['uri'] : '') + . "'; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; + } } elseif($mode === 'channel') { $profile_owner = $a->profile['profile_uid']; $page_writeable = ($profile_owner == local_user()); - if(!$update) { - $tab = notags(trim($_GET['tab'])); - if($tab === 'posts') { - // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, - // because browser prefetching might change it on us. We have to deliver it with the page. - - $live_update_div = '<div id="live-channel"></div>' . "\r\n" - . "<script> var profile_uid = " . $a->profile['profile_uid'] - . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; - } - } + if(!$update) { + $tab = notags(trim($_GET['tab'])); + if($tab === 'posts') { + // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, + // because browser prefetching might change it on us. We have to deliver it with the page. + $live_update_div = '<div id="live-channel"></div>' . "\r\n" + . "<script> var profile_uid = " . $a->profile['profile_uid'] + . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; + } + } } elseif($mode === 'display') { $profile_owner = local_user(); $page_writeable = false; - - $live_update_div = '<div id="live-display"></div>' . "\r\n"; - + $live_update_div = '<div id="live-display"></div>' . "\r\n"; } elseif($mode === 'page') { @@ -519,10 +512,10 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ $live_update_div = '<div id="live-page"></div>' . "\r\n"; } + elseif($mode === 'search') { + $live_update_div = '<div id="live-search"></div>' . "\r\n"; + } - elseif($mode === 'search') { - $live_update_div = '<div id="live-search"></div>' . "\r\n"; - } elseif($mode === 'photos') { $profile_onwer = $a->profile['profile_uid']; $page_writeable = ($profile_owner == local_user()); @@ -555,7 +548,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ $alike = array(); $dlike = array(); - // array with html for each thread (parent+comments) $threads = array(); $threadsid = -1; @@ -603,12 +595,11 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ } else $nickname = $a->user['nickname']; - + $profile_name = ((strlen($item['author-name'])) ? $item['author-name'] : $item['name']); if($item['author-link'] && (! $item['author-name'])) $profile_name = $item['author-link']; - $tags=array(); $hashtags = array(); @@ -631,7 +622,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ $profile_link = $item['author']['xchan_url']; $profile_avatar = $item['author']['xchan_photo_m']; - $location = format_location($item); localize_item($item); @@ -663,7 +653,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ $unverified = ''; - $tags=array(); $terms = get_terms_oftype($item['term'],array(TERM_HASHTAG,TERM_MENTION,TERM_UNKNOWN)); if(count($terms)) @@ -694,12 +683,11 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ 'verified' => $verified, 'unverified' => $unverified, 'txt_cats' => t('Categories:'), - 'txt_folders' => t('Filed under:'), - 'has_cats' => ((count($categories)) ? 'true' : ''), - 'has_folders' => ((count($folders)) ? 'true' : ''), - 'categories' => $categories, - 'folders' => $folders, - + 'txt_folders' => t('Filed under:'), + 'has_cats' => ((count($categories)) ? 'true' : ''), + 'has_folders' => ((count($folders)) ? 'true' : ''), + 'categories' => $categories, + 'folders' => $folders, 'text' => strip_tags($body), 'ago' => relative_date($item['created']), 'app' => $item['app'], @@ -743,10 +731,10 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ // Normal View // logger('conv: items: ' . print_r($items,true)); - require_once('include/ConversationObject.php'); - require_once('include/ItemObject.php'); + require_once('include/ConversationObject.php'); + require_once('include/ItemObject.php'); - $conv = new Conversation($mode, $preview, $prepared_item); + $conv = new Conversation($mode, $preview, $prepared_item); // In the display mode we don't have a profile owner. @@ -754,12 +742,12 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ $conv->set_profile_owner($items[0]['uid']); - // get all the topmost parents - // this shouldn't be needed, as we should have only them in our array - // But for now, this array respects the old style, just in case + // get all the topmost parents + // this shouldn't be needed, as we should have only them in our array + // But for now, this array respects the old style, just in case - $threads = array(); - foreach($items as $item) { + $threads = array(); + foreach($items as $item) { // Check for any blocked authors @@ -774,7 +762,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ if($blocked) continue; } - + // Check all the kids too if($arr_blocked && $item['children']) { @@ -786,46 +774,43 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ } } + like_puller($a, $item, $alike, 'like'); + if(feature_enabled($profile_owner, 'dislike')) + like_puller($a, $item, $dlike, 'dislike'); - like_puller($a,$item,$alike,'like'); - - if(feature_enabled($profile_owner,'dislike')) - like_puller($a,$item,$dlike,'dislike'); - - if(! visible_activity($item)) { - continue; - } + if(! visible_activity($item)) { + continue; + } - $item['pagedrop'] = $page_dropping; + $item['pagedrop'] = $page_dropping; - if($item['id'] == $item['parent']) { + if($item['id'] == $item['parent']) { // $tx1 = dba_timer(); - $item_object = new Item($item); - $conv->add_thread($item_object); + $item_object = new Item($item); + $conv->add_thread($item_object); if($page_mode === 'list') $item_object->set_template('conv_list.tpl'); // $tx2 = dba_timer(); // if($mode === 'network') // profiler($tx1,$tx2,'add thread ' . $item['id']); - } - } + } + } $t2 = dba_timer(); - $threads = $conv->get_template_data($alike, $dlike); - if(!$threads) { - logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG); - $threads = array(); - } + $threads = $conv->get_template_data($alike, $dlike); + if(!$threads) { + logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG); + $threads = array(); + } $t3 = dba_timer(); if($mode === 'network') { profiler($t1,$t2,'Conversation prepare'); profiler($t2,$t3,'Conversation get_template'); } - - } - } + } + } if($page_mode === 'traditional' || $page_mode === 'preview') { $page_template = get_markup_template("threaded_conversation.tpl"); @@ -867,8 +852,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ if($page_mode === 'preview') logger('preview: ' . $o); - return $o; - + return $o; } @@ -981,26 +965,43 @@ function item_photo_menu($item){ return $o; } - -function like_puller($a,$item,&$arr,$mode) { +/** + * @brief Returns a like/dislike entry. + * It gives back a HTML link to the channel that liked/disliked. + * + * @param array $a (not used) + * @param array $item + * @param array &$arr + * @param string $mode like/dislike + * @return void + */ +function like_puller($a, $item, &$arr, $mode) { $url = ''; - $sparkle = ''; $verb = (($mode === 'like') ? ACTIVITY_LIKE : ACTIVITY_DISLIKE); - if((activity_match($item['verb'],$verb)) && ($item['id'] != $item['parent'])) { - $url = chanlink_url($item['author']['xchan_url']); + if((activity_match($item['verb'], $verb)) && ($item['id'] != $item['parent'])) { + + if($item['author']['xchan_url']) + $url = chanlink_url($item['author']['xchan_url']); if(! $item['thr_parent']) $item['thr_parent'] = $item['parent_mid']; if(! ((isset($arr[$item['thr_parent'] . '-l'])) && (is_array($arr[$item['thr_parent'] . '-l'])))) $arr[$item['thr_parent'] . '-l'] = array(); + if(! isset($arr[$item['thr_parent']])) $arr[$item['thr_parent']] = 1; else $arr[$item['thr_parent']] ++; - $arr[$item['thr_parent'] . '-l'][] = '<a href="'. $url . '">' . $item['author']['xchan_name'] . '</a>'; + + $name = (($item['author']['xchan_name']) ? $item['author']['xchan_name'] : t('Unknown')); + + if($url) + $arr[$item['thr_parent'] . '-l'][] = '<a href="'. $url . '">' . $name . '</a>'; + else + $arr[$item['thr_parent'] . '-l'][] = '<a href="#" class="disabled">' . $name . '</a>'; } return; } @@ -1545,8 +1546,8 @@ function profile_tabs($a, $is_owner=False, $nickname=Null){ } require_once('include/chat.php'); - $chats = chatroom_list($uid); - if (count($chats)) { + $has_chats = chatroom_list_count($uid); + if ($has_chats) { $tabs[] = array( 'label' => t('Chatrooms'), 'url' => $a->get_baseurl() . '/chat/' . $nickname, @@ -1556,7 +1557,9 @@ function profile_tabs($a, $is_owner=False, $nickname=Null){ ); } - if($is_owner) { + require_once('include/menu.php'); + $has_bookmarks = menu_list_count(local_user(),'',MENU_BOOKMARK) + menu_list_count(local_user(),'',MENU_SYSTEM|MENU_BOOKMARK); + if($is_owner && $has_bookmarks) { $tabs[] = array( 'label' => t('Bookmarks'), 'url' => $a->get_baseurl() . '/bookmarks', diff --git a/include/diaspora.php b/include/diaspora.php index 3b6321643..f9fd3b4ee 100755 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -58,7 +58,7 @@ function diaspora_dispatch($importer,$msg,$attempt=1) { $xmlbase = $parsed_xml->post; - logger('diaspora_dispatch: ' . print_r($xmlbase,true), LOGGER_DEBUG); + logger('diaspora_dispatch: ' . print_r($xmlbase,true), LOGGER_DATA); if($xmlbase->request) { @@ -545,7 +545,7 @@ function diaspora_decode($importer,$xml) { * </decrypted_header> */ - logger('decrypted: ' . $decrypted, LOGGER_DEBUG); + logger('decrypted: ' . $decrypted, LOGGER_DATA); $idom = parse_xml_string($decrypted,false); $inner_iv = base64_decode($idom->iv); @@ -912,7 +912,7 @@ function diaspora_post($importer,$xml,$msg) { function diaspora_reshare($importer,$xml,$msg) { - logger('diaspora_reshare: init: ' . print_r($xml,true)); + logger('diaspora_reshare: init: ' . print_r($xml,true), LOGGER_DATA); $a = get_app(); $guid = notags(unxmlify($xml->guid)); @@ -955,7 +955,7 @@ function diaspora_reshare($importer,$xml,$msg) { logger('diaspora_reshare: unable to fetch source url ' . $source_url); return; } - logger('diaspora_reshare: source: ' . $x['body']); + logger('diaspora_reshare: source: ' . $x['body'], LOGGER_DATA); $source_xml = parse_xml_string($x['body'],false); @@ -1431,7 +1431,8 @@ function diaspora_conversation($importer,$xml,$msg) { return; } - if(($contact['rel'] == CONTACT_IS_FOLLOWER) || ($contact['blocked']) || ($contact['readonly'])) { + + if(! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'post_mail')) { logger('diaspora_conversation: Ignoring this author.'); return 202; } @@ -1531,14 +1532,20 @@ function diaspora_conversation($importer,$xml,$msg) { continue; } - q("insert into mail ( `uid`, `convid`, `from_xchan`,`to_xchan`,`title`,`body`,`mail_flags`,`mid`,`parent_mid`,`created`) values ( %d, %d, '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s')", + $key = get_config('system','pubkey'); + if($subject) + $subject = json_encode(crypto_encapsulate($subject,$key)); + if($body) + $body = json_encode(crypto_encapsulate($body,$key)); + + q("insert into mail ( `channel_id`, `convid`, `from_xchan`,`to_xchan`,`title`,`body`,`mail_flags`,`mid`,`parent_mid`,`created`) values ( %d, %d, '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s')", intval($importer['channel_id']), intval($conversation['id']), dbesc($person['xchan_hash']), dbesc($importer['channel_hash']), dbesc($subject), dbesc($body), - 0, + intval(MAIL_OBSCURED), dbesc($msg_guid), dbesc($parent_uri), dbesc($msg_created_at) @@ -1587,7 +1594,7 @@ function diaspora_message($importer,$xml,$msg) { $msg_diaspora_handle = notags(unxmlify($xml->diaspora_handle)); $msg_conversation_guid = notags(unxmlify($xml->conversation_guid)); - $parent_uri = $diaspora_handle . ':' . $msg_parent_guid; + $parent_uri = $msg_parent_guid; $contact = diaspora_get_contact_by_handle($importer['channel_id'],$msg_diaspora_handle); if(! $contact) { @@ -1606,7 +1613,7 @@ function diaspora_message($importer,$xml,$msg) { intval($importer['channel_id']), dbesc($msg_conversation_guid) ); - if(count($c)) + if($c) $conversation = $c[0]; else { logger('diaspora_message: conversation not available.'); @@ -1615,6 +1622,7 @@ function diaspora_message($importer,$xml,$msg) { $reply = 0; + $subject = $conversation['subject']; $body = diaspora2bb($msg_text); $message_id = $msg_diaspora_handle . ':' . $msg_guid; @@ -1624,8 +1632,8 @@ function diaspora_message($importer,$xml,$msg) { $author_signature = base64_decode($msg_author_signature); $person = find_diaspora_person_by_handle($msg_diaspora_handle); - if(is_array($person) && x($person,'pubkey')) - $key = $person['pubkey']; + if(is_array($person) && x($person,'xchan_pubkey')) + $key = $person['xchan_pubkey']; else { logger('diaspora_message: unable to find author details'); return; @@ -1636,28 +1644,30 @@ function diaspora_message($importer,$xml,$msg) { return; } - $r = q("select id from mail where `uri` = '%s' and uid = %d limit 1", + $r = q("select id from mail where mid = '%s' and channel_id = %d limit 1", dbesc($message_id), intval($importer['channel_id']) ); - if(count($r)) { + if($r) { logger('diaspora_message: duplicate message already delivered.', LOGGER_DEBUG); return; } - q("insert into mail ( `uid`, `guid`, `convid`, `from-name`,`from-photo`,`from-url`,`contact-id`,`title`,`body`,`seen`,`reply`,`uri`,`parent-uri`,`created`) values ( %d, '%s', %d, '%s', '%s', '%s', %d, '%s', '%s', %d, %d, '%s','%s','%s')", + $key = get_config('system','pubkey'); + if($subject) + $subject = json_encode(crypto_encapsulate($subject,$key)); + if($body) + $body = json_encode(crypto_encapsulate($body,$key)); + + q("insert into mail ( `channel_id`, `convid`, `from_xchan`,`to_xchan`,`title`,`body`,`mail_flags`,`mid`,`parent_mid`,`created`) values ( %d, %d, '%s', '%s', '%s', '%s', '%d','%s','%s','%s')", intval($importer['channel_id']), - dbesc($msg_guid), intval($conversation['id']), - dbesc($person['name']), - dbesc($person['photo']), - dbesc($person['url']), - intval($contact['id']), - dbesc($conversation['subject']), + dbesc($person['xchan_hash']), + dbesc($importer['xchan_hash']), + dbesc($subject), dbesc($body), - 0, - 1, - dbesc($message_id), + intval(MAIL_OBSCURED), + dbesc($msg_guid), dbesc($parent_uri), dbesc($msg_created_at) ); @@ -2123,15 +2133,9 @@ function diaspora_profile($importer,$xml,$msg) { $image_url = "http://" . $handle_parts[1] . $image_url; } -/* $r = q("SELECT DISTINCT ( `resource-id` ) FROM `photo` WHERE `uid` = %d AND `contact-id` = %d AND `album` = 'Contact Photos' ", - intval($importer['channel_id']), - intval($contact['id']) - ); - $oldphotos = ((count($r)) ? $r : null);*/ - - require_once('include/Photo.php'); + require_once('include/photo/photo_driver.php'); - $images = import_profile_photo($image_url,$importer['channel_id'],$contact['id']); + $images = import_profile_photo($image_url,$contact['xchan_hash']); // Generic birthday. We don't know the timezone. The year is irrelevant. @@ -2148,7 +2152,7 @@ function diaspora_profile($importer,$xml,$msg) { // TODO: update name on item['author-name'] if the name changed. See consume_feed() // Not doing this currently because D* protocol is scheduled for revision soon. - $r = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s', `avatar-date` = '%s' , `bd` = '%s' WHERE `id` = %d AND `uid` = %d", +/* $r = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s', `avatar-date` = '%s' , `bd` = '%s' WHERE `id` = %d AND `uid` = %d", dbesc($name), dbesc(datetime_convert()), dbesc($images[0]), @@ -2159,7 +2163,7 @@ function diaspora_profile($importer,$xml,$msg) { intval($contact['id']), intval($importer['channel_id']) ); - +*/ /* if($r) { if($oldphotos) { foreach($oldphotos as $ph) { @@ -2391,7 +2395,7 @@ function diaspora_send_images($item,$owner,$contact,$images,$public_batch = fals function diaspora_send_followup($item,$owner,$contact,$public_batch = false) { $a = get_app(); - $myaddr = $owner['channel_address'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + $myaddr = $owner['channel_address'] . '@' . get_app()->get_hostname(); $theiraddr = $contact['xchan_addr']; // Diaspora doesn't support threaded comments, but some @@ -2482,7 +2486,7 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { $a = get_app(); - $myaddr = $owner['channel_address'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + $myaddr = $owner['channel_address'] . '@' . get_app()->get_hostname(); $text = bb2diaspora_itembody($item); @@ -2624,7 +2628,7 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { function diaspora_send_retraction($item,$owner,$contact,$public_batch = false) { $a = get_app(); - $myaddr = $owner['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + $myaddr = $owner['channel_address'] . '@' . get_app()->get_hostname(); // Check whether the retraction is for a top-level post or whether it's a relayable if( $item['mid'] !== $item['parent_mid'] ) { @@ -2655,11 +2659,11 @@ function diaspora_send_retraction($item,$owner,$contact,$public_batch = false) { function diaspora_send_mail($item,$owner,$contact) { $a = get_app(); - $myaddr = $owner['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + $myaddr = $owner['channel_address'] . '@' . get_app()->get_hostname(); $r = q("select * from conv where id = %d and uid = %d limit 1", intval($item['convid']), - intval($item['uid']) + intval($item['channel_id']) ); if(! count($r)) { @@ -2676,16 +2680,25 @@ function diaspora_send_mail($item,$owner,$contact) { 'participant_handles' => xmlify($cnv['recips']) ); + if(array_key_exists('mail_flags',$item) && ($item['mail_flags'] & MAIL_OBSCURED)) { + $key = get_config('system','prvkey'); +// if($item['title']) +// $item['title'] = crypto_unencapsulate(json_decode_plus($item['title']),$key); + if($item['body']) + $item['body'] = crypto_unencapsulate(json_decode_plus($item['body']),$key); + } + + $body = bb2diaspora($item['body']); $created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d H:i:s \U\T\C'); - $signed_text = $item['guid'] . ';' . $cnv['guid'] . ';' . $body . ';' + $signed_text = $item['mid'] . ';' . $cnv['guid'] . ';' . $body . ';' . $created . ';' . $myaddr . ';' . $cnv['guid']; $sig = base64_encode(rsa_sign($signed_text,$owner['channel_prvkey'],'sha256')); $msg = array( - 'guid' => xmlify($item['guid']), + 'guid' => xmlify($item['mid']), 'parent_guid' => xmlify($cnv['guid']), 'parent_author_signature' => (($item['reply']) ? null : xmlify($sig)), 'author_signature' => xmlify($sig), diff --git a/include/follow.php b/include/follow.php index 3c1fcd890..a967386e9 100644 --- a/include/follow.php +++ b/include/follow.php @@ -19,6 +19,9 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) $is_red = false; $is_http = ((strpos($url,'://') !== false) ? true : false); + if($is_http && substr($url,-1,1) === '/') + $url = substr($url,0,-1); + if(! allowed_url($url)) { $result['message'] = t('Channel is blocked on this site.'); return $result; @@ -143,7 +146,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) if(! $r) { // attempt network auto-discovery - if(strpos($url,'@')) { + if(strpos($url,'@') && (! $is_http)) { $r = discover_by_webbie($url); } elseif($is_http) { diff --git a/include/items.php b/include/items.php index 1fa833eb2..4d89606da 100755 --- a/include/items.php +++ b/include/items.php @@ -1418,16 +1418,23 @@ function get_atom_elements($feed,$item,&$author) { if($found_author) { $author['author_name'] = unxmlify($found_author->get_name()); $author['author_link'] = unxmlify($found_author->get_link()); + $author['author_is_feed'] = false; } else { $author['author_name'] = unxmlify($feed->get_title()); $author['author_link'] = unxmlify($feed->get_permalink()); + $author['author_is_feed'] = true; } + if(substr($author['author_link'],-1,1) == '/') + $author['author_link'] = substr($author['author_link'],0,-1); + $res['mid'] = base64url_encode(unxmlify($item->get_id())); $res['title'] = unxmlify($item->get_title()); $res['body'] = unxmlify($item->get_content()); $res['plink'] = unxmlify($item->get_link(0)); + $res['item_flags'] = ITEM_RSS; + // removing the content of the title if its identically to the body // This helps with auto generated titles e.g. from tumblr @@ -1488,8 +1495,10 @@ function get_atom_elements($feed,$item,&$author) { if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach($base as $link) { - if($link['attribs']['']['rel'] === 'alternate' && (! $author['author_link'])) + if($link['attribs']['']['rel'] === 'alternate' && (! $author['author_link'])) { $author['author_link'] = unxmlify($link['attribs']['']['href']); + $author['author_is_feed'] = true; + } if(! $author['author_photo']) { if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') $author['author_photo'] = unxmlify($link['attribs']['']['href']); @@ -1576,6 +1585,28 @@ function get_atom_elements($feed,$item,&$author) { $res['body'] = escape_tags($res['body']); } + if($res['plink'] && $res['title']) { + $res['body'] = '#^[url=' . $res['plink'] . ']' . $res['title'] . '[/url]' . "\n\n" . $res['body']; + $terms = array(); + $terms[] = array( + 'otype' => TERM_OBJ_POST, + 'type' => TERM_BOOKMARK, + 'url' => $res['plink'], + 'term' => $res['title'], + ); + } + elseif($res['plink']) { + $res['body'] = '#^[url]' . $res['plink'] . '[/url]' . "\n\n" . $res['body']; + $terms = array(); + $terms[] = array( + 'otype' => TERM_OBJ_POST, + 'type' => TERM_BOOKMARK, + 'url' => $res['plink'], + 'term' => $res['plink'], + ); + } + + $private = $item->get_item_tags(NAMESPACE_DFRN,'private'); if($private && intval($private[0]['data']) > 0) $res['item_private'] = ((intval($private[0]['data'])) ? 1 : 0); @@ -1664,7 +1695,8 @@ function get_atom_elements($feed,$item,&$author) { $cats = $item->get_categories(); if($cats) { - $terms = array(); + if(is_null($terms)) + $terms = array(); foreach($cats as $cat) { $term = $cat->get_term(); if(! $term) @@ -1689,9 +1721,11 @@ function get_atom_elements($feed,$item,&$author) { ); } } - $res['term'] = $terms; } + if(! is_null($terms)) + $res['term'] = $terms; + $attach = $item->get_enclosures(); if($attach) { $res['attach'] = array(); @@ -1791,6 +1825,7 @@ function get_atom_elements($feed,$item,&$author) { call_hooks('parse_atom', $arr); logger('get_atom_elements: author: ' . print_r($author,true),LOGGER_DATA); + logger('get_atom_elements: ' . print_r($res,true),LOGGER_DATA); return $res; @@ -2469,18 +2504,10 @@ function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id) return; } - $body = $datarray['body']; - if(array_key_exists('item_flags',$datarray) && ($datarray['item_flags'] & ITEM_OBSCURED)) { - $key = get_config('system','prvkey'); - if($datarray['body']) - $body = crypto_unencapsulate(json_decode($datarray['body'],true),$key); - } - - logger('mod_item: storing diaspora comment signature',LOGGER_DEBUG); - require_once('include/bb2diaspora.php'); + $signed_body = bb2diaspora_itembody($datarray); - $signed_body = html_entity_decode(bb2diaspora($body)); + logger('mod_item: storing diaspora comment signature',LOGGER_DEBUG); $diaspora_handle = $channel['channel_address'] . '@' . get_app()->get_hostname(); @@ -3203,7 +3230,6 @@ function mail_store($arr) { } - /** * * consume_feed - process atom feed and update anything/everything we might need to update @@ -3321,11 +3347,11 @@ function consume_feed($xml,$importer,&$contact,$pass = 0) { $author = array(); $datarray = get_atom_elements($feed,$item,$author); - if(! x($author,'author_name')) + if((! x($author,'author_name')) || ($author['author_is_feed'])) $author['author_name'] = $contact['xchan_name']; - if(! x($author,'author_link')) + if((! x($author,'author_link')) || ($author['author_is_feed'])) $author['author_link'] = $contact['xchan_url']; - if(! x($author,'author_photo')) + if((! x($author,'author_photo'))|| ($author['author_is_feed'])) $author['author_photo'] = $contact['xchan_photo_m']; $datarray['author_xchan'] = ''; @@ -3384,11 +3410,11 @@ function consume_feed($xml,$importer,&$contact,$pass = 0) { $datarray = get_atom_elements($feed,$item,$author); if(is_array($contact)) { - if(! x($author,'author_name')) + if((! x($author,'author_name')) || ($author['author_is_feed'])) $author['author_name'] = $contact['xchan_name']; - if(! x($author,'author_link')) + if((! x($author,'author_link')) || ($author['author_is_feed'])) $author['author_link'] = $contact['xchan_url']; - if(! x($author,'author_photo')) + if((! x($author,'author_photo'))|| ($author['author_is_feed'])) $author['author_photo'] = $contact['xchan_photo_m']; } diff --git a/include/js_strings.php b/include/js_strings.php index cda66a09c..f4c0a631d 100644 --- a/include/js_strings.php +++ b/include/js_strings.php @@ -15,6 +15,7 @@ function js_strings() { '$passhint' => t('Passphrase hint'), '$permschange' => t('Notice: Permissions have changed but have not yet been submitted.'), '$closeAll' => t('close all'), + '$nothingnew' => t('Nothing new here'), '$t01' => ((t('timeago.prefixAgo') != 'timeago.prefixAgo') ? t('timeago.prefixAgo') : ''), '$t02' => ((t('timeago.prefixFromNow') != 'timeago.prefixFromNow') ? t('timeago.prefixFromNow') : ''), diff --git a/include/menu.php b/include/menu.php index 4b0a11f10..8997d2e39 100644 --- a/include/menu.php +++ b/include/menu.php @@ -124,7 +124,17 @@ function menu_list($channel_id, $name = '', $flags = 0) { return $r; } +function menu_list_count($channel_id, $name = '', $flags = 0) { + $sel_options = ''; + $sel_options .= (($name) ? " and menu_name = '" . protect_sprintf(dbesc($name)) . "' " : ''); + $sel_options .= (($flags) ? " and menu_flags = " . intval($flags) . " " : ''); + + $r = q("select count(*) as total from menu where menu_channel_id = %d $sel_options", + intval($channel_id) + ); + return $r[0]['total']; +} function menu_edit($arr) { diff --git a/include/message.php b/include/message.php index 96c3532c1..88cfb7ba2 100644 --- a/include/message.php +++ b/include/message.php @@ -27,6 +27,9 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto=' // else // $expires = datetime_convert(date_default_timezone_get(),'UTC',$expires); + + + if($uid) { $r = q("select * from channel where channel_id = %d limit 1", intval($uid) @@ -43,6 +46,59 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto=' return $ret; } + + // look for any existing conversation structure + + if(strlen($replyto)) { + $r = q("select convid from mail where uid = %d and ( mid = '%s' or parent_mid = '%s' ) limit 1", + intval(local_user()), + dbesc($replyto), + dbesc($replyto) + ); + if($r) + $convid = $r[0]['convid']; + } + + if(! $convid) { + + // create a new conversation + + $conv_guid = random_string(); + + $recip = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($recipient) + ); + if($recip) + $recip_handle = $recip[0]['xchan_addr']; + + $sender_handle = $channel['channel_address'] . '@' . get_app()->get_hostname(); + + $handles = $recip_handle . ';' . $sender_handle; + + $r = q("insert into conv (uid,guid,creator,created,updated,subject,recips) values(%d, '%s', '%s', '%s', '%s', '%s', '%s') ", + intval(local_user()), + dbesc($conv_guid), + dbesc($sender_handle), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($subject), + dbesc($handles) + ); + + $r = q("select * from conv where guid = '%s' and uid = %d limit 1", + dbesc($conv_guid), + intval(local_user()) + ); + if($r) + $convid = $r[0]['id']; + } + + if(! $convid) { + $ret['message'] = 'conversation not found'; + return $ret; + } + + // generate a unique message_id do { @@ -115,9 +171,10 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto=' - $r = q("INSERT INTO mail ( account_id, mail_flags, channel_id, from_xchan, to_xchan, title, body, attach, mid, parent_mid, created, expires ) - VALUES ( %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", + $r = q("INSERT INTO mail ( account_id, convid, mail_flags, channel_id, from_xchan, to_xchan, title, body, attach, mid, parent_mid, created, expires ) + VALUES ( %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", intval($channel['channel_account_id']), + intval($convid), intval(MAIL_OBSCURED), intval($channel['channel_id']), dbesc($channel['channel_hash']), @@ -227,9 +284,7 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) { $r[$k]['to'] = find_xchan_in_array($rr['to_xchan'],$c); $r[$k]['seen'] = (($rr['mail_flags'] & MAIL_SEEN) ? 1 : 0); if($r[$k]['mail_flags'] & MAIL_OBSCURED) { - logger('unencrypting'); $key = get_config('system','prvkey'); - if($r[$k]['title']) $r[$k]['title'] = crypto_unencapsulate(json_decode_plus($r[$k]['title']),$key); if($r[$k]['body']) diff --git a/include/nav.php b/include/nav.php index 799faf5ce..98d1b644e 100644 --- a/include/nav.php +++ b/include/nav.php @@ -105,14 +105,19 @@ EOT; $nav['usermenu'][] = Array('cloud/' . $channel['channel_address'],t('Files'),"",t('Your files')); require_once('include/chat.php'); - $chats = chatroom_list(local_user()); - if (count($chats)) { + $has_chats = chatroom_list_count(local_user()); + if($has_chats) { $nav['usermenu'][] = Array('chat/' . $channel['channel_address'],t('Chat'),"",t('Your chatrooms')); } - $nav['usermenu'][] = Array('bookmarks', t('Bookmarks'), "", t('Your bookmarks')); + require_once('include/menu.php'); + $has_bookmarks = menu_list_count(local_user(),'',MENU_BOOKMARK) + menu_list_count(local_user(),'',MENU_SYSTEM|MENU_BOOKMARK); + if($has_bookmarks) { + $nav['usermenu'][] = Array('bookmarks', t('Bookmarks'), "", t('Your bookmarks')); + } + if(feature_enabled($channel['channel_id'],'webpages')) - $nav['usermenu'][] = Array('webpages/' . $channel['channel_address'],t('Webpages'),"",t('Your webpages')); + $nav['usermenu'][] = Array('webpages/' . $channel['channel_address'],t('Webpages'),"",t('Your webpages')); } else { if(! get_account_id()) @@ -241,7 +246,7 @@ EOT; '$sitelocation' => $sitelocation, '$nav' => $x['nav'], '$banner' => $banner, - '$emptynotifications' => t('Nothing new here'), + '$emptynotifications' => t('Loading...'), '$userinfo' => $x['usermenu'], '$localuser' => local_user(), '$sel' => $a->nav_sel, diff --git a/include/notifier.php b/include/notifier.php index 3f34d6133..79a6886ad 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -158,7 +158,7 @@ function notifier_run($argv, $argc){ $message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1", intval($item_id) ); - if(! count($message)){ + if(! $message) { return; } xchan_mail_query($message[0]); @@ -477,10 +477,13 @@ function notifier_run($argv, $argc){ where hubloc_hash in (" . implode(',',$recipients) . ") group by hubloc_sitekey order by hubloc_connected desc limit 1"); } else { + $r = q("select hubloc_guid, hubloc_url, hubloc_sitekey, hubloc_network, hubloc_flags, hubloc_callback, hubloc_host from hubloc - where hubloc_hash in (" . implode(',',$recipients) . ") and not (hubloc_flags & %d) group by hubloc_sitekey", - intval(HUBLOC_FLAGS_DELETED) + where hubloc_hash in (" . implode(',',$recipients) . ") and not (hubloc_flags & %d) and not (hubloc_status & %d) group by hubloc_sitekey", + intval(HUBLOC_FLAGS_DELETED), + intval(HUBLOC_OFFLINE) ); + } if(! $r) { diff --git a/include/onepoll.php b/include/onepoll.php index 1f28852e9..98d52db93 100644 --- a/include/onepoll.php +++ b/include/onepoll.php @@ -135,7 +135,7 @@ function onepoll_run($argv, $argc){ foreach($j['messages'] as $message) { $results = process_delivery(array('hash' => $contact['xchan_hash']), get_item_elements($message), array(array('hash' => $importer['xchan_hash'])), false); - logger('onepoll: feed_update: process_delivery: ' . print_r($results,true)); + logger('onepoll: feed_update: process_delivery: ' . print_r($results,true), LOGGER_DATA); $total ++; } logger("onepoll: $total messages processed"); diff --git a/include/permissions.php b/include/permissions.php index e25052f95..438b807d0 100644 --- a/include/permissions.php +++ b/include/permissions.php @@ -747,7 +747,7 @@ function role_selector($current) { $selected = (($kk === $current) ? ' selected="selected" ' : ''); $o .= '<option value="' . $kk . '" ' . $selected . '>' . htmlspecialchars($vv) . '</option>'; } - $o .= '<optgroup>'; + $o .= '</optgroup>'; } $o .= '</select>'; return $o; diff --git a/include/security.php b/include/security.php index 0f2edc708..e83cc7061 100644 --- a/include/security.php +++ b/include/security.php @@ -82,6 +82,19 @@ function change_channel($change_channel) { intval(PAGE_REMOVED) ); + // It's not there. Is this an administrator, and is this the sys channel? + if (is_developer()) { + if (! $r) { + if (is_site_admin()) { + $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and ( channel_pageflags & %d) and not (channel_pageflags & %d ) limit 1", + intval($change_channel), + intval(PAGE_SYSTEM), + intval(PAGE_REMOVED) + ); + } + } + } + if($r) { $hash = $r[0]['channel_hash']; $_SESSION['uid'] = intval($r[0]['channel_id']); diff --git a/include/text.php b/include/text.php index 599c5d445..22cf17866 100644 --- a/include/text.php +++ b/include/text.php @@ -1183,7 +1183,11 @@ function theme_attachments(&$item) { $title = t('unknown.???'); $title .= ' ' . $r['length'] . ' ' . t('bytes'); - $url = z_root() . '/magic?f=&hash=' . $item['author_xchan'] . '&dest=' . $r['href'] . '/' . $r['revision']; + require_once('include/identity.php'); + if(is_foreigner($item['author_xchan'])) + $url = $r['href']; + else + $url = z_root() . '/magic?f=&hash=' . $item['author_xchan'] . '&dest=' . $r['href'] . '/' . $r['revision']; $s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>'; $attaches[] = array('title' => $title, 'url' => $url, 'icon' => $icon ); @@ -1851,9 +1855,17 @@ function ids_to_querystr($arr,$idx = 'id') { // author_xchan and owner_xchan. If $abook is true also include the abook info. // This is needed in the API to save extra per item lookups there. -function xchan_query(&$items,$abook = true) { +function xchan_query(&$items,$abook = true,$effective_uid = 0) { $arr = array(); if($items && count($items)) { + + if($effective_uid) { + for($x = 0; $x < count($items); $x ++) { + $items[$x]['real_uid'] = $items[$x]['uid']; + $items[$x]['uid'] = $effective_uid; + } + } + foreach($items as $item) { if($item['owner_xchan'] && (! in_array($item['owner_xchan'],$arr))) $arr[] = "'" . dbesc($item['owner_xchan']) . "'"; diff --git a/include/zot.php b/include/zot.php index b7ffe14e4..828194c3a 100644 --- a/include/zot.php +++ b/include/zot.php @@ -2399,7 +2399,7 @@ function process_channel_sync_delivery($sender,$arr,$deliveries) { ); if($r) { // don't count yourself - $total_friends = ((count($r) > 0) ? $count($r) - 1 : 0); + $total_friends = ((count($r) > 0) ? count($r) - 1 : 0); foreach($r as $rr) if($rr['abook_flags'] & ABOOK_FLAG_FEED) $total_feeds ++; @@ -2407,9 +2407,9 @@ function process_channel_sync_delivery($sender,$arr,$deliveries) { $disallowed = array('abook_id','abook_account','abook_channel'); - $clean = array(); foreach($arr['abook'] as $abook) { + $clean = array(); if($abook['abook_xchan'] && $abook['entry_deleted']) { logger('process_channel_sync_delivery: removing abook entry for ' . $abook['abook_xchan']); require_once('include/Contact.php'); |