diff --git a/include/Contact.php b/include/Contact.php index a4d6211fa..5cf40a9f0 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -106,7 +106,7 @@ function terminate_friendship($user,$self,$contact) { } elseif($contact['network'] === NETWORK_DIASPORA) { require_once('include/diaspora.php'); - diaspora::send_unshare($user,$contact); + Diaspora::send_unshare($user,$contact); } elseif($contact['network'] === NETWORK_DFRN) { require_once('include/dfrn.php'); diff --git a/include/api.php b/include/api.php index a352da9fa..678c0ca33 100644 --- a/include/api.php +++ b/include/api.php @@ -3218,7 +3218,7 @@ function api_share_as_retweet(&$item) { $body = trim($item["body"]); - if (diaspora::is_reshare($body, false)===false) { + if (Diaspora::is_reshare($body, false)===false) { return false; } diff --git a/include/contact_selectors.php b/include/contact_selectors.php index ec9dff61d..6b827baf3 100644 --- a/include/contact_selectors.php +++ b/include/contact_selectors.php @@ -99,7 +99,7 @@ function network_to_name($s, $profile = "") { $networkname = str_replace($search,$replace,$s); - if (($s == NETWORK_DIASPORA) AND ($profile != "") AND diaspora::is_redmatrix($profile)) { + if (($s == NETWORK_DIASPORA) AND ($profile != "") AND Diaspora::is_redmatrix($profile)) { $networkname = t("Hubzilla/Redmatrix"); $r = q("SELECT `gserver`.`platform` FROM `gcontact` diff --git a/include/delivery.php b/include/delivery.php index db2f03c8f..f7245942a 100644 --- a/include/delivery.php +++ b/include/delivery.php @@ -508,7 +508,7 @@ function delivery_run(&$argv, &$argc){ break; if ($mail) { - diaspora::send_mail($item,$owner,$contact); + Diaspora::send_mail($item,$owner,$contact); break; } @@ -530,22 +530,22 @@ function delivery_run(&$argv, &$argc){ if (($target_item['deleted']) && (($target_item['uri'] === $target_item['parent-uri']) || $followup)) { // top-level retraction logger('diaspora retract: '.$loc); - diaspora::send_retraction($target_item,$owner,$contact,$public_message); + Diaspora::send_retraction($target_item,$owner,$contact,$public_message); break; } elseif ($followup) { // send comments and likes to owner to relay logger('diaspora followup: '.$loc); - diaspora::send_followup($target_item,$owner,$contact,$public_message); + Diaspora::send_followup($target_item,$owner,$contact,$public_message); break; } elseif ($target_item['uri'] !== $target_item['parent-uri']) { // we are the relay - send comments, likes and relayable_retractions to our conversants logger('diaspora relay: '.$loc); - diaspora::send_relay($target_item,$owner,$contact,$public_message); + Diaspora::send_relay($target_item,$owner,$contact,$public_message); break; } elseif ($top_level && !$walltowall) { // currently no workable solution for sending walltowall logger('diaspora status: '.$loc); - diaspora::send_status($target_item,$owner,$contact,$public_message); + Diaspora::send_status($target_item,$owner,$contact,$public_message); break; } diff --git a/include/diaspora.php b/include/diaspora.php index cfb624fdf..e4c81dca4 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -23,7 +23,7 @@ require_once("include/queue_fn.php"); * @brief This class contain functions to create and send Diaspora XML files * */ -class diaspora { +class Diaspora { /** * @brief Return a list of relay servers @@ -344,7 +344,7 @@ class diaspora { // This will often be different with relayed messages (for example "like" and "comment") $sender = $msg["author"]; - if (!diaspora::valid_posting($msg, $fields)) { + if (!self::valid_posting($msg, $fields)) { logger("Invalid posting"); return false; } @@ -669,27 +669,30 @@ class diaspora { * @return string the handle */ public static function handle_from_contact($contact_id, $gcontact_id = 0) { - $handle = False; + $handle = false; logger("contact id is ".$contact_id." - gcontact id is ".$gcontact_id, LOGGER_DEBUG); if ($gcontact_id != 0) { $r = q("SELECT `addr` FROM `gcontact` WHERE `id` = %d AND `addr` != ''", intval($gcontact_id)); - if ($r) + + if (dbm::is_result($r)) { return strtolower($r[0]["addr"]); + } } $r = q("SELECT `network`, `addr`, `self`, `url`, `nick` FROM `contact` WHERE `id` = %d", intval($contact_id)); - if ($r) { + + if (dbm::is_result($r)) { $contact = $r[0]; logger("contact 'self' = ".$contact['self']." 'url' = ".$contact['url'], LOGGER_DEBUG); - if($contact['addr'] != "") + if ($contact['addr'] != "") { $handle = $contact['addr']; - else { + } else { $baseurl_start = strpos($contact['url'],'://') + 3; $baseurl_length = strpos($contact['url'],'/profile') - $baseurl_start; // allows installations in a subdirectory--not sure how Diaspora will handle $baseurl = substr($contact['url'], $baseurl_start, $baseurl_length); @@ -700,6 +703,29 @@ class diaspora { return strtolower($handle); } + /** + * @brief get a url (scheme://domain.tld/u/user) from a given Diaspora* + * fcontact guid + * + * @param mixed $fcontact_guid Hexadecimal string guid + * + * @return string the contact url or null + */ + public static function url_from_contact_guid($fcontact_guid) { + logger("fcontact guid is ".$fcontact_guid, LOGGER_DEBUG); + + $r = q("SELECT `url` FROM `fcontact` WHERE `url` != '' AND `network` = '%s' AND `guid` = '%s'", + dbesc(NETWORK_DIASPORA), + dbesc($fcontact_guid) + ); + + if (dbm::is_result($r)) { + return $r[0]['url']; + } + + return null; + } + /** * @brief Get a contact id for a given handle * @@ -826,6 +852,38 @@ class diaspora { },$item["body"]); } + /** + * @brief Checks for relative /people/* links in an item body to match local + * contacts or prepends the remote host taken from the author link. + * + * @param string $body The item body to replace links from + * @param string $author_link The author link for missing local contact fallback + * + * @return the replaced string + */ + public function replace_people_guid($body, $author_link) { + $return = preg_replace_callback("&\[url=/people/([^\[\]]*)\](.*)\[\/url\]&Usi", + function ($match) use ($author_link) { + // $match + // 0 => '[url=/people/0123456789abcdef]Foo Bar[/url]' + // 1 => '0123456789abcdef' + // 2 => 'Foo Bar' + $handle = self::url_from_contact_guid($match[1]); + + if ($handle) { + $return = '@[url='.$handle.']'.$match[2].'[/url]'; + } else { + // No local match, restoring absolute remote URL from author scheme and host + $author_url = parse_url($author_link); + $return = '[url='.$author_url['scheme'].'://'.$author_url['host'].'/people/'.$match[1].']'.$match[2].'[/url]'; + } + + return $return; + }, $body); + + return $return; + } + /** * @brief sub function of "fetch_guid" which checks for links in messages * @@ -1115,22 +1173,26 @@ class diaspora { $text = unxmlify($data->text); $author = notags(unxmlify($data->author)); - if (isset($data->created_at)) + if (isset($data->created_at)) { $created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at))); - else + } else { $created_at = datetime_convert(); + } $contact = self::allowed_contact_by_handle($importer, $sender, true); - if (!$contact) + if (!$contact) { return false; + } $message_id = self::message_exists($importer["uid"], $guid); - if ($message_id) + if ($message_id) { return $message_id; + } $parent_item = self::parent_item($importer["uid"], $parent_guid, $author, $contact); - if (!$parent_item) + if (!$parent_item) { return false; + } $person = self::person_by_handle($author); if (!is_array($person)) { @@ -1168,14 +1230,17 @@ class diaspora { $datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at; - $datarray["body"] = diaspora2bb($text); + $body = diaspora2bb($text); + + $datarray["body"] = self::replace_people_guid($body, $person["url"]); self::fetch_guid($datarray); $message_id = item_store($datarray); - if ($message_id) + if ($message_id) { logger("Stored comment ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG); + } // If we are the origin of the parent we store the original data and notify our followers if($message_id AND $parent_item["origin"]) { @@ -1211,8 +1276,6 @@ class diaspora { $subject = notags(unxmlify($data->subject)); $author = notags(unxmlify($data->author)); - $reply = 0; - $msg_guid = notags(unxmlify($mesg->guid)); $msg_parent_guid = notags(unxmlify($mesg->parent_guid)); $msg_parent_author_signature = notags(unxmlify($mesg->parent_author_signature)); @@ -1222,16 +1285,17 @@ class diaspora { // "diaspora_handle" is the element name from the old version // "author" is the element name from the new version - if ($mesg->author) + if ($mesg->author) { $msg_author = notags(unxmlify($mesg->author)); - elseif ($mesg->diaspora_handle) + } elseif ($mesg->diaspora_handle) { $msg_author = notags(unxmlify($mesg->diaspora_handle)); - else + } else { return false; + } $msg_conversation_guid = notags(unxmlify($mesg->conversation_guid)); - if($msg_conversation_guid != $guid) { + if ($msg_conversation_guid != $guid) { logger("message conversation guid does not belong to the current conversation."); return false; } @@ -1243,15 +1307,15 @@ class diaspora { $author_signature = base64_decode($msg_author_signature); - if(strcasecmp($msg_author,$msg["author"]) == 0) { + if (strcasecmp($msg_author,$msg["author"]) == 0) { $person = $contact; $key = $msg["key"]; } else { $person = self::person_by_handle($msg_author); - if (is_array($person) && x($person, "pubkey")) + if (is_array($person) && x($person, "pubkey")) { $key = $person["pubkey"]; - else { + } else { logger("unable to find author details"); return false; } @@ -1262,7 +1326,7 @@ class diaspora { return false; } - if($msg_parent_author_signature) { + if ($msg_parent_author_signature) { $owner_signed_data = $msg_guid.";".$msg_parent_guid.";".$msg_text.";".unxmlify($mesg->created_at).";".$msg_author.";".$msg_conversation_guid; $parent_author_signature = base64_decode($msg_parent_author_signature); @@ -1546,8 +1610,9 @@ class diaspora { $conversation_guid = notags(unxmlify($data->conversation_guid)); $contact = self::allowed_contact_by_handle($importer, $author, true); - if (!$contact) + if (!$contact) { return false; + } $conversation = null; @@ -1555,16 +1620,13 @@ class diaspora { intval($importer["uid"]), dbesc($conversation_guid) ); - if($c) + if ($c) { $conversation = $c[0]; - else { + } else { logger("conversation not available."); return false; } - $reply = 0; - - $body = diaspora2bb($text); $message_uri = $author.":".$guid; $person = self::person_by_handle($author); @@ -1577,11 +1639,15 @@ class diaspora { dbesc($message_uri), intval($importer["uid"]) ); - if ($r) { + if (dbm::is_result($r)) { logger("duplicate message already delivered.", LOGGER_DEBUG); return false; } + $body = diaspora2bb($text); + + $body = self::replace_people_guid($body, $person["url"]); + 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')", intval($importer["uid"]), @@ -1840,20 +1906,23 @@ class diaspora { $author = unxmlify($data->author); $recipient = unxmlify($data->recipient); - if (!$author || !$recipient) + if (!$author || !$recipient) { return false; + } // the current protocol version doesn't know these fields // That means that we will assume their existance - if (isset($data->following)) + if (isset($data->following)) { $following = (unxmlify($data->following) == "true"); - else + } else { $following = true; + } - if (isset($data->sharing)) + if (isset($data->sharing)) { $sharing = (unxmlify($data->sharing) == "true"); - else + } else { $sharing = true; + } $contact = self::contact_by_handle($importer["uid"],$author); @@ -1871,7 +1940,7 @@ class diaspora { // Normally we needn't to do so, but the first message could have been vanished. if (in_array($contact["rel"], array(CONTACT_IS_FRIEND, CONTACT_IS_FOLLOWER))) { $u = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer["uid"])); - if($u) { + if ($u) { logger("Sending share message to author ".$author." - Contact: ".$contact["id"]." - User: ".$importer["uid"], LOGGER_DEBUG); $ret = self::send_share($u[0], $contact); } @@ -2022,26 +2091,29 @@ class diaspora { FROM `item` WHERE `guid` = '%s' AND `visible` AND NOT `deleted` AND `body` != '' LIMIT 1", dbesc($guid)); - if ($r) { + if (dbm::is_result($r)) { logger("reshared message ".$guid." already exists on system."); // Maybe it is already a reshared item? // Then refetch the content, if it is a reshare from a reshare. // If it is a reshared post from another network then reformat to avoid display problems with two share elements - if (self::is_reshare($r[0]["body"], true)) + if (self::is_reshare($r[0]["body"], true)) { $r = array(); - elseif (self::is_reshare($r[0]["body"], false)) { + } elseif (self::is_reshare($r[0]["body"], false)) { $r[0]["body"] = diaspora2bb(bb2diaspora($r[0]["body"])); + $r[0]["body"] = self::replace_people_guid($r[0]["body"], $r[0]["author-link"]); + // Add OEmbed and other information to the body $r[0]["body"] = add_page_info_to_body($r[0]["body"], false, true); return $r[0]; - } else + } else { return $r[0]; + } } - if (!$r) { + if (!dbm::is_result($r)) { $server = "https://".substr($orig_author, strpos($orig_author, "@") + 1); logger("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server); $item_id = self::store_by_guid($guid, $server); @@ -2058,10 +2130,12 @@ class diaspora { FROM `item` WHERE `id` = %d AND `visible` AND NOT `deleted` AND `body` != '' LIMIT 1", intval($item_id)); - if ($r) { + if (dbm::is_result($r)) { // If it is a reshared post from another network then reformat to avoid display problems with two share elements - if (self::is_reshare($r[0]["body"], false)) + if (self::is_reshare($r[0]["body"], false)) { $r[0]["body"] = diaspora2bb(bb2diaspora($r[0]["body"])); + $r[0]["body"] = self::replace_people_guid($r[0]["body"], $r[0]["author-link"]); + } return $r[0]; } @@ -2089,16 +2163,19 @@ class diaspora { $created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at))); $contact = self::allowed_contact_by_handle($importer, $author, false); - if (!$contact) + if (!$contact) { return false; + } $message_id = self::message_exists($importer["uid"], $guid); - if ($message_id) + if ($message_id) { return $message_id; + } $original_item = self::original_item($root_guid, $root_author, $author); - if (!$original_item) + if (!$original_item) { return false; + } $orig_url = App::get_baseurl()."/display/".$original_item["guid"]; @@ -2140,8 +2217,9 @@ class diaspora { self::fetch_guid($datarray); $message_id = item_store($datarray); - if ($message_id) + if ($message_id) { logger("Stored reshare ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG); + } return $message_id; } @@ -2268,17 +2346,21 @@ class diaspora { // die("poll!\n"); //} $contact = self::allowed_contact_by_handle($importer, $author, false); - if (!$contact) + if (!$contact) { return false; + } $message_id = self::message_exists($importer["uid"], $guid); - if ($message_id) + if ($message_id) { return $message_id; + } $address = array(); - if ($data->location) - foreach ($data->location->children() AS $fieldname => $data) + if ($data->location) { + foreach ($data->location->children() AS $fieldname => $data) { $address[$fieldname] = notags(unxmlify($data)); + } + } $body = diaspora2bb($raw_message); @@ -2286,17 +2368,19 @@ class diaspora { // Attach embedded pictures to the body if ($data->photo) { - foreach ($data->photo AS $photo) + foreach ($data->photo AS $photo) { $body = "[img]".unxmlify($photo->remote_photo_path). unxmlify($photo->remote_photo_name)."[/img]\n".$body; + } $datarray["object-type"] = ACTIVITY_OBJ_IMAGE; } else { $datarray["object-type"] = ACTIVITY_OBJ_NOTE; // Add OEmbed and other information to the body - if (!self::is_redmatrix($contact["url"])) + if (!self::is_redmatrix($contact["url"])) { $body = add_page_info_to_body($body, false, true); + } } $datarray["uid"] = $importer["uid"]; @@ -2319,26 +2403,30 @@ class diaspora { $datarray["object"] = $xml; - $datarray["body"] = $body; + $datarray["body"] = self::replace_people_guid($body, $contact["url"]); - if ($provider_display_name != "") + if ($provider_display_name != "") { $datarray["app"] = $provider_display_name; + } $datarray["plink"] = self::plink($author, $guid); $datarray["private"] = (($public == "false") ? 1 : 0); $datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at; - if (isset($address["address"])) + if (isset($address["address"])) { $datarray["location"] = $address["address"]; + } - if (isset($address["lat"]) AND isset($address["lng"])) + if (isset($address["lat"]) AND isset($address["lng"])) { $datarray["coord"] = $address["lat"]." ".$address["lng"]; + } self::fetch_guid($datarray); $message_id = item_store($datarray); - if ($message_id) + if ($message_id) { logger("Stored item ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG); + } return $message_id; } @@ -2382,7 +2470,7 @@ class diaspora { $b64url_data = base64url_encode($msg); $data = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data); - $key_id = base64url_encode(diaspora::my_handle($user)); + $key_id = base64url_encode(self::my_handle($user)); $type = "application/xml"; $encoding = "base64url"; $alg = "RSA-SHA256"; @@ -2908,7 +2996,7 @@ class diaspora { */ public static function send_status($item, $owner, $contact, $public_batch = false) { - $status = diaspora::build_status($item, $owner); + $status = self::build_status($item, $owner); return self::build_and_transmit($owner, $contact, $status["type"], $status["message"], $public_batch, $item["guid"]); } diff --git a/include/follow.php b/include/follow.php index 15e8dd28d..e7693822a 100644 --- a/include/follow.php +++ b/include/follow.php @@ -293,8 +293,9 @@ function new_contact($uid,$url,$interactive = false) { $slap = ostatus::salmon($item, $r[0]); slapper($r[0], $contact['notify'], $slap); } + if ($contact['network'] == NETWORK_DIASPORA) { - $ret = diaspora::send_share($a->user,$contact); + $ret = Diaspora::send_share($a->user,$contact); logger('share returns: '.$ret); } } diff --git a/include/like.php b/include/like.php index 4df15b4b6..893047da3 100644 --- a/include/like.php +++ b/include/like.php @@ -246,7 +246,7 @@ EOT; // Save the author information for the like in case we need to relay to Diaspora - diaspora::store_like_signature($contact, $post_id); + Diaspora::store_like_signature($contact, $post_id); $arr['id'] = $post_id; diff --git a/include/notifier.php b/include/notifier.php index 72387c98d..84efe7952 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -571,7 +571,7 @@ function notifier_run(&$argv, &$argc){ if($public_message) { if (!$followup) - $r0 = diaspora::relay_list(); + $r0 = Diaspora::relay_list(); else $r0 = array(); diff --git a/include/profile_update.php b/include/profile_update.php index 399150f21..7aa34d45d 100644 --- a/include/profile_update.php +++ b/include/profile_update.php @@ -2,5 +2,5 @@ require_once('include/diaspora.php'); function profile_change() { - diaspora::send_profile(local_user()); + Diaspora::send_profile(local_user()); } diff --git a/include/queue.php b/include/queue.php index 8f57bf3d7..2e0b19bfa 100644 --- a/include/queue.php +++ b/include/queue.php @@ -196,7 +196,7 @@ function queue_run(&$argv, &$argc){ case NETWORK_DIASPORA: if($contact['notify']) { logger('queue: diaspora_delivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); - $deliver_status = diaspora::transmit($owner,$contact,$data,$public,true); + $deliver_status = Diaspora::transmit($owner,$contact,$data,$public,true); if($deliver_status == (-1)) { update_queue_time($q_item['id']); diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php index 65ec67586..684cd341e 100644 --- a/mod/dfrn_confirm.php +++ b/mod/dfrn_confirm.php @@ -433,7 +433,7 @@ function dfrn_confirm_post(&$a,$handsfree = null) { if(($contact) && ($contact['network'] === NETWORK_DIASPORA)) { require_once('include/diaspora.php'); - $ret = diaspora::send_share($user[0],$r[0]); + $ret = Diaspora::send_share($user[0],$r[0]); logger('share returns: ' . $ret); } diff --git a/mod/fetch.php b/mod/fetch.php index 04bdf5188..afb5b88af 100644 --- a/mod/fetch.php +++ b/mod/fetch.php @@ -52,12 +52,12 @@ function fetch_init(&$a){ } $user = $r[0]; - $status = diaspora::build_status($item[0], $user); - $xml = diaspora::build_post_xml($status["type"], $status["message"]); + $status = Diaspora::build_status($item[0], $user); + $xml = Diaspora::build_post_xml($status["type"], $status["message"]); // Send the envelope header("Content-Type: application/magic-envelope+xml; charset=utf-8"); - echo diaspora::build_magic_envelope($xml, $user); + echo Diaspora::build_magic_envelope($xml, $user); killme(); } diff --git a/mod/item.php b/mod/item.php index ca428e3d1..b902f1e35 100644 --- a/mod/item.php +++ b/mod/item.php @@ -965,7 +965,7 @@ function item_post(&$a) { // Store the comment signature information in case we need to relay to Diaspora - diaspora::store_comment_signature($datarray, $author, ($self ? $user['prvkey'] : false), $post_id); + Diaspora::store_comment_signature($datarray, $author, ($self ? $user['prvkey'] : false), $post_id); } else { $parent = $post_id; diff --git a/mod/p.php b/mod/p.php index 4db8f5529..875546451 100644 --- a/mod/p.php +++ b/mod/p.php @@ -54,8 +54,8 @@ function p_init($a){ } $user = $r[0]; - $status = diaspora::build_status($item[0], $user); - $xml = diaspora::build_post_xml($status["type"], $status["message"]); + $status = Diaspora::build_status($item[0], $user); + $xml = Diaspora::build_post_xml($status["type"], $status["message"]); header("Content-Type: application/xml; charset=utf-8"); echo $xml; diff --git a/mod/receive.php b/mod/receive.php index 99e3648e9..87fd79363 100644 --- a/mod/receive.php +++ b/mod/receive.php @@ -54,7 +54,7 @@ function receive_post(&$a) { logger('mod-diaspora: message is okay', LOGGER_DEBUG); - $msg = diaspora::decode($importer,$xml); + $msg = Diaspora::decode($importer,$xml); logger('mod-diaspora: decoded', LOGGER_DEBUG); @@ -67,9 +67,9 @@ function receive_post(&$a) { $ret = 0; if($public) { - diaspora::dispatch_public($msg); + Diaspora::dispatch_public($msg); } else { - $ret = diaspora::dispatch($importer,$msg); + $ret = Diaspora::dispatch($importer,$msg); } http_status_exit(($ret) ? $ret : 200); diff --git a/object/Item.php b/object/Item.php index e60344f7d..1c6eaf5f9 100644 --- a/object/Item.php +++ b/object/Item.php @@ -349,7 +349,7 @@ class Item extends BaseObject { // Diaspora isn't able to do likes on comments - but red does if (($item["item_network"] == NETWORK_DIASPORA) AND ($indent == 'comment') AND - !diaspora::is_redmatrix($item["owner-link"]) AND isset($buttons["like"])) { + !Diaspora::is_redmatrix($item["owner-link"]) AND isset($buttons["like"])) { unset($buttons["like"]); }