]> git.mxchange.org Git - friendica.git/blobdiff - src/Model/Item.php
Signed Diaspora posts should now be stored more reliable
[friendica.git] / src / Model / Item.php
index d235f0a7f96bab562745c0be47b04c5131b8e5e5..824e240cc36e54edcf7377889a80878ecfbb35d8 100644 (file)
@@ -176,7 +176,7 @@ class Item extends BaseObject
 
                // We can always comment on posts from these networks
                if (array_key_exists('writable', $row) &&
-                       in_array($row['internal-network'], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
+                       in_array($row['internal-network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) {
                        $row['writable'] = true;
                }
 
@@ -231,6 +231,10 @@ class Item extends BaseObject
                        }
                }
 
+               if (array_key_exists('signed_text', $row) && array_key_exists('interaction', $row) && !is_null($row['interaction'])) {
+                       $row['signed_text'] = $row['interaction'];
+               }
+
                if (array_key_exists('ignored', $row) && array_key_exists('internal-user-ignored', $row) && !is_null($row['internal-user-ignored'])) {
                        $row['ignored'] = $row['internal-user-ignored'];
                }
@@ -242,6 +246,7 @@ class Item extends BaseObject
                unset($row['internal-iaid']);
                unset($row['internal-icid']);
                unset($row['internal-user-ignored']);
+               unset($row['interaction']);
 
                return $row;
        }
@@ -567,6 +572,8 @@ class Item extends BaseObject
 
                $fields['sign'] = ['signed_text', 'signature', 'signer'];
 
+               $fields['diaspora-interaction'] = ['interaction'];
+
                return $fields;
        }
 
@@ -653,6 +660,10 @@ class Item extends BaseObject
                        $joins .= " LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id`";
                }
 
+               if (strpos($sql_commands, "`diaspora-interaction`.") !== false) {
+                       $joins .= " LEFT JOIN `diaspora-interaction` ON `diaspora-interaction`.`uri-id` = `item`.`uri-id`";
+               }
+
                if (strpos($sql_commands, "`item-activity`.") !== false) {
                        $joins .= " LEFT JOIN `item-activity` ON `item-activity`.`id` = `item`.`iaid`";
                }
@@ -705,6 +716,10 @@ class Item extends BaseObject
                        $selected[] = 'internal-user-ignored';
                }
 
