API: Forum mentions are now working

This commit is contained in:
Michael 2022-03-02 06:59:07 +00:00
parent 1f1d3b2578
commit f853d58198
3 changed files with 98 additions and 75 deletions

View file

@ -383,69 +383,34 @@ function item_post(App $a) {
$contact_record = DBA::selectFirst('contact', [], ['uid' => $profile_uid, 'self' => true]) ?: [];
}
// Look for any tags and linkify them
$inform = '';
$private_forum = false;
$private_id = null;
$only_to_forum = false;
$forum_contact = [];
// Personal notes must never be altered to a forum post.
if ($posttype != Item::PT_PERSONAL_NOTE) {
// Convert mentions in the body to a unified format
$body = BBCode::setMentions($body, local_user() ? local_user() : $profile_uid, $network);
// Look for any tags and linkify them
$item = [
'uid' => local_user() ? local_user() : $profile_uid,
'gravity' => $toplevel_item_id ? GRAVITY_COMMENT : GRAVITY_PARENT,
'network' => $network,
'body' => $body,
'postopts' => $postopts,
'private' => $private,
'allow_cid' => $str_contact_allow,
'allow_gid' => $str_group_allow,
'deny_cid' => $str_contact_deny,
'deny_gid' => $str_group_deny,
];
// Search for forum mentions
foreach (Tag::getFromBody($body, Tag::TAG_CHARACTER[Tag::MENTION] . Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]) as $tag) {
$contact = Contact::getByURLForUser($tag[2], $profile_uid);
if (!empty($inform)) {
$inform .= ',';
}
$inform .= 'cid:' . $contact['id'];
$item = DI::contentItem()->expandTags($item);
if ($toplevel_item_id || empty($contact['cid']) || ($contact['contact-type'] != Contact::TYPE_COMMUNITY)) {
continue;
}
if (!empty($contact['prv']) || ($tag[1] == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION])) {
$private_forum = $contact['prv'];
$only_to_forum = ($tag[1] == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]);
$private_id = $contact['id'];
$forum_contact = $contact;
Logger::info('Private forum or exclusive mention', ['url' => $tag[2], 'mention' => $tag[1]]);
} elseif ($str_contact_allow == '<' . $contact['id'] . '>') {
$private_forum = false;
$only_to_forum = true;
$private_id = $contact['id'];
$forum_contact = $contact;
Logger::info('Public forum', ['url' => $tag[2], 'mention' => $tag[1]]);
} else {
Logger::info('Post with forum mention will not be converted to a forum post', ['url' => $tag[2], 'mention' => $tag[1]]);
}
}
Logger::info('Got inform', ['inform' => $inform]);
}
$original_contact_id = $contact_id;
if (!$toplevel_item_id && !empty($forum_contact) && ($private_forum || $only_to_forum)) {
// we tagged a forum in a top level post. Now we change the post
$private = $private_forum ? Item::PRIVATE : Item::UNLISTED;
if ($only_to_forum) {
$postopts = '';
}
$str_contact_deny = '';
$str_group_deny = '';
if ($private_forum) {
$str_contact_allow = '<' . $private_id . '>';
$str_group_allow = '<' . Group::getIdForForum($forum_contact['id']) . '>';
} else {
$str_contact_allow = '';
$str_group_allow = '';
}
$body = $item['body'];
$inform = $item['inform'];
$postopts = $item['postopts'];
$private = $item['private'];
$str_contact_allow = $item['allow_cid'];
$str_group_allow = $item['allow_gid'];
$str_contact_deny = $item['deny_cid'];
$str_group_deny = $item['deny_gid'];
} else {
$inform = '';
}
/*
@ -460,7 +425,7 @@ function item_post(App $a) {
$match = null;
if (!$preview && Photo::setPermissionFromBody($body, $uid, $original_contact_id, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny)) {
if (!$preview && Photo::setPermissionFromBody($body, $uid, $contact_id, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny)) {
$objecttype = Activity\ObjectType::IMAGE;
}
@ -475,7 +440,7 @@ function item_post(App $a) {
if (count($attaches)) {
foreach ($attaches as $attach) {
// Ensure to only modify attachments that you own
$srch = '<' . intval($original_contact_id) . '>';
$srch = '<' . intval($contact_id) . '>';
$condition = ['allow_cid' => $srch, 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '',
'id' => $attach];
@ -797,12 +762,6 @@ function item_post(App $a) {
}
}
// When we are doing some forum posting via ! we have to start the notifier manually.
// These kind of posts don't initiate the notifier call in the item class.
if ($only_to_forum) {
Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => false], "Notifier", Delivery::POST, (int)$datarray['uri-id'], (int)$datarray['uid']);
}
Logger::info('post_complete');
if ($api_source) {

View file

@ -21,12 +21,15 @@
namespace Friendica\Content;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
use Friendica\Core\Session;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Item as ModelItem;
use Friendica\Model\Tag;
use Friendica\Model\Post;
@ -53,7 +56,7 @@ class Item
$this->activity = $activity;
$this->l10n = $l10n;
}
/**
* Return array with details for categories and folders for an item
*
@ -479,7 +482,7 @@ class Item
if (empty($item['verb']) || $this->activity->isHidden($item['verb'])) {
return false;
}
// @TODO below if() block can be rewritten to a single line: $isVisible = allConditionsHere;
if ($this->activity->match($item['verb'], Activity::FOLLOW) &&
$item['object-type'] === Activity\ObjectType::NOTE &&
@ -487,7 +490,71 @@ class Item
$item['uid'] == local_user()) {
return false;
}
return true;
}
public function expandTags(array $item)
{
// Look for any tags and linkify them
$item['inform'] = '';
$private_forum = false;
$private_id = null;
$only_to_forum = false;
$forum_contact = [];
// Convert mentions in the body to a unified format
$item['body'] = BBCode::setMentions($item['body'], $item['uid'], $item['network']);
// Search for forum mentions
foreach (Tag::getFromBody($item['body'], Tag::TAG_CHARACTER[Tag::MENTION] . Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]) as $tag) {
$contact = Contact::getByURLForUser($tag[2], $item['uid']);
if (!empty($item['inform'])) {
$item['inform'] .= ',';
}
$item['inform'] .= 'cid:' . $contact['id'];
if (($item['gravity'] == GRAVITY_COMMENT) || empty($contact['cid']) || ($contact['contact-type'] != Contact::TYPE_COMMUNITY)) {
continue;
}
if (!empty($contact['prv']) || ($tag[1] == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION])) {
$private_forum = $contact['prv'];
$only_to_forum = ($tag[1] == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]);
$private_id = $contact['id'];
$forum_contact = $contact;
Logger::info('Private forum or exclusive mention', ['url' => $tag[2], 'mention' => $tag[1]]);
} elseif ($item['allow_cid'] == '<' . $contact['id'] . '>') {
$private_forum = false;
$only_to_forum = true;
$private_id = $contact['id'];
$forum_contact = $contact;
Logger::info('Public forum', ['url' => $tag[2], 'mention' => $tag[1]]);
} else {
Logger::info('Post with forum mention will not be converted to a forum post', ['url' => $tag[2], 'mention' => $tag[1]]);
}
}
Logger::info('Got inform', ['inform' => $item['inform']]);
if (($item['gravity'] == GRAVITY_PARENT) && !empty($forum_contact) && ($private_forum || $only_to_forum)) {
// we tagged a forum in a top level post. Now we change the post
$item['private'] = $private_forum ? ModelItem::PRIVATE : ModelItem::UNLISTED;
if ($only_to_forum) {
$item['postopts'] = '';
}
$item['deny_cid'] = '';
$item['deny_gid'] = '';
if ($private_forum) {
$item['allow_cid'] = '<' . $private_id . '>';
$item['allow_gid'] = '<' . Group::getIdForForum($forum_contact['id']) . '>';
} else {
$item['allow_cid'] = '';
$item['allow_gid'] = '';
}
}
return $item;
}
}

View file

@ -78,11 +78,6 @@ class Update extends BaseApi
$body = Markdown::toBBCode($request['status']);
}
// Avoids potential double expansion of existing links
$body = BBCode::performWithEscapedTags($body, ['url'], function ($body) {
return BBCode::expandTags($body);
});
$item = [];
$item['uid'] = $uid;
$item['verb'] = Activity::POST;
@ -127,6 +122,8 @@ class Update extends BaseApi
$item['object-type'] = Activity\ObjectType::NOTE;
}
$item = DI::contentItem()->expandTags($item);
if (!empty($request['media_ids'])) {
$ids = explode(',', $request['media_ids']);
} elseif (!empty($_FILES['media'])) {