require_once("include/bb2diaspora.php");
require_once("include/Scrape.php");
require_once("include/Contact.php");
+require_once("include/Photo.php");
+require_once("include/socgraph.php");
-function array_to_xml($array, &$xml) {
+class xml {
+ function from_array($array, &$xml) {
- if (!is_object($xml)) {
- foreach($array as $key => $value) {
- $root = new SimpleXMLElement('<'.$key.'/>');
- array_to_xml($value, $root);
+ if (!is_object($xml)) {
+ foreach($array as $key => $value) {
+ $root = new SimpleXMLElement('<'.$key.'/>');
+ array_to_xml($value, $root);
- $dom = dom_import_simplexml($root)->ownerDocument;
- $dom->formatOutput = true;
- return $dom->saveXML();
+ $dom = dom_import_simplexml($root)->ownerDocument;
+ $dom->formatOutput = true;
+ return $dom->saveXML();
+ }
+ }
+
+ foreach($array as $key => $value) {
+ if (!is_array($value) AND !is_numeric($key))
+ $xml->addChild($key, $value);
+ elseif (is_array($value))
+ array_to_xml($value, $xml->addChild($key));
}
}
- foreach($array as $key => $value) {
- if (!is_array($value) AND !is_numeric($key))
- $xml->addChild($key, $value);
- elseif (is_array($value))
- array_to_xml($value, $xml->addChild($key));
+ function copy(&$source, &$target, $elementname) {
+ if (count($source->children()) == 0)
+ $target->addChild($elementname, $source);
+ else {
+ $child = $target->addChild($elementname);
+ foreach ($source->children() AS $childfield => $childentry)
+ self::copy($childentry, $child, $childfield);
+ }
}
}
-
/**
- * @brief This class contain functions to create and send DFRN XML files
+ * @brief This class contain functions to create and send Diaspora XML files
*
*/
class diaspora {
$enabled = intval(get_config("system", "diaspora_enabled"));
if (!$enabled) {
- logger('diaspora is disabled');
+ logger("diaspora is disabled");
return false;
}
// This will often be different with relayed messages (for example "like" and "comment")
$sender = $msg["author"];
- if (!diaspora::valid_posting($msg, $fields)) {
+ if (!diaspora::valid_posting($msg, $fields, $data2)) {
logger("Invalid posting");
return false;
}
$type = $fields->getName();
switch ($type) {
- case "account_deletion":
+ case "account_deletion": // Not implemented
return self::import_account_deletion($importer, $fields);
case "comment":
return true;
- // return self::import_comment($importer, $sender, $fields);
+ //return self::import_comment($importer, $sender, $fields);
case "conversation":
return self::import_conversation($importer, $fields);
case "like":
- // return true;
- return self::import_like($importer, $sender, $fields);
+ return true;
+ //return self::import_like($importer, $sender, $fields);
case "message":
- return self::import_message($importer, $fields);
+ return true;
+ //return self::import_message($importer, $fields);
- case "participation":
+ case "participation": // Not implemented
return self::import_participation($importer, $fields);
case "photo":
return self::import_photo($importer, $fields);
- case "poll_participation":
+ case "poll_participation": // Not implemented
return self::import_poll_participation($importer, $fields);
case "profile":
- return self::import_profile($importer, $fields);
+ return true;
+ //return self::import_profile($importer, $fields);
case "request":
return self::import_request($importer, $fields);
return self::import_retraction($importer, $fields);
case "status_message":
- return self::import_status_message($importer, $fields);
+ return self::import_status_message($importer, $fields, $msg, $data2);
default:
logger("Unknown message type ".$type);
* It also does the conversion between the old and the new diaspora format.
*
* @param array $msg Array with the XML, the sender handle and the sender signature
- * @param object $fields SimpleXML object that contains the posting
+ * @param object $fields SimpleXML object that contains the posting when it is valid
*
* @return bool Is the posting valid?
*/
- private function valid_posting($msg, &$fields) {
+ private function valid_posting($msg, &$fields, &$element) {
$data = parse_xml_string($msg["message"], false);
+ if (!is_object($data))
+ return false;
+
$first_child = $data->getName();
+ // Is this the new or the old version?
if ($data->getName() == "XML") {
$oldXML = true;
foreach ($data->post->children() as $child)
$type = $element->getName();
+ // All retractions are handled identically from now on.
+ // In the new version there will only be "retraction".
if (in_array($type, array("signed_retraction", "relayable_retraction")))
$type = "retraction";
$signed_data = "";
- foreach ($element->children() AS $fieldname => $data) {
-
+ foreach ($element->children() AS $fieldname => $entry) {
if ($oldXML) {
// Translation for the old XML structure
if ($fieldname == "diaspora_handle")
}
if ($fieldname == "author_signature")
- $author_signature = base64_decode($data);
+ $author_signature = base64_decode($entry);
elseif ($fieldname == "parent_author_signature")
- $parent_author_signature = base64_decode($data);
+ $parent_author_signature = base64_decode($entry);
elseif ($fieldname != "target_author_signature") {
if ($signed_data != "") {
$signed_data .= ";";
$signed_data_parent .= ";";
}
- $signed_data .= $data;
+ $signed_data .= $entry;
}
if (!in_array($fieldname, array("parent_author_signature", "target_author_signature")))
- $fields->$fieldname = $data;
+ xml::copy($entry, $fields, $fieldname);
}
- if (in_array($type, array("status_message", "reshare")))
+ // This is something that shouldn't happen at all.
+ if (in_array($type, array("status_message", "reshare", "profile")))
if ($msg["author"] != $fields->author) {
logger("Message handle is not the same as envelope sender. Quitting this message.");
return false;
}
+ // Only some message types have signatures. So we quit here for the other types.
if (!in_array($type, array("comment", "conversation", "message", "like")))
return true;
+ // No author_signature? This is a must, so we quit.
if (!isset($author_signature))
return false;
logger("Trying to fetch item ".$guid." from ".$server, LOGGER_DEBUG);
-/// @todo $item = self::fetch_message($guid, $server);
+ $msg = self::fetch_message($guid, $server);
- if (!$item)
+ if (!$msg)
return false;
logger("Successfully fetched item ".$guid." from ".$server, LOGGER_DEBUG);
-// @todo - neue Funktion import_status... nutzen
-print_r($item);
-die();
- return self::import_status_message($importer, $data);
+ // Now call the dispatcher
+ return self::dispatch_public($msg);
+ }
-/*
- $body = $item["body"];
- $str_tags = $item["tag"];
- $app = $item["app"];
- $created = $item["created"];
- $author = $item["author"];
- $guid = $item["guid"];
- $private = $item["private"];
- $object = $item["object"];
- $objecttype = $item["object-type"];
+ private function fetch_message($guid, $server, $level = 0) {
- $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
- intval($uid),
- dbesc($guid)
- );
- if(count($r))
- return $r[0]["id"];
+ if ($level > 5)
+ return false;
- $person = self::get_person_by_handle($author);
+ // This will not work if the server is not a Diaspora server
+ $source_url = $server."/p/".$guid.".xml";
+ $x = fetch_url($source_url);
+ if(!$x)
+ return false;
- $contact_id = get_contact($person["url"], $uid);
+ /// @todo - should maybe solved by the dispatcher
+ $source_xml = parse_xml_string($x, false);
- $contacts = q("SELECT * FROM `contact` WHERE `id` = %d", intval($contact_id));
- $importers = q("SELECT * FROM `user` WHERE `uid` = %d", intval($uid));
+ if (!is_object($source_xml))
+ return false;
- if ($contacts AND $importers)
- if (!self::post_allow($importers[0],$contacts[0], false)) {
- logger("Ignoring author ".$person["url"]." for uid ".$uid);
- return false;
- } else
- logger("Author ".$person["url"]." is allowed for uid ".$uid);
+ if ($source_xml->post->reshare) {
+ // Reshare of a reshare - old Diaspora version
+ return self::fetch_message($source_xml->post->reshare->root_guid, $server, ++$level);
+ } elseif ($source_xml->getName() == "reshare") {
+ // Reshare of a reshare - new Diaspora version
+ return self::fetch_message($source_xml->root_guid, $server, ++$level);
+ }
- $datarray = array();
- $datarray["uid"] = $uid;
- $datarray["contact-id"] = $contact_id;
- $datarray["wall"] = 0;
- $datarray["network"] = NETWORK_DIASPORA;
- $datarray["guid"] = $guid;
- $datarray["uri"] = $datarray["parent-uri"] = $author.":".$guid;
- $datarray["changed"] = $datarray["created"] = $datarray["edited"] = datetime_convert('UTC','UTC',$created);
- $datarray["private"] = $private;
- $datarray["parent"] = 0;
- $datarray["plink"] = self::plink($author, $guid);
- $datarray["author-name"] = $person["name"];
- $datarray["author-link"] = $person["url"];
- $datarray["author-avatar"] = ((x($person,'thumb')) ? $person["thumb"] : $person["photo"]);
- $datarray["owner-name"] = $datarray["author-name"];
- $datarray["owner-link"] = $datarray["author-link"];
- $datarray["owner-avatar"] = $datarray["author-avatar"];
- $datarray["body"] = $body;
- $datarray["tag"] = $str_tags;
- $datarray["app"] = $app;
- $datarray["visible"] = ((strlen($body)) ? 1 : 0);
- $datarray["object"] = $object;
- $datarray["object-type"] = $objecttype;
+ // Fetch the author - for the old and the new Diaspora version
+ if ($source_xml->post->status_message->diaspora_handle)
+ $author = (string)$source_xml->post->status_message->diaspora_handle;
+ elseif ($source_xml->author)
+ $author = (string)$source_xml->author;
- if ($datarray["contact-id"] == 0)
+ if (!$author)
return false;
- self::fetch_guid($datarray);
- $message_id = item_store($datarray);
+ $msg = array("message" => $x, "author" => $author);
- /// @TODO
- /// Looking if there is some subscribe mechanism in Diaspora to get all comments for this post
+ // We don't really need this, but until the work is unfinished we better will keep this
+ $msg["key"] = self::get_key($msg["author"]);
- return $message_id;
-*/
+ return $msg;
}
private function post_allow($importer, $contact, $is_comment = false) {
}
private function fetch_parent_item($uid, $guid, $author, $contact) {
- $r = q("SELECT `id`, `body`, `wall`, `uri`, `private`, `owner-name`, `owner-link`, `owner-avatar`, `origin`
+ $r = q("SELECT `id`, `body`, `wall`, `uri`, `private`, `origin`,
+ `author-name`, `author-link`, `author-avatar`,
+ `owner-name`, `owner-link`, `owner-avatar`
FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
intval($uid), dbesc($guid));
if ($result) {
logger("Fetched missing item ".$guid." - result: ".$result, LOGGER_DEBUG);
- $r = q("SELECT `id`, `body`, `wall`, `uri`, `private`,
- `owner-name`, `owner-link`, `owner-avatar`, `origin`
+ $r = q("SELECT `id`, `body`, `wall`, `uri`, `private`, `origin`,
+ `author-name`, `author-link`, `author-avatar`,
+ `owner-name`, `owner-link`, `owner-avatar`
FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
intval($uid), dbesc($guid));
}
return $r[0];
}
+ private function get_author_contact_by_url($contact, $person, $uid) {
+
+ $r = q("SELECT `id`, `network` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d LIMIT 1",
+ dbesc(normalise_link($person["url"])), intval($uid));
+ if ($r) {
+ $cid = $r[0]["id"];
+ $network = $r[0]["network"];
+ } else {
+ $cid = $contact["id"];
+ $network = NETWORK_DIASPORA;
+ }
+
+ return (array("cid" => $cid, "network" => $network));
+ }
+
+ public static function is_redmatrix($url) {
+ return(strstr($url, "/channel/"));
+ }
+
+ private function plink($addr, $guid) {
+ $r = q("SELECT `url`, `nick`, `network` FROM `fcontact` WHERE `addr`='%s' LIMIT 1", dbesc($addr));
+
+ // Fallback
+ if (!$r)
+ return "https://".substr($addr,strpos($addr,"@")+1)."/posts/".$guid;
+
+ // Friendica contacts are often detected as Diaspora contacts in the "fcontact" table
+ // So we try another way as well.
+ $s = q("SELECT `network` FROM `gcontact` WHERE `nurl`='%s' LIMIT 1", dbesc(normalise_link($r[0]["url"])));
+ if ($s)
+ $r[0]["network"] = $s[0]["network"];
+
+ if ($r[0]["network"] == NETWORK_DFRN)
+ return(str_replace("/profile/".$r[0]["nick"]."/", "/display/".$guid, $r[0]["url"]."/"));
+
+ if (self::is_redmatrix($r[0]["url"]))
+ return $r[0]["url"]."/?f=&mid=".$guid;
+
+ return "https://".substr($addr,strpos($addr,"@")+1)."/posts/".$guid;
+ }
+
private function import_account_deletion($importer, $data) {
+ // Not supported by now. We are waiting for sample data
return true;
}
logger("Ignoring the author ".$sender);
return false;
}
-/*
+
$r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
intval($importer["uid"]),
dbesc($guid)
);
if(count($r)) {
logger("The comment already exists: ".$guid);
- return;
+ return false;
}
-*/
+
$parent_item = self::fetch_parent_item($importer["uid"], $parent_guid, $author, $contact);
if (!$parent_item)
return false;
}
// Fetch the contact id - if we know this contact
- $r = q("SELECT `id`, `network` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d LIMIT 1",
- dbesc(normalise_link($person["url"])), intval($importer["uid"]));
- if ($r) {
- $cid = $r[0]["id"];
- $network = $r[0]["network"];
- } else {
- $cid = $contact["id"];
- $network = NETWORK_DIASPORA;
- }
-
- $body = diaspora2bb($text);
+ $author_contact = self::get_author_contact_by_url($contact, $person, $importer["uid"]);
$datarray = array();
$datarray["uid"] = $importer["uid"];
- $datarray["contact-id"] = $cid;
- $datarray["type"] = 'remote-comment';
- $datarray["wall"] = $parent_item["wall"];
- $datarray["network"] = $network;
- $datarray["verb"] = ACTIVITY_POST;
- $datarray["gravity"] = GRAVITY_COMMENT;
- $datarray["guid"] = $guid;
- $datarray["uri"] = $author.":".$guid;
- $datarray["parent-uri"] = $parent_item["uri"];
+ $datarray["contact-id"] = $author_contact["cid"];
+ $datarray["network"] = $author_contact["network"];
- // The old Diaspora protocol doesn't have a timestamp for comments
- $datarray["changed"] = $datarray["created"] = $datarray["edited"] = datetime_convert();
- $datarray["private"] = $parent_item["private"];
+ $datarray["author-name"] = $person["name"];
+ $datarray["author-link"] = $person["url"];
+ $datarray["author-avatar"] = ((x($person,"thumb")) ? $person["thumb"] : $person["photo"]);
$datarray["owner-name"] = $contact["name"];
$datarray["owner-link"] = $contact["url"];
$datarray["owner-avatar"] = ((x($contact,"thumb")) ? $contact["thumb"] : $contact["photo"]);
- $datarray["author-name"] = $person["name"];
- $datarray["author-link"] = $person["url"];
- $datarray["author-avatar"] = ((x($person,"thumb")) ? $person["thumb"] : $person["photo"]);
- $datarray["body"] = $body;
- $datarray["object"] = json_encode($data);
+ $datarray["guid"] = $guid;
+ $datarray["uri"] = $author.":".$guid;
+
+ $datarray["type"] = "remote-comment";
+ $datarray["verb"] = ACTIVITY_POST;
+ $datarray["gravity"] = GRAVITY_COMMENT;
+ $datarray["parent-uri"] = $parent_item["uri"];
+
$datarray["object-type"] = ACTIVITY_OBJ_COMMENT;
+ $datarray["object"] = json_encode($data);
+
+ $datarray["body"] = diaspora2bb($text);
self::fetch_guid($datarray);
-// $message_id = item_store($datarray);
-print_r($datarray);
- $datarray["id"] = $message_id;
+ $message_id = item_store($datarray);
+ // print_r($datarray);
// If we are the origin of the parent we store the original data and notify our followers
if($message_id AND $parent_item["origin"]) {
return true;
}
+ private function construct_like_body($contact, $parent_item, $guid) {
+ $bodyverb = t('%1$s likes %2$s\'s %3$s');
+
+ $ulink = "[url=".$contact["url"]."]".$contact["name"]."[/url]";
+ $alink = "[url=".$parent_item["author-link"]."]".$parent_item["author-name"]."[/url]";
+ $plink = "[url=".App::get_baseurl()."/display/".urlencode($guid)."]".t("status")."[/url]";
+
+ return sprintf($bodyverb, $ulink, $alink, $plink);
+ }
+
+ private function construct_like_object($importer, $parent_item) {
+ $objtype = ACTIVITY_OBJ_NOTE;
+ $link = xmlify('<link rel="alternate" type="text/html" href="'.App::get_baseurl()."/display/".$importer["nickname"]."/".$parent_item["id"].'" />'."\n") ;
+ $parent_body = $parent_item["body"];
+
+ $obj = <<< EOT
+
+ <object>
+ <type>$objtype</type>
+ <local>1</local>
+ <id>{$parent_item["uri"]}</id>
+ <link>$link</link>
+ <title></title>
+ <content>$parent_body</content>
+ </object>
+EOT;
+
+ return $obj;
+ }
+
private function import_like($importer, $sender, $data) {
$positive = notags(unxmlify($data->positive));
$guid = notags(unxmlify($data->guid));
logger("Ignoring the author ".$sender);
return false;
}
-/*
+
$r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
intval($importer["uid"]),
dbesc($guid)
logger("The like already exists: ".$guid);
return false;
}
-*/
+
$parent_item = self::fetch_parent_item($importer["uid"], $parent_guid, $author, $contact);
if (!$parent_item)
return false;
}
// Fetch the contact id - if we know this contact
- $r = q("SELECT `id`, `network` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d LIMIT 1",
- dbesc(normalise_link($person["url"])), intval($importer["uid"]));
- if ($r) {
- $cid = $r[0]["id"];
- $network = $r[0]["network"];
- } else {
- $cid = $contact["id"];
- $network = NETWORK_DIASPORA;
- }
-
-// ------------------------------------------------
- $objtype = ACTIVITY_OBJ_NOTE;
- $link = xmlify('<link rel="alternate" type="text/html" href="'.App::get_baseurl()."/display/".$importer["nickname"]."/".$parent_item["id"].'" />'."\n") ;
- $parent_body = $parent_item["body"];
-
- $obj = <<< EOT
-
- <object>
- <type>$objtype</type>
- <local>1</local>
- <id>{$parent_item["uri"]}</id>
- <link>$link</link>
- <title></title>
- <content>$parent_body</content>
- </object>
-EOT;
- $bodyverb = t('%1$s likes %2$s\'s %3$s');
-
- $ulink = "[url=".$contact["url"]."]".$contact["name"]."[/url]";
- $alink = "[url=".$parent_item["author-link"]."]".$parent_item["author-name"]."[/url]";
- $plink = "[url=".App::get_baseurl()."/display/".urlencode($guid)."]".t("status")."[/url]";
- $body = sprintf($bodyverb, $ulink, $alink, $plink);
-// ------------------------------------------------
+ $author_contact = self::get_author_contact_by_url($contact, $person, $importer["uid"]);
$datarray = array();
- $datarray["uri"] = $author.":".$guid;
$datarray["uid"] = $importer["uid"];
- $datarray["guid"] = $guid;
- $datarray["network"] = $network;
- $datarray["contact-id"] = $cid;
- $datarray["type"] = "activity";
- $datarray["wall"] = $parent_item["wall"];
- $datarray["gravity"] = GRAVITY_LIKE;
- $datarray["parent"] = $parent_item["id"];
- $datarray["parent-uri"] = $parent_item["uri"];
+ $datarray["contact-id"] = $author_contact["cid"];
+ $datarray["network"] = $author_contact["network"];
+
+ $datarray["author-name"] = $person["name"];
+ $datarray["author-link"] = $person["url"];
+ $datarray["author-avatar"] = ((x($person,"thumb")) ? $person["thumb"] : $person["photo"]);
$datarray["owner-name"] = $contact["name"];
$datarray["owner-link"] = $contact["url"];
$datarray["owner-avatar"] = ((x($contact,"thumb")) ? $contact["thumb"] : $contact["photo"]);
- $datarray["author-name"] = $person["name"];
- $datarray["author-link"] = $person["url"];
- $datarray["author-avatar"] = ((x($person,"thumb")) ? $person["thumb"] : $person["photo"]);
+ $datarray["guid"] = $guid;
+ $datarray["uri"] = $author.":".$guid;
- $datarray["body"] = $body;
- $datarray["private"] = $parent_item["private"];
+ $datarray["type"] = "activity";
$datarray["verb"] = ACTIVITY_LIKE;
- $datarray["object-type"] = $objtype;
- $datarray["object"] = $obj;
- $datarray["visible"] = 1;
- $datarray["unseen"] = 1;
- $datarray["last-child"] = 0;
+ $datarray["gravity"] = GRAVITY_LIKE;
+ $datarray["parent-uri"] = $parent_item["uri"];
-print_r($datarray);
-// $message_id = item_store($datarray);
+ $datarray["object-type"] = ACTIVITY_OBJ_NOTE;
+ $datarray["object"] = self::construct_like_object($importer, $parent_item);
+
+ $datarray["body"] = self::construct_like_body($contact, $parent_item, $guid);
+
+ $message_id = item_store($datarray);
+ //print_r($datarray);
// If we are the origin of the parent we store the original data and notify our followers
if($message_id AND $parent_item["origin"]) {
proc_run("php", "include/notifier.php", "comment-import", $message_id);
}
- return true;
+ return $message_id;
}
private function import_message($importer, $data) {
+ $guid = notags(unxmlify($data->guid));
+ $parent_guid = notags(unxmlify($data->parent_guid));
+ $text = unxmlify($data->text);
+ $created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at)));
+ $author = notags(unxmlify($data->author));
+ $conversation_guid = notags(unxmlify($data->conversation_guid));
+
+ $parent_uri = $author.":".$parent_guid;
+
+ $contact = self::get_contact_by_handle($importer["uid"], $author);
+ if (!$contact) {
+ logger("cannot find contact: ".$author);
+ return false;
+ }
+
+ if(($contact["rel"] == CONTACT_IS_FOLLOWER) || ($contact["blocked"]) || ($contact["readonly"])) {
+ logger("Ignoring this author.");
+ return false;
+ }
+
+ $conversation = null;
+
+ $c = q("SELECT * FROM `conv` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
+ intval($importer["uid"]),
+ dbesc($conversation_guid)
+ );
+ if(count($c))
+ $conversation = $c[0];
+ else {
+ logger("conversation not available.");
+ return false;
+ }
+
+ $reply = 0;
+
+ $body = diaspora2bb($text);
+ $message_id = $author.":".$guid;
+
+ $person = self::get_person_by_handle($author);
+ if (!$person) {
+ logger("unable to find author details");
+ return false;
+ }
+
+ $r = q("SELECT `id` FROM `mail` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+ dbesc($message_id),
+ intval($importer["uid"])
+ );
+ if(count($r)) {
+ logger("duplicate message already delivered.", LOGGER_DEBUG);
+ return false;
+ }
+
+ 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"]),
+ dbesc($guid),
+ intval($conversation["id"]),
+ dbesc($person["name"]),
+ dbesc($person["photo"]),
+ dbesc($person["url"]),
+ intval($contact["id"]),
+ dbesc($conversation["subject"]),
+ dbesc($body),
+ 0,
+ 1,
+ dbesc($message_id),
+ dbesc($parent_uri),
+ dbesc($created_at)
+ );
+
+ q("UPDATE `conv` SET `updated` = '%s' WHERE `id` = %d",
+ dbesc(datetime_convert()),
+ intval($conversation["id"])
+ );
+
return true;
}
}
private function import_profile($importer, $data) {
+ $author = notags(unxmlify($data->author));
+
+ $contact = self::get_contact_by_handle($importer["uid"], $author);
+ if (!$contact)
+ return;
+
+ $name = unxmlify($data->first_name).((strlen($data->last_name)) ? " ".unxmlify($data->last_name) : "");
+ $image_url = unxmlify($data->image_url);
+ $birthday = unxmlify($data->birthday);
+ $location = diaspora2bb(unxmlify($data->location));
+ $about = diaspora2bb(unxmlify($data->bio));
+ $gender = unxmlify($data->gender);
+ $searchable = (unxmlify($data->searchable) == "true");
+ $nsfw = (unxmlify($data->nsfw) == "true");
+ $tags = unxmlify($data->tag_string);
+
+ $tags = explode("#", $tags);
+
+ $keywords = array();
+ foreach ($tags as $tag) {
+ $tag = trim(strtolower($tag));
+ if ($tag != "")
+ $keywords[] = $tag;
+ }
+
+ $keywords = implode(", ", $keywords);
+
+ $handle_parts = explode("@", $author);
+ $nick = $handle_parts[0];
+
+ if($name === "")
+ $name = $handle_parts[0];
+
+ if( preg_match("|^https?://|", $image_url) === 0)
+ $image_url = "http://".$handle_parts[1].$image_url;
+
+ update_contact_avatar($image_url, $importer["uid"], $contact["id"]);
+
+ // Generic birthday. We don't know the timezone. The year is irrelevant.
+
+ $birthday = str_replace("1000", "1901", $birthday);
+
+ if ($birthday != "")
+ $birthday = datetime_convert("UTC", "UTC", $birthday, "Y-m-d");
+
+ // this is to prevent multiple birthday notifications in a single year
+ // if we already have a stored birthday and the 'm-d' part hasn't changed, preserve the entry, which will preserve the notify year
+
+ if(substr($birthday,5) === substr($contact["bd"],5))
+ $birthday = $contact["bd"];
+
+ $r = q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `addr` = '%s', `name-date` = '%s', `bd` = '%s',
+ `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s' WHERE `id` = %d AND `uid` = %d",
+ dbesc($name),
+ dbesc($nick),
+ dbesc($author),
+ dbesc(datetime_convert()),
+ dbesc($birthday),
+ dbesc($location),
+ dbesc($about),
+ dbesc($keywords),
+ dbesc($gender),
+ intval($contact["id"]),
+ intval($importer["uid"])
+ );
+
+ if ($searchable) {
+ poco_check($contact["url"], $name, NETWORK_DIASPORA, $image_url, $about, $location, $gender, $keywords, "",
+ datetime_convert(), 2, $contact["id"], $importer["uid"]);
+ }
+
+ $gcontact = array("url" => $contact["url"], "network" => NETWORK_DIASPORA, "generation" => 2,
+ "photo" => $image_url, "name" => $name, "location" => $location,
+ "about" => $about, "birthday" => $birthday, "gender" => $gender,
+ "addr" => $author, "nick" => $nick, "keywords" => $keywords,
+ "hide" => !$searchable, "nsfw" => $nsfw);
+
+ update_gcontact($gcontact);
+
return true;
}
private function import_request($importer, $data) {
+print_r($data);
+/*
+ $author = unxmlify($xml->author);
+ $recipient = unxmlify($xml->recipient);
+
+ if (!$author || !$recipient)
+ return;
+
+ $contact = self::get_contact_by_handle($importer["uid"],$author);
+
+ if($contact) {
+
+ // perhaps we were already sharing with this person. Now they're sharing with us.
+ // That makes us friends.
+
+ if($contact["rel"] == CONTACT_IS_FOLLOWER && in_array($importer["page-flags"], array(PAGE_FREELOVE))) {
+ q("UPDATE `contact` SET `rel` = %d, `writable` = 1 WHERE `id` = %d AND `uid` = %d",
+ intval(CONTACT_IS_FRIEND),
+ intval($contact["id"]),
+ intval($importer["uid"])
+ );
+ }
+ // send notification
+
+ $r = q("SELECT `hide-friends` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1",
+ intval($importer["uid"])
+ );
+
+ if((count($r)) && (!$r[0]["hide-friends"]) && (!$contact["hidden"]) && intval(get_pconfig($importer["uid"],'system','post_newfriend'))) {
+ require_once('include/items.php');
+
+ $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
+ intval($importer["uid"])
+ );
+
+ // they are not CONTACT_IS_FOLLOWER anymore but that's what we have in the array
+
+ if(count($self) && $contact["rel"] == CONTACT_IS_FOLLOWER) {
+
+ $arr = array();
+ $arr["uri"] = $arr["parent-uri"] = item_new_uri($a->get_hostname(), $importer["uid"]);
+ $arr["uid"] = $importer["uid"];
+ $arr["contact-id"] = $self[0]["id"];
+ $arr["wall"] = 1;
+ $arr["type"] = 'wall';
+ $arr["gravity"] = 0;
+ $arr["origin"] = 1;
+ $arr["author-name"] = $arr["owner-name"] = $self[0]["name"];
+ $arr["author-link"] = $arr["owner-link"] = $self[0]["url"];
+ $arr["author-avatar"] = $arr["owner-avatar"] = $self[0]["thumb"];
+ $arr["verb"] = ACTIVITY_FRIEND;
+ $arr["object-type"] = ACTIVITY_OBJ_PERSON;
+
+ $A = '[url=' . $self[0]["url"] . "]' . $self[0]["name"] . '[/url]';
+ $B = '[url=' . $contact["url"] . "]' . $contact["name"] . '[/url]';
+ $BPhoto = '[url=' . $contact["url"] . "]' . '[img]' . $contact["thumb"] . '[/img][/url]';
+ $arr["body"] = sprintf( t('%1$s is now friends with %2$s'), $A, $B)."\n\n\n".$Bphoto;
+
+ $arr["object"] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $contact["name"] . '</title>'
+ . '<id>' . $contact["url"] . '/' . $contact["name"] . '</id>';
+ $arr["object"] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $contact["url"] . '" />' . "\n")
+;
+ $arr["object"] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $contact["thumb"] . '" />' . "\n");
+ $arr["object"] .= '</link></object>' . "\n";
+ $arr["last-child"] = 1;
+
+ $arr["allow_cid"] = $user[0]["allow_cid"];
+ $arr["allow_gid"] = $user[0]["allow_gid"];
+ $arr["deny_cid"] = $user[0]["deny_cid"];
+ $arr["deny_gid"] = $user[0]["deny_gid"];
+
+ $i = item_store($arr);
+ if($i)
+ proc_run('php',"include/notifier.php","activity","$i");
+
+ }
+
+ }
+
+ return;
+ }
+
+ $ret = self::get_person_by_handle($author);
+
+
+ if((! count($ret)) || ($ret["network"] != NETWORK_DIASPORA)) {
+ logger('diaspora_request: Cannot resolve diaspora handle ' . $author . ' for ' . $recipient);
+ return;
+ }
+
+ $batch = (($ret["batch"]) ? $ret["batch"] : implode('/', array_slice(explode('/',$ret["url"]),0,3)) . '/receive/public');
+
+
+
+ $r = q("INSERT INTO `contact` (`uid`, `network`,`addr`,`created`,`url`,`nurl`,`batch`,`name`,`nick`,`photo`,`pubkey`,`notify`,`poll`,`blocked`,`priority`)
+ VALUES ( %d, '%s', '%s', '%s', '%s','%s','%s','%s','%s','%s','%s','%s','%s',%d,%d) ",
+ intval($importer["uid"]),
+ dbesc($ret["network"]),
+ dbesc($ret["addr"]),
+ datetime_convert(),
+ dbesc($ret["url"]),
+ dbesc(normalise_link($ret["url"])),
+ dbesc($batch),
+ dbesc($ret["name"]),
+ dbesc($ret["nick"]),
+ dbesc($ret["photo"]),
+ dbesc($ret["pubkey"]),
+ dbesc($ret["notify"]),
+ dbesc($ret["poll"]),
+ 1,
+ 2
+ );
+
+ // find the contact record we just created
+
+ $contact_record = diaspora_get_contact_by_handle($importer["uid"],$author);
+
+ if(! $contact_record) {
+ logger('diaspora_request: unable to locate newly created contact record.');
+ return;
+ }
+
+ $g = q("select def_gid from user where uid = %d limit 1",
+ intval($importer["uid"])
+ );
+ if($g && intval($g[0]["def_gid"])) {
+ require_once('include/group.php');
+ group_add_member($importer["uid"],'',$contact_record["id"],$g[0]["def_gid"]);
+ }
+
+ if($importer["page-flags"] == PAGE_NORMAL) {
+
+ $hash = random_string() . (string) time(); // Generate a confirm_key
+
+ $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime` )
+ VALUES ( %d, %d, %d, %d, '%s', '%s', '%s' )",
+ intval($importer["uid"]),
+ intval($contact_record["id"]),
+ 0,
+ 0,
+ dbesc( t('Sharing notification from Diaspora network')),
+ dbesc($hash),
+ dbesc(datetime_convert())
+ );
+ }
+ else {
+
+ // automatic friend approval
+
+ require_once('include/Photo.php');
+
+ update_contact_avatar($contact_record["photo"],$importer["uid"],$contact_record["id"]);
+
+ // technically they are sharing with us (CONTACT_IS_SHARING),
+ // but if our page-type is PAGE_COMMUNITY or PAGE_SOAPBOX
+ // we are going to change the relationship and make them a follower.
+
+ if($importer["page-flags"] == PAGE_FREELOVE)
+ $new_relation = CONTACT_IS_FRIEND;
+ else
+ $new_relation = CONTACT_IS_FOLLOWER;
+
+ $r = q("UPDATE `contact` SET `rel` = %d,
+ `name-date` = '%s',
+ `uri-date` = '%s',
+ `blocked` = 0,
+ `pending` = 0,
+ `writable` = 1
+ WHERE `id` = %d
+ ",
+ intval($new_relation),
+ dbesc(datetime_convert()),
+ dbesc(datetime_convert()),
+ intval($contact_record["id"])
+ );
+
+ $u = q("select * from user where uid = %d limit 1",intval($importer["uid"]));
+ if($u)
+ $ret = diaspora_share($u[0],$contact_record);
+ }
+*/
return true;
}
private function import_reshare($importer, $data) {
+/*
+ $guid = notags(unxmlify($xml->guid));
+ $author = notags(unxmlify($xml->author));
+
+
+ if($author != $msg["author"]) {
+ logger('diaspora_post: Potential forgery. Message handle is not the same as envelope sender.');
+ return 202;
+ }
+
+ $contact = diaspora_get_contact_by_handle($importer["uid"],$author);
+ if(! $contact)
+ return;
+
+ if(! diaspora_post_allow($importer,$contact, false)) {
+ logger('diaspora_reshare: Ignoring this author: ' . $author . ' ' . print_r($xml,true));
+ return 202;
+ }
+
+ $message_id = $author . ':' . $guid;
+ $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
+ intval($importer["uid"]),
+ dbesc($guid)
+ );
+ if(count($r)) {
+ logger('diaspora_reshare: message exists: ' . $guid);
+ return;
+ }
+
+ $orig_author = notags(unxmlify($xml->root_diaspora_id));
+ $orig_guid = notags(unxmlify($xml->root_guid));
+ $orig_url = $a->get_baseurl()."/display/".$orig_guid;
+
+ $create_original_post = false;
+
+ // Do we already have this item?
+ $r = q("SELECT `body`, `tag`, `app`, `created`, `plink`, `object`, `object-type`, `uri` FROM `item` WHERE `guid` = '%s' AND `visible` AND NOT
+`deleted` AND `body` != '' LIMIT 1",
+ dbesc($orig_guid),
+ dbesc(NETWORK_DIASPORA)
+ );
+ if(count($r)) {
+ logger('reshared message '.$orig_guid." reshared by ".$guid.' already exists on system.');
+
+ // Maybe it is already a reshared item?
+ // Then refetch the content, since there can be many side effects with reshared posts from other networks or reshares from reshares
+ require_once('include/api.php');
+ if (api_share_as_retweet($r[0]))
+ $r = array();
+ else {
+ $body = $r[0]["body"];
+ $str_tags = $r[0]["tag"];
+ $app = $r[0]["app"];
+ $orig_created = $r[0]["created"];
+ $orig_plink = $r[0]["plink"];
+ $orig_uri = $r[0]["uri"];
+ $object = $r[0]["object"];
+ $objecttype = $r[0]["object-type"];
+ }
+ }
+
+ if (!count($r)) {
+ $body = "";
+ $str_tags = "";
+ $app = "";
+
+ $server = 'https://'.substr($orig_author,strpos($orig_author,'@')+1);
+ logger('1st try: reshared message '.$orig_guid." reshared by ".$guid.' will be fetched from original server: '.$server);
+ $item = diaspora_fetch_message($orig_guid, $server);
+
+ if (!$item) {
+ $server = 'https://'.substr($author,strpos($author,'@')+1);
+ logger('2nd try: reshared message '.$orig_guid." reshared by ".$guid." will be fetched from sharer's server: ".$server);
+ $item = diaspora_fetch_message($orig_guid, $server);
+ }
+ if (!$item) {
+ $server = 'http://'.substr($orig_author,strpos($orig_author,'@')+1);
+ logger('3rd try: reshared message '.$orig_guid." reshared by ".$guid.' will be fetched from original server: '.$server);
+ $item = diaspora_fetch_message($orig_guid, $server);
+ }
+ if (!$item) {
+ $server = 'http://'.substr($author,strpos($author,'@')+1);
+ logger('4th try: reshared message '.$orig_guid." reshared by ".$guid." will be fetched from sharer's server: ".$server);
+ $item = diaspora_fetch_message($orig_guid, $server);
+ }
+
+ if ($item) {
+ $body = $item["body"];
+ $str_tags = $item["tag"];
+ $app = $item["app"];
+ $orig_created = $item["created"];
+ $orig_author = $item["author"];
+ $orig_guid = $item["guid"];
+ $orig_plink = diaspora_plink($orig_author, $orig_guid);
+ $orig_uri = $orig_author.':'.$orig_guid;
+ $create_original_post = ($body != "");
+ $object = $item["object"];
+ $objecttype = $item["object-type"];
+ }
+ }
+
+ $plink = diaspora_plink($author, $guid);
+
+ $person = find_diaspora_person_by_handle($orig_author);
+
+ $created = unxmlify($xml->created_at);
+ $private = ((unxmlify($xml->public) == 'false') ? 1 : 0);
+
+ $datarray = array();
+
+ $datarray["uid"] = $importer["uid"];
+ $datarray["contact-id"] = $contact["id"];
+ $datarray["wall"] = 0;
+ $datarray["network"] = NETWORK_DIASPORA;
+ $datarray["guid"] = $guid;
+ $datarray["uri"] = $datarray["parent-uri"] = $message_id;
+ $datarray["changed"] = $datarray["created"] = $datarray["edited"] = datetime_convert('UTC','UTC',$created);
+ $datarray["private"] = $private;
+ $datarray["parent"] = 0;
+ $datarray["plink"] = $plink;
+ $datarray["owner-name"] = $contact["name"];
+ $datarray["owner-link"] = $contact["url"];
+ $datarray["owner-avatar"] = ((x($contact,'thumb')) ? $contact["thumb"] : $contact["photo"]);
+ $prefix = share_header($person["name"], $person["url"], ((x($person,'thumb')) ? $person["thumb"] : $person["photo"]), $orig_guid, $orig_created, $orig_url);
+
+ $datarray["author-name"] = $contact["name"];
+ $datarray["author-link"] = $contact["url"];
+ $datarray["author-avatar"] = $contact["thumb"];
+ $datarray["body"] = $prefix.$body."[/share]";
+
+ $datarray["object"] = json_encode($xml);
+ $datarray["object-type"] = $objecttype;
+
+ $datarray["tag"] = $str_tags;
+ $datarray["app"] = $app;
+
+ // if empty content it might be a photo that hasn't arrived yet. If a photo arrives, we'll make it visible. (testing)
+ $datarray["visible"] = ((strlen($body)) ? 1 : 0);
+
+ // Store the original item of a reshare
+ if ($create_original_post) {
+ require_once("include/Contact.php");
+
+ $datarray2 = $datarray;
+
+ $datarray2["uid"] = 0;
+ $datarray2["contact-id"] = get_contact($person["url"], 0);
+ $datarray2["guid"] = $orig_guid;
+ $datarray2["uri"] = $datarray2["parent-uri"] = $orig_uri;
+ $datarray2["changed"] = $datarray2["created"] = $datarray2["edited"] = $datarray2["commented"] = $datarray2["received"] = datetime_convert('UTC','UTC',$orig_created);
+ $datarray2["parent"] = 0;
+ $datarray2["plink"] = $orig_plink;
+
+ $datarray2["author-name"] = $person["name"];
+ $datarray2["author-link"] = $person["url"];
+ $datarray2["author-avatar"] = ((x($person,'thumb')) ? $person["thumb"] : $person["photo"]);
+ $datarray2["owner-name"] = $datarray2["author-name"];
+ $datarray2["owner-link"] = $datarray2["author-link"];
+ $datarray2["owner-avatar"] = $datarray2["author-avatar"];
+ $datarray2["body"] = $body;
+ $datarray2["object"] = $object;
+
+ DiasporaFetchGuid($datarray2);
+ $message_id = item_store($datarray2);
+
+ logger("Store original item ".$orig_guid." under message id ".$message_id);
+ }
+
+ DiasporaFetchGuid($datarray);
+ $message_id = item_store($datarray);
+*/
return true;
}
return true;
}
- private function import_status_message($importer, $data) {
- return true;
+ private function import_status_message($importer, $data, $msg, $data2) {
+
+ $raw_message = unxmlify($data->raw_message);
+ $guid = notags(unxmlify($data->guid));
+ $author = notags(unxmlify($data->author));
+ $public = notags(unxmlify($data->public));
+ $created_at = notags(unxmlify($data->created_at));
+ $provider_display_name = notags(unxmlify($data->provider_display_name));
+
+ foreach ($data->children() AS $name => $entry)
+ if (count($entry->children()))
+ if (!in_array($name, array("location", "photo", "poll")))
+ die("Kinder: ".$name."\n");
+/*
+ if ($data->location) {
+ print_r($location);
+ foreach ($data->location->children() AS $fieldname => $data)
+ echo $fieldname." - ".$data."\n";
+ die("Location!\n");
+ }
+*/
+/*
+ if ($data->photo) {
+ print_r($data->photo);
+ foreach ($data->photo->children() AS $fieldname => $data)
+ echo $fieldname." - ".$data."\n";
+ die("Photo!\n");
+ }
+*/
+
+ if ($data->poll) {
+ print_r($data2);
+ print_r($data);
+ die("poll!\n");
+ }
+
+
+ $contact = self::get_contact_by_handle($importer["uid"], $author);
+ if (!$contact) {
+ logger("A Contact for handle ".$author." and user ".$importer["uid"]." was not found");
+ return false;
+ }
+
+ if (!self::post_allow($importer, $contact, false)) {
+ logger("Ignoring this author.");
+ return false;
+ }
+/*
+ $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
+ intval($importer["uid"]),
+ dbesc($guid)
+ );
+ if(count($r)) {
+ logger("message exists: ".$guid);
+ return false;
+ }
+*/
+ $private = (($public == "false") ? 1 : 0);
+
+ $body = diaspora2bb($raw_message);
+
+ $datarray = array();
+
+ if($data->photo->remote_photo_path AND $data->photo->remote_photo_name)
+ $datarray["object-type"] = ACTIVITY_OBJ_PHOTO;
+ else {
+ $datarray["object-type"] = ACTIVITY_OBJ_NOTE;
+ // Add OEmbed and other information to the body
+ if (!self::is_redmatrix($contact["url"]))
+ $body = add_page_info_to_body($body, false, true);
+ }
+
+ $str_tags = "";
+
+ $cnt = preg_match_all("/@\[url=(.*?)\[\/url\]/ism", $body, $matches, PREG_SET_ORDER);
+ if($cnt) {
+ foreach($matches as $mtch) {
+ if(strlen($str_tags))
+ $str_tags .= ",";
+ $str_tags .= "@[url=".$mtch[1]."[/url]";
+ }
+ }
+ $plink = self::plink($author, $guid);
+
+ $datarray["uid"] = $importer["uid"];
+ $datarray["contact-id"] = $contact["id"];
+ $datarray["network"] = NETWORK_DIASPORA;
+
+ $datarray["author-name"] = $contact["name"];
+ $datarray["author-link"] = $contact["url"];
+ $datarray["author-avatar"] = ((x($contact,"thumb")) ? $contact["thumb"] : $contact["photo"]);
+
+ $datarray["owner-name"] = $datarray["author-name"];
+ $datarray["owner-link"] = $datarray["author-link"];
+ $datarray["owner-avatar"] = $datarray["author-avatar"];
+
+ $datarray["guid"] = $guid;
+ $datarray["uri"] = $datarray["parent-uri"] = $author.":".$guid;
+
+ $datarray["verb"] = ACTIVITY_POST;
+ $datarray["gravity"] = GRAVITY_PARENT;
+
+ $datarray["object"] = json_encode($data);
+
+ $datarray["body"] = $body;
+
+ $datarray["tag"] = $str_tags;
+ if ($provider_display_name != "")
+ $datarray["app"] = $provider_display_name;
+
+ $datarray["plink"] = $plink;
+ $datarray["private"] = $private;
+ $datarray["changed"] = $datarray["created"] = $datarray["edited"] = datetime_convert("UTC", "UTC", $created_at);
+
+ // if empty content it might be a photo that hasn't arrived yet. If a photo arrives, we'll make it visible.
+
+ $datarray["visible"] = ((strlen($body)) ? 1 : 0);
+
+ self::fetch_guid($datarray);
+ //$message_id = item_store($datarray);
+ print_r($datarray);
+
+ logger("Stored item with message id ".$message_id, LOGGER_DEBUG);
+
+ return $message_id;
}
}
?>