diff --git a/database.sql b/database.sql index 737337900d..8564a8ba02 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2020.12-dev (Red Hot Poker) --- DB_UPDATE_VERSION 1380 +-- DB_UPDATE_VERSION 1381 -- ------------------------------------------ @@ -1140,6 +1140,7 @@ CREATE TABLE IF NOT EXISTS `post-tag` ( CREATE TABLE IF NOT EXISTS `post-user` ( `uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri', `uid` mediumint unsigned NOT NULL COMMENT 'Owner id which owns this copy of the item', + `protocol` tinyint unsigned COMMENT 'Protocol used to deliver the item for this user', `contact-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'contact.id', `unseen` boolean NOT NULL DEFAULT '1' COMMENT 'post has not been seen', `hidden` boolean NOT NULL DEFAULT '0' COMMENT 'Marker to hide the post from the user', @@ -1755,4 +1756,3 @@ CREATE VIEW `workerqueue-view` AS SELECT INNER JOIN `workerqueue` ON `workerqueue`.`pid` = `process`.`pid` WHERE NOT `workerqueue`.`done`; - diff --git a/mod/dfrn_notify.php b/mod/dfrn_notify.php index 8b14fe49ba..33953c6a28 100644 --- a/mod/dfrn_notify.php +++ b/mod/dfrn_notify.php @@ -28,6 +28,7 @@ use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; +use Friendica\Model\Conversation; use Friendica\Model\User; use Friendica\Protocol\DFRN; use Friendica\Protocol\Diaspora; @@ -192,7 +193,7 @@ function dfrn_notify_post(App $a) { Logger::log('Importing post from ' . $importer['addr'] . ' to ' . $importer['nickname'] . ' with the RINO ' . $rino_remote . ' encryption.', Logger::DEBUG); - $ret = DFRN::import($data, $importer); + $ret = DFRN::import($data, $importer, false, Conversation::PARCEL_LEGACY_DFRN); System::xmlExit($ret, 'Processed'); // NOTREACHED @@ -224,7 +225,7 @@ function dfrn_dispatch_public($postdata) Logger::log('Importing post from ' . $msg['author'] . ' with the public envelope.', Logger::DEBUG); // Now we should be able to import it - $ret = DFRN::import($msg['message'], $importer); + $ret = DFRN::import($msg['message'], $importer, false, Conversation::PARCEL_DIASPORA_DFRN); System::xmlExit($ret, 'Done'); } @@ -257,7 +258,7 @@ function dfrn_dispatch_private($user, $postdata) Logger::log('Importing post from ' . $msg['author'] . ' to ' . $user['nickname'] . ' with the private envelope.', Logger::DEBUG); // Now we should be able to import it - $ret = DFRN::import($msg['message'], $importer); + $ret = DFRN::import($msg['message'], $importer, false, Conversation::PARCEL_DIASPORA_DFRN); System::xmlExit($ret, 'Done'); } diff --git a/mod/item.php b/mod/item.php index f192d9525a..6864dabacd 100644 --- a/mod/item.php +++ b/mod/item.php @@ -81,8 +81,6 @@ function item_post(App $a) { $api_source = $_REQUEST['api_source'] ?? false; - $message_id = ((!empty($_REQUEST['message_id']) && $api_source) ? strip_tags($_REQUEST['message_id']) : ''); - $return_path = $_REQUEST['return'] ?? ''; $preview = intval($_REQUEST['preview'] ?? 0); @@ -176,14 +174,6 @@ function item_post(App $a) { $profile_uid = $toplevel_user_id; } - // Check for multiple posts with the same message id (when the post was created via API) - if (($message_id != '') && ($profile_uid != 0)) { - if (Item::exists(['uri' => $message_id, 'uid' => $profile_uid])) { - Logger::info('Message already exists for user', ['uri' => $message_id, 'uid' => $profile_uid]); - return 0; - } - } - // Allow commenting if it is an answer to a public post $allow_comment = local_user() && ($profile_uid == 0) && $toplevel_item_id && in_array($toplevel_item['network'], Protocol::FEDERATED); @@ -562,7 +552,7 @@ function item_post(App $a) { $origin = $_REQUEST['origin']; } - $uri = ($message_id ? $message_id : Item::newURI($api_source ? $profile_uid : $uid, $guid)); + $uri = Item::newURI($api_source ? $profile_uid : $uid, $guid); // Fallback so that we alway have a parent uri if (!$thr_parent_uri || !$toplevel_item_id) { @@ -628,7 +618,7 @@ function item_post(App $a) { $datarray['api_source'] = $api_source; // This field is for storing the raw conversation data - $datarray['protocol'] = Conversation::PARCEL_DFRN; + $datarray['protocol'] = Conversation::PARCEL_DIRECT; $conversation = DBA::selectFirst('conversation', ['conversation-uri', 'conversation-href'], ['item-uri' => $datarray['thr-parent']]); if (DBA::isResult($conversation)) { diff --git a/src/Model/Conversation.php b/src/Model/Conversation.php index c2f5b78bd9..d05f8af9fd 100644 --- a/src/Model/Conversation.php +++ b/src/Model/Conversation.php @@ -34,11 +34,15 @@ class Conversation * It currently is stored in the "protocol" field for legacy reasons. */ const PARCEL_ACTIVITYPUB = 0; - const PARCEL_DFRN = 1; + const PARCEL_DFRN = 1; // Deprecated const PARCEL_DIASPORA = 2; const PARCEL_SALMON = 3; const PARCEL_FEED = 4; // Deprecated const PARCEL_SPLIT_CONVERSATION = 6; + const PARCEL_LEGACY_DFRN = 7; + const PARCEL_DIASPORA_DFRN = 8; + const PARCEL_LOCAL_DFRN = 9; + const PARCEL_DIRECT = 10; const PARCEL_TWITTER = 67; const PARCEL_UNKNOWN = 255; @@ -134,9 +138,7 @@ class Conversation unset($arr['conversation-uri']); unset($arr['conversation-href']); - unset($arr['protocol']); unset($arr['source']); - unset($arr['direction']); return $arr; } diff --git a/src/Model/Item.php b/src/Model/Item.php index 5bc97c677f..59928fd641 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -1553,7 +1553,7 @@ class Item $item['wall'] = 1; $item['origin'] = 1; $item['network'] = Protocol::DFRN; - $item['protocol'] = Conversation::PARCEL_DFRN; + $item['protocol'] = Conversation::PARCEL_DIRECT; if (is_int($notify)) { $priority = $notify; @@ -1879,14 +1879,14 @@ class Item Tag::storeFromBody($item['uri-id'], $body); } - // Remove all fields that aren't part of the item table - foreach ($item as $field => $value) { - if (!in_array($field, $structure['item'])) { - unset($item[$field]); - } - } - if (Post\User::insert($item['uri-id'], $item['uid'], $item)) { + // Remove all fields that aren't part of the item table + foreach ($item as $field => $value) { + if (!in_array($field, $structure['item'])) { + unset($item[$field]); + } + } + $condition = ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'network' => $item['network']]; if (DBA::exists('item', $condition)) { Logger::notice('Item is already inserted - aborting', $condition); diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index 22a889a851..312aae5f7b 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -2199,13 +2199,13 @@ class DFRN * @throws \ImagickException * @todo Add type-hints */ - private static function processEntry($header, $xpath, $entry, $importer, $xml) + private static function processEntry($header, $xpath, $entry, $importer, $xml, $protocol) { Logger::log("Processing entries"); $item = $header; - $item["protocol"] = Conversation::PARCEL_DFRN; + $item["protocol"] = $protocol; $item["source"] = $xml; @@ -2601,7 +2601,7 @@ class DFRN * @throws \ImagickException * @todo set proper type-hints */ - public static function import($xml, $importer, $sort_by_date = false) + public static function import($xml, $importer, $sort_by_date = false, $protocol = Conversation::PARCEL_DFRN) { if ($xml == "") { return 400; @@ -2712,7 +2712,7 @@ class DFRN if (!$sort_by_date) { $entries = $xpath->query("/atom:feed/atom:entry"); foreach ($entries as $entry) { - self::processEntry($header, $xpath, $entry, $importer, $xml); + self::processEntry($header, $xpath, $entry, $importer, $xml, $protocol); } } else { $newentries = []; @@ -2726,7 +2726,7 @@ class DFRN ksort($newentries); foreach ($newentries as $entry) { - self::processEntry($header, $xpath, $entry, $importer, $xml); + self::processEntry($header, $xpath, $entry, $importer, $xml, $protocol); } } Logger::log("Import done for user " . $importer["importer_uid"] . " from contact " . $importer["id"], Logger::DEBUG); diff --git a/src/Protocol/Feed.php b/src/Protocol/Feed.php index 93e68241c6..dee1f204cc 100644 --- a/src/Protocol/Feed.php +++ b/src/Protocol/Feed.php @@ -32,6 +32,7 @@ use Friendica\Core\Protocol; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; +use Friendica\Model\Conversation; use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\Tag; @@ -100,7 +101,7 @@ class Feed $dfrn_importer = DFRN::getImporter($contact['id'], $importer['uid']); if (!empty($dfrn_importer)) { Logger::info('Now import the DFRN feed'); - DFRN::import($xml, $dfrn_importer, true); + DFRN::import($xml, $dfrn_importer, true, Conversation::PARCEL_LEGACY_DFRN); return; } } diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index 2cc815c323..a6e0df4c33 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -875,7 +875,9 @@ class OStatus */ private static function fetchSelf($self, array &$item) { - $condition = ['`item-uri` = ? AND `protocol` IN (?, ?)', $self, Conversation::PARCEL_DFRN, Conversation::PARCEL_SALMON]; + $condition = ['item-uri' => $self, 'protocol' => [Conversation::PARCEL_DFRN, + Conversation::PARCEL_DIASPORA_DFRN, Conversation::PARCEL_LEGACY_DFRN, + Conversation::PARCEL_LOCAL_DFRN, Conversation::PARCEL_DIRECT, Conversation::PARCEL_SALMON]]; if (DBA::exists('conversation', $condition)) { Logger::log('Conversation '.$item['uri'].' is already stored.', Logger::DEBUG); return; @@ -912,7 +914,9 @@ class OStatus */ private static function fetchRelated($related, $related_uri, $importer) { - $condition = ['`item-uri` = ? AND `protocol` IN (?, ?)', $related_uri, Conversation::PARCEL_DFRN, Conversation::PARCEL_SALMON]; + $condition = ['item-uri' => $related_uri, 'protocol' => [Conversation::PARCEL_DFRN, + Conversation::PARCEL_DIASPORA_DFRN, Conversation::PARCEL_LEGACY_DFRN, + Conversation::PARCEL_LOCAL_DFRN, Conversation::PARCEL_DIRECT, Conversation::PARCEL_SALMON]]; $conversation = DBA::selectFirst('conversation', ['source', 'protocol'], $condition); if (DBA::isResult($conversation)) { $stored = true; diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index 8e49ee4715..fc24faef62 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -33,6 +33,7 @@ use Friendica\Protocol\Activity; use Friendica\Util\Strings; use Friendica\Util\Network; use Friendica\Core\Worker; +use Friendica\Model\Conversation; use Friendica\Model\FContact; use Friendica\Protocol\Relay; @@ -334,7 +335,7 @@ class Delivery return; } - DFRN::import($atom, $target_importer); + DFRN::import($atom, $target_importer, false, Conversation::PARCEL_LOCAL_DFRN); if (in_array($cmd, [Delivery::POST, Delivery::POKE])) { Model\Post\DeliveryData::incrementQueueDone($target_item['uri-id'], Model\Post\DeliveryData::DFRN); diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 41c8af1de2..9a125cc15b 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1380); + define('DB_UPDATE_VERSION', 1381); } return [ @@ -1191,6 +1191,7 @@ return [ "fields" => [ "uri-id" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the item uri"], "uid" => ["type" => "mediumint unsigned", "not null" => "1", "primary" => "1", "foreign" => ["user" => "uid"], "comment" => "Owner id which owns this copy of the item"], + "protocol" => ["type" => "tinyint unsigned", "comment" => "Protocol used to deliver the item for this user"], "contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => "contact.id"], "unseen" => ["type" => "boolean", "not null" => "1", "default" => "1", "comment" => "post has not been seen"], "hidden" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Marker to hide the post from the user"],