<?php
/**
- * @copyright Copyright (C) 2010-2022, the Friendica project
+ * @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
use DOMElement;
use DOMNode;
use DOMXPath;
+use Friendica\App;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\Event;
-use Friendica\Model\FContact;
use Friendica\Model\GServer;
use Friendica\Model\Item;
use Friendica\Model\ItemURI;
use Friendica\Model\Profile;
use Friendica\Model\Tag;
use Friendica\Model\User;
+use Friendica\Network\HTTPException;
use Friendica\Network\Probe;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
class DFRN
{
- const TOP_LEVEL = 0; // Top level posting
- const REPLY = 1; // Regular reply that is stored locally
- const REPLY_RC = 2; // Reply that will be relayed
+ const TOP_LEVEL = 0; // Top level posting
+ const REPLY = 1; // Regular reply that is stored locally
+ const REPLY_RC = 2; // Reply that will be relayed
/**
* Generates an array of contact and user for DFRN imports
DI::config()->set('system', 'site_pubkey', $res['pubkey']);
}
- $profilephotos = Photo::selectToArray(['resource-id' , 'scale'], ['profile' => true, 'uid' => $uid], ['order' => ['scale']]);
+ $profilephotos = Photo::selectToArray(['resource-id', 'scale', 'type'], ['profile' => true, 'uid' => $uid], ['order' => ['scale']]);
$photos = [];
$ext = Images::supportedTypes();
foreach ($profilephotos as $p) {
- $photos[$p['scale']] = DI::baseUrl().'/photo/'.$p['resource-id'].'-'.$p['scale'].'.'.$ext[$p['type']];
+ $photos[$p['scale']] = DI::baseUrl() . '/photo/' . $p['resource-id'] . '-' . $p['scale'] . '.' . $ext[$p['type']];
}
-
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
XML::addElement($doc, $root, 'id', DI::baseUrl() . '/profile/' . $owner['nick']);
XML::addElement($doc, $root, 'title', $owner['name']);
- $attributes = ['uri' => 'https://friendi.ca', 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION];
- XML::addElement($doc, $root, 'generator', FRIENDICA_PLATFORM, $attributes);
+ $attributes = ['uri' => 'https://friendi.ca', 'version' => App::VERSION . '-' . DB_UPDATE_VERSION];
+ XML::addElement($doc, $root, 'generator', App::PLATFORM, $attributes);
$attributes = ['rel' => 'license', 'href' => 'http://creativecommons.org/licenses/by/3.0/'];
XML::addElement($doc, $root, 'link', '', $attributes);
XML::addElement($doc, $author, 'poco:utcOffset', DateTimeFormat::timezoneNow($profile['timezone'], 'P'));
- if (trim($profile['homepage']) != '') {
+ if (trim($profile['homepage'])) {
$urls = $doc->createElement('poco:urls');
XML::addElement($doc, $urls, 'poco:type', 'homepage');
XML::addElement($doc, $urls, 'poco:value', $profile['homepage']);
$author->appendChild($urls);
}
- if (trim($profile['pub_keywords']) != '') {
+ if (trim($profile['pub_keywords'] ?? '')) {
$keywords = explode(',', $profile['pub_keywords']);
foreach ($keywords as $keyword) {
}
}
- if (trim($profile['xmpp']) != '') {
+ if (trim($profile['xmpp'])) {
$ims = $doc->createElement('poco:ims');
XML::addElement($doc, $ims, 'poco:type', 'xmpp');
XML::addElement($doc, $ims, 'poco:value', $profile['xmpp']);
$author->appendChild($ims);
}
- if (trim($profile['locality'] . $profile['region'] . $profile['country-name']) != '') {
+ if (trim($profile['locality'] . $profile['region'] . $profile['country-name'])) {
$element = $doc->createElement('poco:address');
XML::addElement($doc, $element, 'poco:formatted', Profile::formatLocation($profile));
/// @Todo
/// - Check real image type and image size
- /// - Check which of these boths elements we should use
+ /// - Check which of these elements we should use
$attributes = [
'rel' => 'photo',
'type' => 'image/jpeg',
*/
private static function getAttachment($doc, $root, array $item)
{
- foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT, Post\Media::TORRENT, Post\Media::UNKNOWN]) as $attachment) {
+ foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT, Post\Media::TORRENT]) as $attachment) {
$attributes = ['rel' => 'enclosure',
'href' => $attachment['url'],
'type' => $attachment['mimetype']];
$mentioned = [];
if (!$item['parent']) {
- Logger::notice('Item without parent found.', ['type' => $type, 'item' => $item]);
+ Logger::warning('Item without parent found.', ['type' => $type, 'item' => $item]);
return null;
}
$entry->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
}
- $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body'] ?? '');
+ $body = Post\Media::addAttachmentsToBody($item['uri-id'], DI::contentItem()->addSharedPost($item));
+ $body = Post\Media::addHTMLAttachmentToBody($item['uri-id'], $body);
if ($item['private'] == Item::PRIVATE) {
$body = Item::fixPrivatePhotos($body, $owner['uid'], $item, $cid);
$dfrnowner = self::addEntryAuthor($doc, "dfrn:owner", $item["owner-link"], $item);
$entry->appendChild($dfrnowner);
- if ($item['gravity'] != GRAVITY_PARENT) {
+ if ($item['gravity'] != Item::GRAVITY_PARENT) {
$parent = Post::selectFirst(['guid', 'plink'], ['uri' => $item['thr-parent'], 'uid' => $item['uid']]);
if (DBA::isResult($parent)) {
$attributes = ["ref" => $item['thr-parent'], "type" => "text/html",
XML::addElement($doc, $entry, 'dfrn:diaspora_guid', $item['guid']);
- // The signed text contains the content in Markdown, the sender handle and the signatur for the content
+ // The signed text contains the content in Markdown, the sender handle and the signature for the content
// It is needed for relayed comments to Diaspora.
if ($item['signed_text']) {
$sign = base64_encode(json_encode(['signed_text' => $item['signed_text'],'signature' => '','signer' => '']));
if ($item['object-type'] != '') {
XML::addElement($doc, $entry, 'activity:object-type', $item['object-type']);
- } elseif ($item['gravity'] == GRAVITY_PARENT) {
+ } elseif ($item['gravity'] == Item::GRAVITY_PARENT) {
XML::addElement($doc, $entry, 'activity:object-type', Activity\ObjectType::NOTE);
} else {
XML::addElement($doc, $entry, 'activity:object-type', Activity\ObjectType::COMMENT);
}
}
- $fcontact = FContact::getByURL($contact['addr']);
- if (empty($fcontact)) {
+ try {
+ $pubkey = DI::dsprContact()->getByAddr(WebFingerUri::fromString($contact['addr']))->pubKey;
+ } catch (HTTPException\NotFoundException|\InvalidArgumentException $e) {
Logger::notice('Unable to find contact details for ' . $contact['id'] . ' - ' . $contact['addr']);
return -22;
}
- $pubkey = $fcontact['pubkey'] ?? '';
} else {
$pubkey = '';
}
$xml = $postResult->getBody();
$curl_stat = $postResult->getReturnCode();
+ if (!empty($contact['gsid']) && ($postResult->isTimeout() || empty($curl_stat))) {
+ GServer::setFailureById($contact['gsid']);
+ }
+
if (empty($curl_stat) || empty($xml)) {
Logger::notice('Empty answer from ' . $contact['id'] . ' - ' . $dest_url);
return -9; // timed out
return -23;
}
+ if (!empty($contact['gsid'])) {
+ GServer::setReachableById($contact['gsid'], Protocol::DFRN);
+ }
+
if (!empty($res->message)) {
Logger::info('Transmit to ' . $dest_url . ' returned status '.$res->status.' - '.$res->message);
}
$fields = ['id', 'uid', 'url', 'network', 'avatar-date', 'avatar', 'name-date', 'uri-date', 'addr',
'name', 'nick', 'about', 'location', 'keywords', 'xmpp', 'bdyear', 'bd', 'hidden', 'contact-type'];
- $condition = ["`uid` = ? AND `nurl` = ? AND `network` != ? AND NOT `pending` AND NOT `blocked`",
- $importer["importer_uid"], Strings::normaliseLink($author["link"]), Protocol::STATUSNET];
+ $condition = ["`uid` = ? AND `nurl` = ? AND NOT `pending` AND NOT `blocked`",
+ $importer["importer_uid"], Strings::normaliseLink($author["link"])];
if ($importer['account-type'] != User::ACCOUNT_TYPE_COMMUNITY) {
$condition = DBA::mergeConditions($condition, ['rel' => [Contact::SHARING, Contact::FRIEND]]);
*/
private static function processMail(DOMXPath $xpath, DOMNode $mail, array $importer)
{
- Logger::notice("Processing mails");
+ Logger::info("Processing mails");
$msg = [];
$msg['uid'] = $importer['importer_uid'];
*/
private static function processSuggestion(DOMXPath $xpath, DOMNode $suggestion, array $importer)
{
- Logger::notice('Processing suggestions');
+ Logger::info('Processing suggestions');
$url = $xpath->evaluate('string(dfrn:url[1]/text())', $suggestion);
$cid = Contact::getIdForURL($url);
*/
private static function processRelocation(DOMXPath $xpath, DOMNode $relocation, array $importer): bool
{
- Logger::notice("Processing relocations");
+ Logger::info("Processing relocations");
/// @TODO Rewrite this to one statement
$relocate = [];
// update contact
$old = Contact::selectFirst(['photo', 'url'], ['id' => $importer['id'], 'uid' => $importer['importer_uid']]);
-
if (!DBA::isResult($old)) {
- Logger::notice("Query failed to execute, no result returned in " . __FUNCTION__);
+ Logger::warning('Existing contact had not been fetched', ['id' => $importer['id']]);
return false;
}
Contact::updateAvatar($importer['id'], $relocate['avatar'], true);
- Logger::notice('Contacts are updated.');
+ Logger::info('Contacts are updated.');
/// @TODO
/// merge with current record, current contents have priority
private static function getEntryType(array $importer, array $item): int
{
if ($item['thr-parent'] != $item['uri']) {
- $community = false;
-
- if ($importer['account-type'] == User::ACCOUNT_TYPE_COMMUNITY) {
- $sql_extra = '';
- $community = true;
- Logger::notice("possible community action");
- } else {
- $sql_extra = " AND `self` AND `wall`";
- }
-
// was the top-level post for this action written by somebody on this site?
// Specifically, the recipient?
- $parent = Post::selectFirst(['wall'],
- ["`uri` = ? AND `uid` = ?" . $sql_extra, $item['thr-parent'], $importer['importer_uid']]);
-
- $is_a_remote_action = DBA::isResult($parent);
-
- if ($is_a_remote_action) {
- return DFRN::REPLY_RC;
+ if (Post::exists(['uri' => $item['thr-parent'], 'uid' => $importer['importer_uid'], 'self' => true, 'wall' => true])) {
+ return self::REPLY_RC;
} else {
- return DFRN::REPLY;
+ return self::REPLY;
}
} else {
- return DFRN::TOP_LEVEL;
+ return self::TOP_LEVEL;
}
}
* @param int $entrytype Is it a toplevel entry, a comment or a relayed comment?
* @param array $importer Record of the importer user mixed with contact of the content
* @param array $item the new item record
- * @param bool $is_like Is the verb a "like"?
*
* @return bool Should the processing of the entries be continued?
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- private static function processVerbs(int $entrytype, array $importer, array &$item, bool &$is_like)
+ private static function processVerbs(int $entrytype, array $importer, array &$item)
{
Logger::info('Process verb ' . $item['verb'] . ' and object-type ' . $item['object-type'] . ' for entrytype ' . $entrytype);
- if (($entrytype == DFRN::TOP_LEVEL) && !empty($importer['id'])) {
- // The filling of the the "contact" variable is done for legcy reasons
+ if (($entrytype == self::TOP_LEVEL) && !empty($importer['id'])) {
+ // The filling of the "contact" variable is done for legacy reasons
// The functions below are partly used by ostatus.php as well - where we have this variable
$contact = Contact::selectFirst([], ['id' => $importer['id']]);
// Big question: Do we need these functions? They were part of the "consume_feed" function.
// This function once was responsible for DFRN and OStatus.
if ($activity->match($item['verb'], Activity::FOLLOW)) {
- Logger::notice("New follower");
+ Logger::info("New follower");
Contact::addRelationship($importer, $contact, $item);
return false;
}
if ($activity->match($item['verb'], Activity::UNFOLLOW)) {
- Logger::notice("Lost follower");
+ Logger::info("Lost follower");
Contact::removeFollower($contact);
return false;
}
if ($activity->match($item['verb'], Activity::REQ_FRIEND)) {
- Logger::notice("New friend request");
+ Logger::info("New friend request");
Contact::addRelationship($importer, $contact, $item, true);
return false;
}
if ($activity->match($item['verb'], Activity::UNFRIEND)) {
- Logger::notice("Lost sharer");
+ Logger::info("Lost sharer");
Contact::removeSharer($contact);
return false;
}
|| ($item['verb'] == Activity::ATTENDMAYBE)
|| ($item['verb'] == Activity::ANNOUNCE)
) {
- $is_like = true;
- $item['gravity'] = GRAVITY_ACTIVITY;
+ $item['gravity'] = Item::GRAVITY_ACTIVITY;
// only one like or dislike per person
// split into two queries for performance issues
$condition = [
- 'uid' => $item['uid'],
- 'author-id' => $item['author-id'],
- 'gravity' => GRAVITY_ACTIVITY,
- 'verb' => $item['verb'],
+ 'uid' => $item['uid'],
+ 'author-id' => $item['author-id'],
+ 'gravity' => Item::GRAVITY_ACTIVITY,
+ 'verb' => $item['verb'],
'parent-uri' => $item['thr-parent'],
];
if (Post::exists($condition)) {
return false;
}
- $condition = ['uid' => $item['uid'], 'author-id' => $item['author-id'], 'gravity' => GRAVITY_ACTIVITY,
+ $condition = ['uid' => $item['uid'], 'author-id' => $item['author-id'], 'gravity' => Item::GRAVITY_ACTIVITY,
'verb' => $item['verb'], 'thr-parent' => $item['thr-parent']];
if (Post::exists($condition)) {
return false;
$item['owner-link'] = $item['author-link'];
$item['owner-avatar'] = $item['author-avatar'];
$item['owner-id'] = $item['author-id'];
- } else {
- $is_like = false;
}
if (($item['verb'] == Activity::TAG) && ($item['object-type'] == Activity\ObjectType::TAGTERM)) {
if ($xt->type == Activity\ObjectType::NOTE) {
$item_tag = Post::selectFirst(['id', 'uri-id'], ['uri' => $xt->id, 'uid' => $importer['importer_uid']]);
-
if (!DBA::isResult($item_tag)) {
- Logger::notice("Query failed to execute, no result returned in " . __FUNCTION__);
+ Logger::warning('Post had not been fetched', ['uri' => $xt->id, 'uid' => $importer['importer_uid']]);
return false;
}
* Checks if an incoming message is wanted
*
* @param array $item
- * @param array $imporer
+ * @param array $importer
* @return boolean Is the message wanted?
*/
private static function isSolicitedMessage(array $item, array $importer): bool
*/
private static function processEntry(array $header, DOMXPath $xpath, DOMNode $entry, array $importer, string $xml, int $protocol)
{
- Logger::notice("Processing entries");
+ Logger::info("Processing entries");
$item = $header;
$item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]);
- $item['body'] = Item::improveSharedDataInBody($item);
+ $quote_uri_id = Item::getQuoteUriId($item['body'], $item['uid']);
+ if (!empty($quote_uri_id)) {
+ $item['quote-uri-id'] = $quote_uri_id;
+ $item['body'] = BBCode::removeSharedData($item['body']);
+ }
Tag::storeFromBody($item['uri-id'], $item['body']);
$entrytype = self::getEntryType($importer, $item);
// Now assign the rest of the values that depend on the type of the message
- if (in_array($entrytype, [DFRN::REPLY, DFRN::REPLY_RC])) {
+ if (in_array($entrytype, [self::REPLY, self::REPLY_RC])) {
+ $item['gravity'] = Item::GRAVITY_COMMENT;
+
if (!isset($item['object-type'])) {
$item['object-type'] = Activity\ObjectType::COMMENT;
}
}
}
- // Ensure to have the correct share data
- $item = Item::addShareDataFromOriginal($item);
-
- if ($entrytype == DFRN::REPLY_RC) {
+ if ($entrytype == self::REPLY_RC) {
$item['wall'] = 1;
- } elseif ($entrytype == DFRN::TOP_LEVEL) {
+ } elseif ($entrytype == self::TOP_LEVEL) {
+ $item['gravity'] = Item::GRAVITY_PARENT;
+
if (!isset($item['object-type'])) {
$item['object-type'] = Activity\ObjectType::NOTE;
}
}
}
- // Need to initialize variable, otherwise E_NOTICE will happen
- $is_like = false;
-
- if (!self::processVerbs($entrytype, $importer, $item, $is_like)) {
+ if (!self::processVerbs($entrytype, $importer, $item)) {
Logger::info("Exiting because 'processVerbs' told us so");
return;
}
// This check is done here to be able to receive connection requests in "processVerbs"
- if (($entrytype == DFRN::TOP_LEVEL) && $owner_unknown) {
+ if (($entrytype == self::TOP_LEVEL) && $owner_unknown) {
Logger::info("Item won't be stored because user " . $importer['importer_uid'] . " doesn't follow " . $item['owner-link'] . ".");
return;
}
return;
}
- if (in_array($entrytype, [DFRN::REPLY, DFRN::REPLY_RC])) {
+ if (in_array($entrytype, [self::REPLY, self::REPLY_RC])) {
+ if (($item['uid'] != 0) && !Post::exists(['uid' => $item['uid'], 'uri' => $item['thr-parent']])) {
+ if (DI::pConfig()->get($item['uid'], 'system', 'accept_only_sharer') == Item::COMPLETION_NONE) {
+ Logger::info('Completion is set to "none", so we stop here.', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]);
+ return;
+ }
+ if (!Contact::isSharing($item['owner-id'], $item['uid']) && !Contact::isSharing($item['author-id'], $item['uid'])) {
+ Logger::info('Contact is not sharing with the user', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]);
+ return;
+ }
+ if (($item['gravity'] == Item::GRAVITY_ACTIVITY) && DI::pConfig()->get($item['uid'], 'system', 'accept_only_sharer') == Item::COMPLETION_COMMENT) {
+ Logger::info('Completion is set to "comment", but this is an activity. so we stop here.', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]);
+ return;
+ }
+ Logger::debug('Post is accepted.', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]);
+ } else {
+ Logger::debug('Thread parent exists.', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]);
+ }
+
// Will be overwritten for sharing accounts in Item::insert
- if (empty($item['post-reason']) && ($entrytype == DFRN::REPLY)) {
+ if (empty($item['post-reason']) && ($entrytype == self::REPLY)) {
$item['post-reason'] = Item::PR_COMMENT;
}
return true;
}
- } else { // $entrytype == DFRN::TOP_LEVEL
- if (($importer['uid'] == 0) && ($importer['importer_uid'] != 0)) {
- Logger::info("Contact " . $importer['id'] . " isn't known to user " . $importer['importer_uid'] . ". The post will be ignored.");
- return;
- }
- if (!Strings::compareLink($item['owner-link'], $importer['url'])) {
- /*
- * The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery,
- * but otherwise there's a possible data mixup on the sender's system.
- * the tgroup delivery code called from Item::insert will correct it if it's a forum,
- * but we're going to unconditionally correct it here so that the post will always be owned by our contact.
- */
- Logger::info('Correcting item owner.');
- $item['owner-link'] = $importer['url'];
- $item['owner-id'] = Contact::getIdForURL($importer['url'], 0);
- }
-
- if (($importer['rel'] == Contact::FOLLOWER) && (!self::tgroupCheck($importer['importer_uid'], $item))) {
- Logger::info("Contact " . $importer['id'] . " is only follower and tgroup check was negative.");
+ } else { // $entrytype == self::TOP_LEVEL
+ if (($item['uid'] != 0) && !Contact::isSharing($item['owner-id'], $item['uid']) && !Contact::isSharing($item['author-id'], $item['uid'])) {
+ Logger::info('Contact is not sharing with the user', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]);
return;
}
// This is my contact on another system, but it's really me.
// Turn this into a wall post.
$notify = Item::isRemoteSelf($importer, $item);
+ $item['wall'] = (bool)$notify;
$posted_id = Item::insert($item, $notify);
*/
private static function processDeletion(DOMXPath $xpath, DOMNode $deletion, array $importer)
{
- Logger::notice("Processing deletions");
+ Logger::info("Processing deletions");
$uri = null;
foreach ($deletion->attributes as $attributes) {
}
// When it is a starting post it has to belong to the person that wants to delete it
- if (($item['gravity'] == GRAVITY_PARENT) && ($item['contact-id'] != $importer['id'])) {
+ if (($item['gravity'] == Item::GRAVITY_PARENT) && ($item['contact-id'] != $importer['id'])) {
Logger::info('Item with URI ' . $uri . ' do not belong to contact ' . $importer['id'] . ' - ignoring deletion.');
return;
}
// Comments can be deleted by the thread owner or comment owner
- if (($item['gravity'] != GRAVITY_PARENT) && ($item['contact-id'] != $importer['id'])) {
+ if (($item['gravity'] != Item::GRAVITY_PARENT) && ($item['contact-id'] != $importer['id'])) {
$condition = ['id' => $item['parent'], 'contact-id' => $importer['id']];
if (!Post::exists($condition)) {
Logger::info('Item with URI ' . $uri . ' was not found or must not be deleted by contact ' . $importer['id'] . ' - ignoring deletion.');
GServer::setProtocol($importer['gsid'], Post\DeliveryData::DFRN);
}
- // is it a public forum? Private forums aren't exposed with this method
- $forum = intval(XML::getFirstNodeValue($xpath, '/atom:feed/dfrn:community/text()'));
+ // is it a public group? Private groups aren't exposed with this method
+ $group = intval(XML::getFirstNodeValue($xpath, '/atom:feed/dfrn:community/text()'));
// The account type is new since 3.5.1
if ($xpath->query('/atom:feed/dfrn:account_type')->length > 0) {
// Updating the public contact as well
Contact::update(['contact-type' => $accounttype], ['uid' => 0, 'nurl' => $importer['nurl']]);
}
- // A forum contact can either have set "forum" or "prv" - but not both
+ // A group contact can either have set "forum" or "prv" - but not both
if ($accounttype == User::ACCOUNT_TYPE_COMMUNITY) {
- // It's a forum, so either set the public or private forum flag
- $condition = ['(`forum` != ? OR `prv` != ?) AND `id` = ?', $forum, !$forum, $importer['id']];
- Contact::update(['forum' => $forum, 'prv' => !$forum], $condition);
+ // It's a group, so either set the public or private forum flag
+ $condition = ['(`forum` != ? OR `prv` != ?) AND `id` = ?', $group, !$group, $importer['id']];
+ Contact::update(['forum' => $group, 'prv' => !$group], $condition);
// Updating the public contact as well
- $condition = ['(`forum` != ? OR `prv` != ?) AND `uid` = 0 AND `nurl` = ?', $forum, !$forum, $importer['nurl']];
- Contact::update(['forum' => $forum, 'prv' => !$forum], $condition);
+ $condition = ['(`forum` != ? OR `prv` != ?) AND `uid` = 0 AND `nurl` = ?', $group, !$group, $importer['nurl']];
+ Contact::update(['forum' => $group, 'prv' => !$group], $condition);
} else {
- // It's not a forum, so remove the flags
+ // It's not a group, so remove the flags
$condition = ['(`forum` OR `prv`) AND `id` = ?', $importer['id']];
Contact::update(['forum' => false, 'prv' => false], $condition);
$condition = ['(`forum` OR `prv`) AND `uid` = 0 AND `nurl` = ?', $importer['nurl']];
Contact::update(['forum' => false, 'prv' => false], $condition);
}
- } elseif ($forum != $importer['forum']) { // Deprecated since 3.5.1
- $condition = ['`forum` != ? AND `id` = ?', $forum, $importer['id']];
- Contact::update(['forum' => $forum], $condition);
+ } elseif ($group != $importer['forum']) { // Deprecated since 3.5.1
+ $condition = ['`forum` != ? AND `id` = ?', $group, $importer['id']];
+ Contact::update(['forum' => $group], $condition);
// Updating the public contact as well
- $condition = ['`forum` != ? AND `uid` = 0 AND `nurl` = ?', $forum, $importer['nurl']];
- Contact::update(['forum' => $forum], $condition);
+ $condition = ['`forum` != ? AND `uid` = 0 AND `nurl` = ?', $group, $importer['nurl']];
+ Contact::update(['forum' => $group], $condition);
}
self::processDeletion($xpath, $deletion, $importer);
}
if (count($deletions) > 0) {
- Logger::notice(count($deletions) . ' deletions had been processed');
+ Logger::info(count($deletions) . ' deletions had been processed');
return 200;
}
}
return Activity::POST;
}
- // @TODO Documentation missing
- private static function tgroupCheck(int $uid, array $item): bool
- {
- $mention = false;
-
- // check that the message originated elsewhere and is a top-level post
-
- if ($item['wall'] || $item['origin'] || ($item['uri'] != $item['thr-parent'])) {
- return false;
- }
-
- $user = DBA::selectFirst('user', ['account-type', 'nickname'], ['uid' => $uid]);
- if (!DBA::isResult($user)) {
- return false;
- }
-
- $link = Strings::normaliseLink(DI::baseUrl() . '/profile/' . $user['nickname']);
-
- /*
- * Diaspora uses their own hardwired link URL in @-tags
- * instead of the one we supply with webfinger
- */
- $dlink = Strings::normaliseLink(DI::baseUrl() . '/u/' . $user['nickname']);
-
- $cnt = preg_match_all('/[\@\!]\[url\=(.*?)\](.*?)\[\/url\]/ism', $item['body'], $matches, PREG_SET_ORDER);
- if ($cnt) {
- foreach ($matches as $mtch) {
- if (Strings::compareLink($link, $mtch[1]) || Strings::compareLink($dlink, $mtch[1])) {
- $mention = true;
- Logger::notice('mention found: ' . $mtch[2]);
- }
- }
- }
-
- if (!$mention) {
- return false;
- }
-
- return ($user['account-type'] == User::ACCOUNT_TYPE_COMMUNITY);
- }
-
/**
* This function returns true if $update has an edited timestamp newer
* than $existing, i.e. $update contains new data which should override