<?php
/**
- * @copyright Copyright (C) 2020, Friendica
+ * @copyright Copyright (C) 2010-2021, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
namespace Friendica\Protocol;
use Friendica\Content\Feature;
-use Friendica\Content\PageInfo;
use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\Markdown;
use Friendica\Core\Cache\Duration;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\FContact;
+use Friendica\Model\GServer;
use Friendica\Model\Item;
use Friendica\Model\ItemURI;
use Friendica\Model\Mail;
return $contacts;
}
- $items = Item::select(['author-id', 'author-link', 'parent-author-link', 'parent-guid', 'guid'],
+ $items = Post::select(['author-id', 'author-link', 'parent-author-link', 'parent-guid', 'guid'],
['parent' => $item['parent'], 'gravity' => [GRAVITY_COMMENT, GRAVITY_ACTIVITY]]);
- while ($item = DBA::fetch($items)) {
+ while ($item = Post::fetch($items)) {
$contact = DBA::selectFirst('contact', ['id', 'url', 'name', 'protocol', 'batch', 'network'],
['id' => $item['author-id']]);
if (!DBA::isResult($contact) || empty($contact['batch']) ||
*/
private static function messageExists($uid, $guid)
{
- $item = Item::selectFirst(['id'], ['uid' => $uid, 'guid' => $guid]);
+ $item = Post::selectFirst(['id'], ['uid' => $uid, 'guid' => $guid]);
if (DBA::isResult($item)) {
Logger::log("message ".$guid." already exists for user ".$uid);
return $item["id"];
* 'key' => The public key of the author
* @throws \Exception
*/
- private static function message($guid, $server, $level = 0)
+ public static function message($guid, $server, $level = 0)
{
if ($level > 5) {
return false;
$guid = urldecode($matches[2]);
- $item = Item::selectFirst(['id'], ['guid' => $guid, 'uid' => $uid]);
+ $item = Post::selectFirst(['id'], ['guid' => $guid, 'uid' => $uid]);
if (DBA::isResult($item)) {
Logger::info('Found', ['id' => $item['id']]);
return $item['id'];
$ret = self::storeByGuid($guid, $matches[1], $uid);
Logger::info('Result', ['ret' => $ret]);
- $item = Item::selectFirst(['id'], ['guid' => $guid, 'uid' => $uid]);
+ $item = Post::selectFirst(['id'], ['guid' => $guid, 'uid' => $uid]);
if (DBA::isResult($item)) {
Logger::info('Found', ['id' => $item['id']]);
return $item['id'];
'author-name', 'author-link', 'author-avatar', 'gravity',
'owner-name', 'owner-link', 'owner-avatar'];
$condition = ['uid' => $uid, 'guid' => $guid];
- $item = Item::selectFirst($fields, $condition);
+ $item = Post::selectFirst($fields, $condition);
if (!DBA::isResult($item)) {
$person = FContact::getByURL($author);
if ($result) {
Logger::log("Fetched missing item ".$guid." - result: ".$result, Logger::DEBUG);
- $item = Item::selectFirst($fields, $condition);
+ $item = Post::selectFirst($fields, $condition);
}
}
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
- private static function plink($addr, $guid, $parent_guid = '')
+ private static function plink(string $addr, string $guid, string $parent_guid = '')
{
$contact = Contact::getByURL($addr);
if (empty($contact)) {
*/
private static function getUriFromGuid($author, $guid, $onlyfound = false)
{
- $item = Item::selectFirst(['uri'], ['guid' => $guid]);
+ $item = Post::selectFirst(['uri'], ['guid' => $guid]);
if (DBA::isResult($item)) {
return $item["uri"];
} elseif (!$onlyfound) {
return "";
}
- /**
- * Fetch the guid from our database with a given uri
- *
- * @param string $uri Message uri
- * @param string $uid Author handle
- *
- * @return string The post guid
- * @throws \Exception
- */
- private static function getGuidFromUri($uri, $uid)
- {
- $item = Item::selectFirst(['guid'], ['uri' => $uri, 'uid' => $uid]);
- if (DBA::isResult($item)) {
- return $item["guid"];
- } else {
- return false;
- }
- }
-
/**
* Store the mentions in the tag table
*
return false;
}
+ if (!empty($contact['gsid'])) {
+ GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA);
+ }
+
$message_id = self::messageExists($importer["uid"], $guid);
if ($message_id) {
return true;
// Will be overwritten for sharing accounts in Item::insert
if ($fetched) {
- $datarray["post-type"] = Item::PT_FETCHED;
+ $datarray["post-reason"] = Item::PR_FETCHED;
} elseif ($datarray["uid"] == 0) {
- $datarray["post-type"] = Item::PT_GLOBAL;
+ $datarray["post-reason"] = Item::PR_GLOBAL;
} else {
- $datarray["post-type"] = Item::PT_COMMENT;
+ $datarray["post-reason"] = Item::PR_COMMENT;
}
$datarray["guid"] = $guid;
$datarray['thr-parent'] = $thr_parent ?: $toplevel_parent_item['uri'];
$datarray["object-type"] = Activity\ObjectType::COMMENT;
+ $datarray["post-type"] = Item::PT_NOTE;
$datarray["protocol"] = Conversation::PARCEL_DIASPORA;
$datarray["source"] = $xml;
return false;
}
+ if (!empty($contact['gsid'])) {
+ GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA);
+ }
+
$conversation = DBA::selectFirst('conv', [], ['uid' => $importer["uid"], 'guid' => $guid]);
if (!DBA::isResult($conversation)) {
$r = q(
return false;
}
+ if (!empty($contact['gsid'])) {
+ GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA);
+ }
+
$message_id = self::messageExists($importer["uid"], $guid);
if ($message_id) {
return true;
// like on comments have the comment as parent. So we need to fetch the toplevel parent
if ($toplevel_parent_item['gravity'] != GRAVITY_PARENT) {
- $toplevel = Item::selectFirst(['origin'], ['id' => $toplevel_parent_item['parent']]);
+ $toplevel = Post::selectFirst(['origin'], ['id' => $toplevel_parent_item['parent']]);
$origin = $toplevel["origin"];
} else {
$origin = $toplevel_parent_item["origin"];
return false;
}
+ if (!empty($contact['gsid'])) {
+ GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA);
+ }
+
$conversation = null;
$condition = ['uid' => $importer["uid"], 'guid' => $conversation_guid];
return false;
}
+ if (!empty($contact['gsid'])) {
+ GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA);
+ }
+
if (self::messageExists($importer["uid"], $guid)) {
return true;
}
Logger::info('Participation stored', ['id' => $message_id, 'guid' => $guid, 'parent_guid' => $parent_guid, 'author' => $author]);
// Send all existing comments and likes to the requesting server
- $comments = Item::select(['id', 'uri-id', 'parent-author-network', 'author-network', 'verb'],
+ $comments = Post::select(['id', 'uri-id', 'parent-author-network', 'author-network', 'verb'],
['parent' => $toplevel_parent_item['id'], 'gravity' => [GRAVITY_COMMENT, GRAVITY_ACTIVITY]]);
- while ($comment = Item::fetch($comments)) {
+ while ($comment = Post::fetch($comments)) {
if (in_array($comment['verb'], [Activity::FOLLOW, Activity::TAG])) {
Logger::info('participation messages are not relayed', ['item' => $comment['id']]);
continue;
$fields = ['body', 'title', 'app', 'created', 'object-type', 'uri', 'guid',
'author-name', 'author-link', 'author-avatar', 'plink', 'uri-id'];
$condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => [Item::PUBLIC, Item::UNLISTED]];
- $item = Item::selectFirst($fields, $condition);
+ $item = Post::selectFirst($fields, $condition);
if (DBA::isResult($item)) {
Logger::log("reshared message ".$guid." already exists on system.");
$item["body"] = self::replacePeopleGuid($item["body"], $item["author-link"]);
- // Add OEmbed and other information to the body
- $item["body"] = PageInfo::searchAndAppendToBody($item["body"], false, true);
-
return $item;
} else {
return $item;
$fields = ['body', 'title', 'app', 'created', 'object-type', 'uri', 'guid',
'author-name', 'author-link', 'author-avatar', 'plink', 'uri-id'];
$condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => [Item::PUBLIC, Item::UNLISTED]];
- $item = Item::selectFirst($fields, $condition);
+ $item = Post::selectFirst($fields, $condition);
if (DBA::isResult($item)) {
// If it is a reshared post from another network then reformat to avoid display problems with two share elements
*/
private static function addReshareActivity($item, $parent_message_id, $guid, $author)
{
- $parent = Item::selectFirst(['uri', 'guid'], ['id' => $parent_message_id]);
+ $parent = Post::selectFirst(['uri', 'guid'], ['id' => $parent_message_id]);
$datarray = [];
return false;
}
+ if (!empty($contact['gsid'])) {
+ GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA);
+ }
+
$message_id = self::messageExists($importer["uid"], $guid);
if ($message_id) {
return true;
return false;
}
+ if (empty($original_item['plink'])) {
+ $original_item['plink'] = self::plink($root_author, $root_guid);
+ }
+
$datarray = [];
$datarray["uid"] = $importer["uid"];
Tag::storeFromBody($datarray['uri-id'], $datarray["body"]);
- Post\Media::copy($original_item['uri-id'], $datarray['uri-id']);
$datarray["app"] = $original_item["app"];
$datarray["plink"] = self::plink($author, $guid);
}
// Fetch items that are about to be deleted
- $fields = ['uid', 'id', 'parent', 'author-link', 'file'];
+ $fields = ['uid', 'id', 'parent', 'author-link', 'uri-id'];
// When we receive a public retraction, we delete every item that we find.
if ($importer['uid'] == 0) {
$condition = ['guid' => $target_guid, 'deleted' => false, 'uid' => $importer['uid']];
}
- $r = Item::select($fields, $condition);
+ $r = Post::select($fields, $condition);
if (!DBA::isResult($r)) {
Logger::log("Target guid ".$target_guid." was not found on this system for user ".$importer['uid'].".");
return false;
}
- while ($item = Item::fetch($r)) {
- if (strstr($item['file'], '[')) {
+ while ($item = Post::fetch($r)) {
+ if (DBA::exists('post-category', ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'type' => Post\Category::FILE])) {
Logger::log("Target guid " . $target_guid . " for user " . $item['uid'] . " is filed. So it won't be deleted.", Logger::DEBUG);
continue;
}
// Fetch the parent item
- $parent = Item::selectFirst(['author-link'], ['id' => $item['parent']]);
+ $parent = Post::selectFirst(['author-link'], ['id' => $item['parent']]);
// Only delete it if the parent author really fits
if (!Strings::compareLink($parent["author-link"], $contact["url"]) && !Strings::compareLink($item["author-link"], $contact["url"])) {
Logger::log("Deleted target ".$target_guid." (".$item["id"].") from user ".$item["uid"]." parent: ".$item['parent'], Logger::DEBUG);
}
+ DBA::close($r);
return true;
}
return false;
}
+ if (!empty($contact['gsid'])) {
+ GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA);
+ }
+
$message_id = self::messageExists($importer["uid"], $guid);
if ($message_id) {
return true;
if ($data->photo) {
foreach ($data->photo as $photo) {
self::storePhotoAsMedia($datarray['uri-id'], $photo);
- $body = "[img]".XML::unescape($photo->remote_photo_path).
- XML::unescape($photo->remote_photo_name)."[/img]\n".$body;
}
$datarray["object-type"] = Activity\ObjectType::IMAGE;
+ $datarray["post-type"] = Item::PT_IMAGE;
} else {
$datarray["object-type"] = Activity\ObjectType::NOTE;
-
- // Add OEmbed and other information to the body
- if (!self::isHubzilla($contact["url"])) {
- $body = PageInfo::searchAndAppendToBody($body, false, true);
- }
+ $datarray["post-type"] = Item::PT_NOTE;
}
/// @todo enable support for polls
$datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH;
if ($fetched) {
- $datarray["post-type"] = Item::PT_FETCHED;
+ $datarray["post-reason"] = Item::PR_FETCHED;
} elseif ($datarray["uid"] == 0) {
- $datarray["post-type"] = Item::PT_GLOBAL;
+ $datarray["post-reason"] = Item::PR_GLOBAL;
}
$datarray["body"] = self::replacePeopleGuid($body, $contact["url"]);
return false;
}
- $aes_key = openssl_random_pseudo_bytes(32);
+ $aes_key = random_bytes(32);
$b_aes_key = base64_encode($aes_key);
- $iv = openssl_random_pseudo_bytes(16);
+ $iv = random_bytes(16);
$b_iv = base64_encode($iv);
$ciphertext = self::aesEncrypt($aes_key, $iv, $msg);
return;
}
- // Fetch some user id to have a valid handle to transmit the participation.
- // In fact it doesn't matter which user sends this - but it is needed by the protocol.
- // If the item belongs to a user, we take this user id.
- if ($item['uid'] == 0) {
- $condition = ['verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false];
- $first_user = DBA::selectFirst('user', ['uid'], $condition);
- $owner = User::getOwnerDataById($first_user['uid']);
- } else {
- $owner = User::getOwnerDataById($item['uid']);
- }
-
+ $owner = User::getOwnerDataById($item['uid']);
$author = self::myHandle($owner);
$message = ["author" => $author,
if (!empty($reshared['guid']) && $complete) {
$condition = ['guid' => $reshared['guid'], 'network' => [Protocol::DFRN, Protocol::DIASPORA]];
- $item = Item::selectFirst(['contact-id'], $condition);
+ $item = Post::selectFirst(['contact-id'], $condition);
if (DBA::isResult($item)) {
$ret = [];
$ret["root_handle"] = self::handleFromContact($item["contact-id"]);
$type = "reshare";
} else {
$title = $item["title"];
- $body = $item["body"];
+ $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']);
// Fetch the title from an attached link - if there is one
if (empty($item["title"]) && DI::pConfig()->get($owner['uid'], 'system', 'attach_link_title')) {
*/
private static function constructLike(array $item, array $owner)
{
- $parent = Item::selectFirst(['guid', 'uri', 'thr-parent'], ['uri' => $item["thr-parent"]]);
+ $parent = Post::selectFirst(['guid', 'uri', 'thr-parent'], ['uri' => $item["thr-parent"]]);
if (!DBA::isResult($parent)) {
return false;
}
*/
private static function constructAttend(array $item, array $owner)
{
- $parent = Item::selectFirst(['guid'], ['uri' => $item['thr-parent']]);
+ $parent = Post::selectFirst(['guid'], ['uri' => $item['thr-parent']]);
if (!DBA::isResult($parent)) {
return false;
}
return $result;
}
- $toplevel_item = Item::selectFirst(['guid', 'author-id', 'author-link'], ['id' => $item['parent'], 'parent' => $item['parent']]);
+ $toplevel_item = Post::selectFirst(['guid', 'author-id', 'author-link', 'gravity'], ['id' => $item['parent'], 'parent' => $item['parent']]);
if (!DBA::isResult($toplevel_item)) {
Logger::error('Missing parent conversation item', ['parent' => $item['parent']]);
return false;
$thread_parent_item = $toplevel_item;
if ($item['thr-parent'] != $item['parent-uri']) {
- $thread_parent_item = Item::selectFirst(['guid', 'author-id', 'author-link'], ['uri' => $item['thr-parent'], 'uid' => $item['uid']]);
+ $thread_parent_item = Post::selectFirst(['guid', 'author-id', 'author-link', 'gravity'], ['uri' => $item['thr-parent'], 'uid' => $item['uid']]);
}
- $body = $item["body"];
+ $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']);
// The replied to autor mention is prepended for clarity if:
// - Item replied isn't yours
// - Implicit mentions are enabled
if (
$item['author-id'] != $thread_parent_item['author-id']
+ && ($thread_parent_item['gravity'] != GRAVITY_PARENT)
&& (empty($item['uid']) || !Feature::isEnabled($item['uid'], 'explicit_mentions'))
&& !DI::config()->get('system', 'disable_implicit_mentions')
) {
return self::buildAndTransmit($owner, $contact, $type, $message, $public_batch, $item["guid"]);
}
- /**
- * Creates a message from a signature record entry
- *
- * @param array $item The item that will be exported
- * @return array The message
- */
- private static function messageFromSignature(array $item)
- {
- // Split the signed text
- $signed_parts = explode(";", $item['signed_text']);
-
- if ($item["deleted"]) {
- $message = ["author" => $item['signer'],
- "target_guid" => $signed_parts[0],
- "target_type" => $signed_parts[1]];
- } elseif (in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) {
- $message = ["author" => $signed_parts[4],
- "guid" => $signed_parts[1],
- "parent_guid" => $signed_parts[3],
- "parent_type" => $signed_parts[2],
- "positive" => $signed_parts[0],
- "author_signature" => $item['signature'],
- "parent_author_signature" => ""];
- } else {
- // Remove the comment guid
- $guid = array_shift($signed_parts);
-
- // Remove the parent guid
- $parent_guid = array_shift($signed_parts);
-
- // Remove the handle
- $handle = array_pop($signed_parts);
-
- $message = [
- "author" => $handle,
- "guid" => $guid,
- "parent_guid" => $parent_guid,
- "text" => implode(";", $signed_parts),
- "author_signature" => $item['signature'],
- "parent_author_signature" => ""
- ];
- }
- return $message;
- }
-
/**
* Relays messages (like, comment, retraction) to other servers if we are the thread owner
*
return false;
}
- $parent = Item::selectFirst(['parent-uri'], ['uri' => $item['thr-parent']]);
- if (!DBA::isResult($parent)) {
- return;
+ // This is only needed for the automated tests
+ if (empty($owner['uprvkey'])) {
+ return false;
}
- $item['parent-uri'] = $parent['parent-uri'];
-
$message = self::constructComment($item, $owner);
if ($message === false) {
return false;