+               if (in_array('signed_text', $selected)) {
+                       $selected[] = 'interaction';
+               }
+
                $selection = [];
                foreach ($fields as $table => $table_fields) {
                        foreach ($table_fields as $field => $select) {
@@ -1081,9 +1096,8 @@ class Item extends BaseObject
 
                DBA::delete('item-delivery-data', ['iid' => $item['id']]);
 
-               if (!empty($item['iaid']) && !self::exists(['iaid' => $item['iaid'], 'deleted' => false])) {
-                       DBA::delete('item-activity', ['id' => $item['iaid']], ['cascade' => false]);
-               }
+               // We don't delete the item-activity here, since we need some of the data for ActivityPub
+
                if (!empty($item['icid']) && !self::exists(['icid' => $item['icid'], 'deleted' => false])) {
                        DBA::delete('item-content', ['id' => $item['icid']], ['cascade' => false]);
                }
@@ -1167,7 +1181,7 @@ class Item extends BaseObject
                if ($notify) {
                        // We have to avoid duplicates. So we create the GUID in form of a hash of the plink or uri.
                        // We add the hash of our own host because our host is the original creator of the post.
-                       $prefix_host = get_app()->get_hostname();
+                       $prefix_host = get_app()->getHostName();
                } else {
                        $prefix_host = '';
 
@@ -1205,7 +1219,7 @@ class Item extends BaseObject
                } elseif (!empty($item['uri'])) {
                        $guid = self::guidFromUri($item['uri'], $prefix_host);
                } else {
-                       $guid = System::createGUID(32, hash('crc32', $prefix_host));
+                       $guid = System::createUUID(hash('crc32', $prefix_host));
                }
 
                return $guid;
@@ -1290,17 +1304,16 @@ class Item extends BaseObject
                 */
 
                $dsprsig = null;
-               if (x($item, 'dsprsig')) {
+               if (isset($item['dsprsig'])) {
                        $encoded_signature = $item['dsprsig'];
                        $dsprsig = json_decode(base64_decode($item['dsprsig']));
                        unset($item['dsprsig']);
                }
 
-               if (!empty($item['diaspora_signed_text'])) {
+               $diaspora_signed_text = '';
+               if (isset($item['diaspora_signed_text'])) {
                        $diaspora_signed_text = $item['diaspora_signed_text'];
                        unset($item['diaspora_signed_text']);
-               } else {
-                       $diaspora_signed_text = '';
                }
 
                // Converting the plink
@@ -1352,7 +1365,7 @@ class Item extends BaseObject
                 * We have to check several networks since Friendica posts could be repeated
                 * via OStatus (maybe Diasporsa as well)
                 */
-               if (in_array($item['network'], [Protocol::DIASPORA, Protocol::DFRN, Protocol::OSTATUS, ""])) {
+               if (in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::DIASPORA, Protocol::DFRN, Protocol::OSTATUS, ""])) {
                        $condition = ["`uri` = ? AND `uid` = ? AND `network` IN (?, ?, ?)",
                                trim($item['uri']), $item['uid'],
                                Protocol::DIASPORA, Protocol::DFRN, Protocol::OSTATUS];
@@ -1462,15 +1475,6 @@ class Item extends BaseObject
                        return 0;
                }
 
-               // These fields aren't stored anymore in the item table, they are fetched upon request
-               unset($item['author-link']);
-               unset($item['author-name']);
-               unset($item['author-avatar']);
-
-               unset($item['owner-link']);
-               unset($item['owner-name']);
-               unset($item['owner-avatar']);
-
                if ($item['network'] == Protocol::PHANTOM) {
                        logger('Missing network. Called by: '.System::callstack(), LOGGER_DEBUG);
 
@@ -1708,6 +1712,15 @@ class Item extends BaseObject
                unset($item['postopts']);
                unset($item['inform']);
 
+               // These fields aren't stored anymore in the item table, they are fetched upon request
+               unset($item['author-link']);
+               unset($item['author-name']);
+               unset($item['author-avatar']);
+
+               unset($item['owner-link']);
+               unset($item['owner-name']);
+               unset($item['owner-avatar']);
+
                DBA::transaction();
                $ret = DBA::insert('item', $item);
 
@@ -1799,14 +1812,17 @@ class Item extends BaseObject
                                logger("Repaired double encoded signature from handle ".$dsprsig->signer, LOGGER_DEBUG);
                        }
 
-                       DBA::insert('sign', ['iid' => $current_post, 'signed_text' => $dsprsig->signed_text,
-                                               'signature' => $dsprsig->signature, 'signer' => $dsprsig->signer]);
+                       if (!empty($dsprsig->signed_text) && empty($dsprsig->signature) && empty($dsprsig->signer)) {
+                               DBA::insert('diaspora-interaction', ['uri-id' => $item['uri-id'], 'interaction' => $dsprsig->signed_text], true);
+                       } else {
+                               // The other fields are used by very old Friendica servers, so we currently store them differently
+                               DBA::insert('sign', ['iid' => $current_post, 'signed_text' => $dsprsig->signed_text,
+                                       'signature' => $dsprsig->signature, 'signer' => $dsprsig->signer]);
+                       }
                }
 
                if (!empty($diaspora_signed_text)) {
-                       // Formerly we stored the signed text, the signature and the author in different fields.
-                       // We now store the raw data so that we are more flexible.
-                       DBA::insert('sign', ['iid' => $current_post, 'signed_text' => $diaspora_signed_text]);
+                       DBA::insert('diaspora-interaction', ['uri-id' => $item['uri-id'], 'interaction' => $diaspora_signed_text], true);
                }
 
                $deleted = self::tagDeliver($item['uid'], $current_post);
@@ -1936,6 +1952,7 @@ class Item extends BaseObject
                } else {
                        // This shouldn't happen.
                        logger('Could not insert activity for URI ' . $item['uri'] . ' - should not happen');
+                       Lock::release('item_insert_activity');
                        return false;
                }
                if ($locked) {
@@ -2053,7 +2070,7 @@ class Item extends BaseObject
 
                // Only distribute public items from native networks
                $condition = ['id' => $itemid, 'uid' => 0,
-                       'network' => [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""],
+                       'network' => [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""],
                        'visible' => true, 'deleted' => false, 'moderated' => false, 'private' => false];
                $item = self::selectFirst(self::ITEM_FIELDLIST, ['id' => $itemid]);
                if (!DBA::isResult($item)) {
@@ -2071,14 +2088,46 @@ class Item extends BaseObject
 
                $users = [];
 
-               $condition = ["`nurl` IN (SELECT `nurl` FROM `contact` WHERE `id` = ?) AND `uid` != 0 AND NOT `blocked` AND `rel` IN (?, ?)",
-                       $parent['owner-id'], Contact::SHARING,  Contact::FRIEND];
+               /// @todo add a field "pcid" in the contact table that referrs to the public contact id.
+               $owner = DBA::selectFirst('contact', ['url', 'nurl', 'alias'], ['id' => $parent['owner-id']]);
+               if (!DBA::isResult($owner)) {
+                       return;
+               }
 
+               $condition = ['nurl' => $owner['nurl'], 'rel' => [Contact::SHARING, Contact::FRIEND]];
                $contacts = DBA::select('contact', ['uid'], $condition);
+               while ($contact = DBA::fetch($contacts)) {
+                       if ($contact['uid'] == 0) {
+                               continue;
+                       }
+
+                       $users[$contact['uid']] = $contact['uid'];
+               }
+               DBA::close($contacts);
 
+               $condition = ['alias' => $owner['url'], 'rel' => [Contact::SHARING, Contact::FRIEND]];
+               $contacts = DBA::select('contact', ['uid'], $condition);
                while ($contact = DBA::fetch($contacts)) {
+                       if ($contact['uid'] == 0) {
+                               continue;
+                       }
+
                        $users[$contact['uid']] = $contact['uid'];
                }
+               DBA::close($contacts);
+
+               if (!empty($owner['alias'])) {
+                       $condition = ['url' => $owner['alias'], 'rel' => [Contact::SHARING, Contact::FRIEND]];
+                       $contacts = DBA::select('contact', ['uid'], $condition);
+                       while ($contact = DBA::fetch($contacts)) {
+                               if ($contact['uid'] == 0) {
+                                       continue;
+                               }
+
+                               $users[$contact['uid']] = $contact['uid'];
+                       }
+                       DBA::close($contacts);
+               }
 
                $origin_uid = 0;
 
@@ -2175,7 +2224,7 @@ class Item extends BaseObject
                }
 
                // is it an entry from a connector? Only add an entry for natively connected networks
-               if (!in_array($item["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""])) {
+               if (!in_array($item["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""])) {
                        return;
                }
 
@@ -2326,16 +2375,10 @@ class Item extends BaseObject
        public static function newURI($uid, $guid = "")
        {
                if ($guid == "") {
-                       $guid = System::createGUID(32);
+                       $guid = System::createUUID();
                }
 
-               $hostname = self::getApp()->get_hostname();
-
-               $user = DBA::selectFirst('user', ['nickname'], ['uid' => $uid]);
-
-               $uri = "urn:X-dfrn:" . $hostname . ':' . $user['nickname'] . ':' . $guid;
-
-               return $uri;
+               return self::getApp()->getBaseURL() . '/objects/' . $guid;
        }
 
        /**
@@ -2618,7 +2661,7 @@ class Item extends BaseObject
                }
 
                // Prevent to forward already forwarded posts
-               if ($datarray["app"] == $a->get_hostname()) {
+               if ($datarray["app"] == $a->getHostName()) {
                        logger('Already forwarded (second test)', LOGGER_DEBUG);
                        return false;
                }
@@ -2659,7 +2702,7 @@ class Item extends BaseObject
                        }
 
                        if ($contact['network'] != Protocol::FEED) {
-                               $datarray["guid"] = System::createGUID(32);
+                               $datarray["guid"] = System::createUUID();
                                unset($datarray["plink"]);
                                $datarray["uri"] = self::newURI($contact['uid'], $datarray["guid"]);
                                $datarray["parent-uri"] = $datarray["uri"];
@@ -2825,7 +2868,7 @@ class Item extends BaseObject
        }
 
        // returns an array of contact-ids that are allowed to see this object
-       private static function enumeratePermissions($obj)
+       public static function enumeratePermissions($obj)
        {
                $allow_people = expand_acl($obj['allow_cid']);
                $allow_groups = Group::expand(expand_acl($obj['allow_gid']));
@@ -3085,10 +3128,10 @@ class Item extends BaseObject
                        return true;
                }
 
-               $objtype = $item['resource-id'] ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE ;
+               $objtype = $item['resource-id'] ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE;
 
                $new_item = [
-                       'guid'          => System::createGUID(32),
+                       'guid'          => System::createUUID(),
                        'uri'           => self::newURI($item['uid']),
                        'uid'           => $item['uid'],
                        'contact-id'    => $item_contact_id,
@@ -3099,7 +3142,7 @@ class Item extends BaseObject
                        'parent'        => $item['id'],
                        'parent-uri'    => $item['uri'],
                        'thr-parent'    => $item['uri'],
-                       'owner-id'      => $item['owner-id'],
+                       'owner-id'      => $author_id,
                        'author-id'     => $author_id,
                        'body'          => $activity,
                        'verb'          => $activity,