+ /**
+ * @brief Distributes public items to the receivers
+ *
+ * @param integer $itemid Item ID that should be added
+ * @param string $signed_text Original text (for Diaspora signatures), JSON encoded.
+ */
+ public static function distribute($itemid, $signed_text = '')
+ {
+ $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']);
+ unset($item['parent']);
+ unset($item['mention']);
+ unset($item['wall']);
+ unset($item['origin']);
+ unset($item['starred']);
+ unset($item['rendered-hash']);
+ unset($item['rendered-html']);
+
+ $users = [];
+
+ $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', ['uid'], $condition);
+ while ($contact = dba::fetch($contacts)) {
+ $users[$contact['uid']] = $contact['uid'];
+ }
+
+ $origin_uid = 0;
+
+ if ($item['uri'] != $item['parent-uri']) {
+ $parents = dba::select('item', ['uid', 'origin'], ["`uri` = ? AND `uid` != 0", $item['parent-uri']]);
+ while ($parent = dba::fetch($parents)) {
+ $users[$parent['uid']] = $parent['uid'];
+ if ($parent['origin'] && !$item['origin']) {
+ $origin_uid = $parent['uid'];
+ }
+ }
+ }
+
+ foreach ($users as $uid) {
+ if ($origin_uid == $uid) {
+ $item['diaspora_signed_text'] = $signed_text;
+ }
+ self::storeForUser($itemid, $item, $uid);
+ }
+ }
+
+ /**
+ * @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 integer $uid The user that will receive the item entry
+ */
+ private static function storeForUser($itemid, $item, $uid)
+ {
+ $item['uid'] = $uid;
+ $item['origin'] = 0;
+ $item['wall'] = 0;
+ if ($item['uri'] == $item['parent-uri']) {
+ $item['contact-id'] = Contact::getIdForURL($item['owner-link'], $uid);
+ } else {
+ $item['contact-id'] = Contact::getIdForURL($item['author-link'], $uid);
+ }
+
+ if (empty($item['contact-id'])) {
+ $self = dba::selectFirst('contact', ['id'], ['self' => true, 'uid' => $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"
+
+ $notify = false;
+ if ($item['uri'] == $item['parent-uri']) {
+ $contact = dba::selectFirst('contact', [], ['id' => $item['contact-id'], 'self' => false]);
+ if (DBM::is_result($contact)) {
+ $notify = self::isRemoteSelf($contact, $item);
+ }
+ }
+
+ $distributed = self::insert($item, false, $notify, true);
+
+ if (!$distributed) {
+ logger("Distributed public item " . $itemid . " for user " . $uid . " wasn't stored", LOGGER_DEBUG);
+ } else {
+ logger("Distributed public item " . $itemid . " for user " . $uid . " with id " . $distributed, LOGGER_DEBUG);
+ }
+ }
+