Retractions could work now.
This commit is contained in:
parent
5adecf5b50
commit
2edf4548dc
1 changed files with 105 additions and 65 deletions
|
@ -13,6 +13,10 @@ require_once("include/socgraph.php");
|
||||||
require_once("include/group.php");
|
require_once("include/group.php");
|
||||||
require_once("include/api.php");
|
require_once("include/api.php");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This class contain functions to work with XML data
|
||||||
|
*
|
||||||
|
*/
|
||||||
class xml {
|
class xml {
|
||||||
function from_array($array, &$xml) {
|
function from_array($array, &$xml) {
|
||||||
|
|
||||||
|
@ -45,12 +49,20 @@ class xml {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class contain functions to create and send Diaspora XML files
|
* @brief This class contain functions to create and send Diaspora XML files
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class diaspora {
|
class diaspora {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dispatches public messages and find the fitting receivers
|
||||||
|
*
|
||||||
|
* @param array $msg The post that will be dispatched
|
||||||
|
*
|
||||||
|
* @return bool Was the message accepted?
|
||||||
|
*/
|
||||||
public static function dispatch_public($msg) {
|
public static function dispatch_public($msg) {
|
||||||
|
|
||||||
$enabled = intval(get_config("system", "diaspora_enabled"));
|
$enabled = intval(get_config("system", "diaspora_enabled"));
|
||||||
|
@ -81,6 +93,14 @@ class diaspora {
|
||||||
return $item_id;
|
return $item_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dispatches the different message types to the different functions
|
||||||
|
*
|
||||||
|
* @param array $importer Array of the importer user
|
||||||
|
* @param array $msg The post that will be dispatched
|
||||||
|
*
|
||||||
|
* @return bool Was the message accepted?
|
||||||
|
*/
|
||||||
public static function dispatch($importer, $msg) {
|
public static function dispatch($importer, $msg) {
|
||||||
|
|
||||||
// The sender is the handle of the contact that sent the message.
|
// The sender is the handle of the contact that sent the message.
|
||||||
|
@ -104,8 +124,8 @@ class diaspora {
|
||||||
//return self::import_comment($importer, $sender, $fields);
|
//return self::import_comment($importer, $sender, $fields);
|
||||||
|
|
||||||
case "conversation":
|
case "conversation":
|
||||||
return true;
|
//return true;
|
||||||
//return self::import_conversation($importer, $fields);
|
return self::import_conversation($importer, $fields);
|
||||||
|
|
||||||
case "like": // Done
|
case "like": // Done
|
||||||
return true;
|
return true;
|
||||||
|
@ -129,18 +149,20 @@ class diaspora {
|
||||||
//return self::import_profile($importer, $fields);
|
//return self::import_profile($importer, $fields);
|
||||||
|
|
||||||
case "request":
|
case "request":
|
||||||
|
//return true;
|
||||||
return self::import_request($importer, $fields);
|
return self::import_request($importer, $fields);
|
||||||
|
|
||||||
case "reshare": // Done
|
case "reshare": // Done
|
||||||
return true;
|
return true;
|
||||||
//return self::import_reshare($importer, $fields);
|
//return self::import_reshare($importer, $fields);
|
||||||
|
|
||||||
case "retraction":
|
case "retraction": // Done
|
||||||
return self::import_retraction($importer, $fields);
|
|
||||||
|
|
||||||
case "status_message": // Done
|
|
||||||
return true;
|
return true;
|
||||||
//return self::import_status_message($importer, $fields);
|
//return self::import_retraction($importer, $sender, $fields);
|
||||||
|
|
||||||
|
case "status_message":
|
||||||
|
//return true;
|
||||||
|
return self::import_status_message($importer, $fields);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logger("Unknown message type ".$type);
|
logger("Unknown message type ".$type);
|
||||||
|
@ -181,6 +203,7 @@ class diaspora {
|
||||||
}
|
}
|
||||||
|
|
||||||
$type = $element->getName();
|
$type = $element->getName();
|
||||||
|
$orig_type = $type;
|
||||||
|
|
||||||
// All retractions are handled identically from now on.
|
// All retractions are handled identically from now on.
|
||||||
// In the new version there will only be "retraction".
|
// In the new version there will only be "retraction".
|
||||||
|
@ -235,7 +258,8 @@ class diaspora {
|
||||||
|
|
||||||
$signed_data .= $entry;
|
$signed_data .= $entry;
|
||||||
}
|
}
|
||||||
if (!in_array($fieldname, array("parent_author_signature", "target_author_signature")))
|
if (!in_array($fieldname, array("parent_author_signature", "target_author_signature")) OR
|
||||||
|
($orig_type == "relayable_retraction"))
|
||||||
xml::copy($entry, $fields, $fieldname);
|
xml::copy($entry, $fields, $fieldname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,6 +290,13 @@ class diaspora {
|
||||||
return rsa_verify($signed_data, $author_signature, $key, "sha256");
|
return rsa_verify($signed_data, $author_signature, $key, "sha256");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fetches the public key for a given handle
|
||||||
|
*
|
||||||
|
* @param string $handle The handle
|
||||||
|
*
|
||||||
|
* @return string The public key
|
||||||
|
*/
|
||||||
private function get_key($handle) {
|
private function get_key($handle) {
|
||||||
logger("Fetching diaspora key for: ".$handle);
|
logger("Fetching diaspora key for: ".$handle);
|
||||||
|
|
||||||
|
@ -276,6 +307,13 @@ class diaspora {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fetches data for a given handle
|
||||||
|
*
|
||||||
|
* @param string $handle The handle
|
||||||
|
*
|
||||||
|
* @return array the queried data
|
||||||
|
*/
|
||||||
private function get_person_by_handle($handle) {
|
private function get_person_by_handle($handle) {
|
||||||
|
|
||||||
$r = q("SELECT * FROM `fcontact` WHERE `network` = '%s' AND `addr` = '%s' LIMIT 1",
|
$r = q("SELECT * FROM `fcontact` WHERE `network` = '%s' AND `addr` = '%s' LIMIT 1",
|
||||||
|
@ -306,6 +344,14 @@ class diaspora {
|
||||||
return $person;
|
return $person;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Updates the fcontact table
|
||||||
|
*
|
||||||
|
* @param array $arr The fcontact data
|
||||||
|
* @param bool $update Update or insert?
|
||||||
|
*
|
||||||
|
* @return string The id of the fcontact entry
|
||||||
|
*/
|
||||||
private function add_fcontact($arr, $update = false) {
|
private function add_fcontact($arr, $update = false) {
|
||||||
/// @todo Remove this function from include/network.php
|
/// @todo Remove this function from include/network.php
|
||||||
|
|
||||||
|
@ -477,13 +523,12 @@ class diaspora {
|
||||||
if ($level > 5)
|
if ($level > 5)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// This will not work if the server is not a Diaspora server
|
// This will work for Diaspora and newer Friendica servers
|
||||||
$source_url = $server."/p/".$guid.".xml";
|
$source_url = $server."/p/".$guid.".xml";
|
||||||
$x = fetch_url($source_url);
|
$x = fetch_url($source_url);
|
||||||
if(!$x)
|
if(!$x)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/// @todo - should maybe solved by the dispatcher
|
|
||||||
$source_xml = parse_xml_string($x, false);
|
$source_xml = parse_xml_string($x, false);
|
||||||
|
|
||||||
if (!is_object($source_xml))
|
if (!is_object($source_xml))
|
||||||
|
@ -664,7 +709,7 @@ class diaspora {
|
||||||
if($message_id AND $parent_item["origin"]) {
|
if($message_id AND $parent_item["origin"]) {
|
||||||
|
|
||||||
// Formerly we stored the signed text, the signature and the author in different fields.
|
// Formerly we stored the signed text, the signature and the author in different fields.
|
||||||
// The new Diaspora protocol can have variable fields. We now store the data in correct order in a single field.
|
// We now store the raw data so that we are more flexible.
|
||||||
q("INSERT INTO `sign` (`iid`,`signed_text`) VALUES (%d,'%s')",
|
q("INSERT INTO `sign` (`iid`,`signed_text`) VALUES (%d,'%s')",
|
||||||
intval($message_id),
|
intval($message_id),
|
||||||
dbesc(json_encode($data))
|
dbesc(json_encode($data))
|
||||||
|
@ -678,6 +723,7 @@ class diaspora {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function import_conversation($importer, $data) {
|
private function import_conversation($importer, $data) {
|
||||||
|
// @todo
|
||||||
print_r($data);
|
print_r($data);
|
||||||
die();
|
die();
|
||||||
/*
|
/*
|
||||||
|
@ -934,13 +980,13 @@ EOT;
|
||||||
$datarray["body"] = self::construct_like_body($contact, $parent_item, $guid);
|
$datarray["body"] = self::construct_like_body($contact, $parent_item, $guid);
|
||||||
|
|
||||||
$message_id = item_store($datarray);
|
$message_id = item_store($datarray);
|
||||||
//print_r($datarray);
|
// print_r($datarray);
|
||||||
|
|
||||||
// If we are the origin of the parent we store the original data and notify our followers
|
// If we are the origin of the parent we store the original data and notify our followers
|
||||||
if($message_id AND $parent_item["origin"]) {
|
if($message_id AND $parent_item["origin"]) {
|
||||||
|
|
||||||
// Formerly we stored the signed text, the signature and the author in different fields.
|
// Formerly we stored the signed text, the signature and the author in different fields.
|
||||||
// The new Diaspora protocol can have variable fields. We now store the data in correct order in a single field.
|
// We now store the raw data so that we are more flexible.
|
||||||
q("INSERT INTO `sign` (`iid`,`signed_text`) VALUES (%d,'%s')",
|
q("INSERT INTO `sign` (`iid`,`signed_text`) VALUES (%d,'%s')",
|
||||||
intval($message_id),
|
intval($message_id),
|
||||||
dbesc(json_encode($data))
|
dbesc(json_encode($data))
|
||||||
|
@ -1125,7 +1171,8 @@ EOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function import_request($importer, $data) {
|
private function import_request($importer, $data) {
|
||||||
print_r($data);
|
// @todo
|
||||||
|
print_r($data);
|
||||||
/*
|
/*
|
||||||
$author = unxmlify($xml->author);
|
$author = unxmlify($xml->author);
|
||||||
$recipient = unxmlify($xml->recipient);
|
$recipient = unxmlify($xml->recipient);
|
||||||
|
@ -1371,8 +1418,8 @@ print_r($data);
|
||||||
if (!$contact)
|
if (!$contact)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// if (self::message_exists($importer["uid"], $guid))
|
if (self::message_exists($importer["uid"], $guid))
|
||||||
// return false;
|
return false;
|
||||||
|
|
||||||
$original_item = self::get_original_item($root_guid, $root_author, $author);
|
$original_item = self::get_original_item($root_guid, $root_author, $author);
|
||||||
if (!$original_item)
|
if (!$original_item)
|
||||||
|
@ -1414,14 +1461,22 @@ print_r($data);
|
||||||
$datarray["object-type"] = $original_item["object-type"];
|
$datarray["object-type"] = $original_item["object-type"];
|
||||||
|
|
||||||
self::fetch_guid($datarray);
|
self::fetch_guid($datarray);
|
||||||
//$message_id = item_store($datarray);
|
$message_id = item_store($datarray);
|
||||||
print_r($datarray);
|
// print_r($datarray);
|
||||||
|
|
||||||
return $message_id;
|
return $message_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function item_retraction($importer, $contact, $data) {
|
private function item_retraction($importer, $contact, $data) {
|
||||||
|
$target_type = notags(unxmlify($data->target_type));
|
||||||
$target_guid = notags(unxmlify($data->target_guid));
|
$target_guid = notags(unxmlify($data->target_guid));
|
||||||
|
$author = notags(unxmlify($data->author));
|
||||||
|
|
||||||
|
$person = self::get_person_by_handle($author);
|
||||||
|
if (!is_array($person)) {
|
||||||
|
logger("unable to find author detail for ".$author);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$r = q("SELECT `id`, `parent`, `parent-uri`, `author-link` FROM `item` WHERE `guid` = '%s' AND `uid` = %d AND NOT `file` LIKE '%%[%%' LIMIT 1",
|
$r = q("SELECT `id`, `parent`, `parent-uri`, `author-link` FROM `item` WHERE `guid` = '%s' AND `uid` = %d AND NOT `file` LIKE '%%[%%' LIMIT 1",
|
||||||
dbesc($target_guid),
|
dbesc($target_guid),
|
||||||
|
@ -1431,7 +1486,15 @@ print_r($data);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Only delete it if the author really fits
|
// Only delete it if the author really fits
|
||||||
if (!link_compare($r[0]["author-link"],$contact["url"]))
|
if (!link_compare($r[0]["author-link"],$person["url"]))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if the sender is the thread owner
|
||||||
|
$p = q("SELECT `author-link`, `origin` FROM `item` WHERE `id` = %d",
|
||||||
|
intval($r[0]["parent"]));
|
||||||
|
|
||||||
|
// Only delete it if the parent author really fits
|
||||||
|
if (!link_compare($p[0]["author-link"], $contact["url"]))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Currently we don't have a central deletion function that we could use in this case. The function "item_drop" doesn't work for that case
|
// Currently we don't have a central deletion function that we could use in this case. The function "item_drop" doesn't work for that case
|
||||||
|
@ -1443,47 +1506,36 @@ print_r($data);
|
||||||
delete_thread($r[0]["id"], $r[0]["parent-uri"]);
|
delete_thread($r[0]["id"], $r[0]["parent-uri"]);
|
||||||
|
|
||||||
// Now check if the retraction needs to be relayed by us
|
// Now check if the retraction needs to be relayed by us
|
||||||
//
|
if($p[0]["origin"]) {
|
||||||
// The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always
|
|
||||||
// return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent.
|
|
||||||
// The only item with `parent` and `id` as the parent id is the parent item.
|
|
||||||
$p = q("SELECT `origin` FROM `item` WHERE `parent` = %d AND `id` = %d LIMIT 1",
|
|
||||||
intval($r[0]["parent"]),
|
|
||||||
intval($r[0]["parent"])
|
|
||||||
);
|
|
||||||
if(count($p)) {
|
|
||||||
if($p[0]["origin"]) {
|
|
||||||
|
|
||||||
// Formerly we stored the signed text, the signature and the author in different fields.
|
// Formerly we stored the signed text, the signature and the author in different fields.
|
||||||
// The new Diaspora protocol can have variable fields. We now store the data in correct order in a single field.
|
// We now store the raw data so that we are more flexible.
|
||||||
q("INSERT INTO `sign` (`iid`,`signed_text`) VALUES (%d,'%s')",
|
q("INSERT INTO `sign` (`iid`,`signed_text`) VALUES (%d,'%s')",
|
||||||
intval($r[0]["id"]),
|
intval($r[0]["id"]),
|
||||||
dbesc(json_encode($data))
|
dbesc(json_encode($data))
|
||||||
);
|
);
|
||||||
|
|
||||||
// the existence of parent_author_signature would have meant the parent_author or owner
|
// notify others
|
||||||
// is already relaying.
|
proc_run("php", "include/notifier.php", "drop", $r[0]["id"]);
|
||||||
logger("relaying retraction");
|
|
||||||
|
|
||||||
proc_run("php", "include/notifier.php", "drop", $r[0]["id"]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function import_retraction($importer, $data) {
|
private function import_retraction($importer, $sender, $data) {
|
||||||
$target_type = notags(unxmlify($data->target_type));
|
$target_type = notags(unxmlify($data->target_type));
|
||||||
$author = notags(unxmlify($data->author));
|
|
||||||
|
|
||||||
$contact = self::get_contact_by_handle($importer["uid"], $author);
|
$contact = self::get_contact_by_handle($importer["uid"], $sender);
|
||||||
if (!$contact) {
|
if (!$contact) {
|
||||||
logger("cannot find contact for author: ".$author);
|
logger("cannot find contact for sender: ".$sender." and user ".$importer["uid"]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($target_type) {
|
switch ($target_type) {
|
||||||
case "Comment": case "Like": case "StatusMessage":
|
case "Comment":
|
||||||
self::item_retraction($importer, $contact, $data);
|
case "Like":
|
||||||
break;
|
case "Post": // "Post" will be supported in a future version
|
||||||
|
case "Reshare":
|
||||||
|
case "StatusMessage":
|
||||||
|
return self::item_retraction($importer, $contact, $data);;
|
||||||
|
|
||||||
case "Person":
|
case "Person":
|
||||||
contact_remove($contact["id"]);
|
contact_remove($contact["id"]);
|
||||||
|
@ -1491,6 +1543,7 @@ print_r($data);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logger("Unknown target type ".$target_type);
|
logger("Unknown target type ".$target_type);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1514,8 +1567,8 @@ print_r($data);
|
||||||
if (!$contact)
|
if (!$contact)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//if (self::message_exists($importer["uid"], $guid))
|
if (self::message_exists($importer["uid"], $guid))
|
||||||
// return false;
|
return false;
|
||||||
|
|
||||||
$address = array();
|
$address = array();
|
||||||
if ($data->location)
|
if ($data->location)
|
||||||
|
@ -1539,18 +1592,6 @@ print_r($data);
|
||||||
$body = add_page_info_to_body($body, false, true);
|
$body = add_page_info_to_body($body, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$str_tags = "";
|
|
||||||
|
|
||||||
// This doesn't work. @todo Check if the "tag" field is filled in the "item_store" function.
|
|
||||||
$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]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$datarray["uid"] = $importer["uid"];
|
$datarray["uid"] = $importer["uid"];
|
||||||
$datarray["contact-id"] = $contact["id"];
|
$datarray["contact-id"] = $contact["id"];
|
||||||
$datarray["network"] = NETWORK_DIASPORA;
|
$datarray["network"] = NETWORK_DIASPORA;
|
||||||
|
@ -1573,7 +1614,6 @@ print_r($data);
|
||||||
|
|
||||||
$datarray["body"] = $body;
|
$datarray["body"] = $body;
|
||||||
|
|
||||||
$datarray["tag"] = $str_tags;
|
|
||||||
if ($provider_display_name != "")
|
if ($provider_display_name != "")
|
||||||
$datarray["app"] = $provider_display_name;
|
$datarray["app"] = $provider_display_name;
|
||||||
|
|
||||||
|
@ -1588,8 +1628,8 @@ print_r($data);
|
||||||
$datarray["coord"] = $address["lat"]." ".$address["lng"];
|
$datarray["coord"] = $address["lat"]." ".$address["lng"];
|
||||||
|
|
||||||
self::fetch_guid($datarray);
|
self::fetch_guid($datarray);
|
||||||
//$message_id = item_store($datarray);
|
$message_id = item_store($datarray);
|
||||||
print_r($datarray);
|
// print_r($datarray);
|
||||||
|
|
||||||
logger("Stored item with message id ".$message_id, LOGGER_DEBUG);
|
logger("Stored item with message id ".$message_id, LOGGER_DEBUG);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue