return $current_post;
}
+ /**
+ * @brief Distributes public items to the receivers
+ *
+ * @param integer $itemid Item ID that should be added
+ */
+ public static function distribute($itemid)
+ {
+ $condition = ["`id` IN (SELECT `parent` FROM `item` WHERE `id` = ?)", $itemid];
+ $parent = dba::selectFirst('item', ['owner-id'], $condition);
+ if (!DBM::is_result($parent)) {
+ return;
+ }
+
+ // Only distribute public items from native networks
+ $condition = ['id' => $itemid, 'uid' => 0,
+ 'network' => [NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""],
+ 'visible' => true, 'deleted' => false, 'moderated' => false, 'private' => false];
+ $item = dba::selectFirst('item', [], ['id' => $itemid]);
+ if (!DBM::is_result($item)) {
+ return;
+ }
+
+ unset($item['id']);
+
+ $condition = ["`nurl` IN (SELECT `nurl` FROM `contact` WHERE `id` = ?) AND `uid` != 0 AND NOT `blocked` AND `rel` IN (?, ?)",
+ $parent['owner-id'], CONTACT_IS_SHARING, CONTACT_IS_FRIEND];
+ $contacts = dba::select('contact', [], $condition);
+ while ($contact = dba::fetch($contacts)) {
+ self::storeForUser($itemid, $item, $contact);
+ }
+ }
+
+ /**
+ * @brief Store public items for the receivers
+ *
+ * @param integer $itemid Item ID that should be added
+ * @param array $item The item entry that will be stored
+ * @param array $contact The contact that will receive the item entry
+ */
+ private static function storeForUser($itemid, $item, $contact)
+ {
+ $item['uid'] = $contact['uid'];
+ $item['origin'] = 0;
+ $item['wall'] = 0;
+ if ($item['uri'] == $item['parent-uri']) {
+ $item['contact-id'] = Contact::getIdForURL($item['owner-link'], $contact['uid']);
+ } else {
+ $item['contact-id'] = Contact::getIdForURL($item['author-link'], $contact['uid']);
+ }
+
+ if (empty($item['contact-id'])) {
+ $self = dba::selectFirst('contact', ['id'], ['self' => true, 'uid' => $contact['uid']]);
+ if (!DBM::is_result($self)) {
+ return;
+ }
+ $item['contact-id'] = $self['id'];
+ }
+
+ if (in_array($item['type'], ["net-comment", "wall-comment"])) {
+ $item['type'] = 'remote-comment';
+ } elseif ($item['type'] == 'wall') {
+ $item['type'] = 'remote';
+ }
+
+ /// @todo Handling of "event-id"
+
+ $distributed = self::insert($item, false, false, true);
+
+ if (!$distributed) {
+ logger("Distributed public item " . $itemid . " for user " . $contact['uid'] . " wasn't stored", LOGGER_DEBUG);
+ } else {
+ logger("Distributed public item " . $itemid . " for user " . $contact['uid'] . " with id " . $distributed, LOGGER_DEBUG);
+ }
+ }
+
/**
* @brief Add a shadow entry for a given item id that is a thread starter
*
*/
public static function addShadow($itemid)
{
- $fields = ['uid', 'wall', 'private', 'moderated', 'visible', 'contact-id', 'deleted', 'network', 'author-id', 'owner-id'];
+ $fields = ['uid', 'private', 'moderated', 'visible', 'deleted', 'network'];
$condition = ['id' => $itemid, 'parent' => [0, $itemid]];
$item = dba::selectFirst('item', $fields, $condition);
return false;
}
- if (!($postdata = self::validPosting($msg))) {
+ if (!($fields = self::validPosting($msg))) {
logger("Invalid posting");
return false;
}
- $fields = $postdata['fields'];
-
- // Is it a an action (comment, like, ...) for our own post?
- if (isset($fields->parent_guid) && !$postdata["relayed"]) {
- $guid = notags(unxmlify($fields->parent_guid));
- $importer = self::importerForGuid($guid);
- if (is_array($importer)) {
- logger("delivering to origin: ".$importer["name"]);
- $message_id = self::dispatch($importer, $msg, $fields);
- return $message_id;
- }
- }
-
- // Process item retractions. This has to be done separated from the other stuff,
- // since retractions for comments could come even from non followers.
- if (!empty($fields) && in_array($fields->getName(), ['retraction'])) {
- $target = notags(unxmlify($fields->target_type));
- if (in_array($target, ["Comment", "Like", "Post", "Reshare", "StatusMessage"])) {
- logger('processing retraction for '.$target, LOGGER_DEBUG);
- $importer = ["uid" => 0, "page-flags" => PAGE_FREELOVE];
- $message_id = self::dispatch($importer, $msg, $fields);
- return $message_id;
- }
- }
-
- // Now distribute it to the followers
- $r = q(
- "SELECT `user`.* FROM `user` WHERE `user`.`uid` IN
- (SELECT `contact`.`uid` FROM `contact` WHERE `contact`.`network` = '%s' AND `contact`.`addr` = '%s')
- AND NOT `account_expired` AND NOT `account_removed`",
- dbesc(NETWORK_DIASPORA),
- dbesc($msg["author"])
- );
-
- if (DBM::is_result($r)) {
- foreach ($r as $rr) {
- logger("delivering to: ".$rr["username"]);
- self::dispatch($rr, $msg, $fields);
- }
- } elseif (!Config::get('system', 'relay_subscribe', false)) {
- logger("Unwanted message from ".$msg["author"]." send by ".$_SERVER["REMOTE_ADDR"]." with ".$_SERVER["HTTP_USER_AGENT"].": ".print_r($msg, true), LOGGER_DEBUG);
- } else {
- // Use a dummy importer to import the data for the public copy
- $importer = ["uid" => 0, "page-flags" => PAGE_FREELOVE];
- $message_id = self::dispatch($importer, $msg, $fields);
- }
+ $importer = ["uid" => 0, "page-flags" => PAGE_FREELOVE];
+ $message_id = self::dispatch($importer, $msg, $fields);
return $message_id;
}
// This is only needed for private postings since this is already done for public ones before
if (is_null($fields)) {
- if (!($postdata = self::validPosting($msg))) {
+ if (!($fields = self::validPosting($msg))) {
logger("Invalid posting");
return false;
}
- $fields = $postdata['fields'];
}
$type = $fields->getName();
// Only some message types have signatures. So we quit here for the other types.
if (!in_array($type, ["comment", "like"])) {
- return ["fields" => $fields, "relayed" => false];
+ return $fields;
}
// No author_signature? This is a must, so we quit.
if (!isset($author_signature)) {
}
if (isset($parent_author_signature)) {
- $relayed = true;
-
$key = self::key($msg["author"]);
if (!Crypto::rsaVerify($signed_data, $parent_author_signature, $key, "sha256")) {
logger("No valid parent author signature for parent author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature, LOGGER_DEBUG);
return false;
}
- } else {
- $relayed = false;
}
$key = self::key($fields->author);
logger("No valid author signature for author ".$fields->author. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature, LOGGER_DEBUG);
return false;
} else {
- return ["fields" => $fields, "relayed" => $relayed];
+ return $fields;
}
}
if ($message_id) {
logger("Stored comment ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
+ if ($datarray['uid'] == 0) {
+ Item::distribute($message_id);
+ }
}
// If we are the origin of the parent we store the original data and notify our followers
if ($message_id) {
logger("Stored like ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
+ if ($datarray['uid'] == 0) {
+ Item::distribute($message_id);
+ }
}
// like on comments have the comment as parent. So we need to fetch the toplevel parent
if ($message_id) {
logger("Stored reshare ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
+ if ($datarray['uid'] == 0) {
+ Item::distribute($message_id);
+ }
return true;
} else {
return false;
if ($message_id) {
logger("Stored item ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
+ if ($datarray['uid'] == 0) {
+ Item::distribute($message_id);
+ }
return true;
} else {
return false;