use Friendica\Content\Feature;
use Friendica\Content\Text\BBCode;
-use Friendica\Content\Text\Plaintext;
use Friendica\Core\Cache\Duration;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
use Friendica\Model\Conversation;
use Friendica\Model\GServer;
use Friendica\Model\Item;
-use Friendica\Model\ItemURI;
-use Friendica\Model\Profile;
use Friendica\Model\Photo;
use Friendica\Model\Post;
+use Friendica\Model\Profile;
use Friendica\Model\Tag;
use Friendica\Model\User;
+use Friendica\Network\HTTPException;
use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Relay;
$activity_id = ActivityPub\Transmitter::activityIDFromContact($contact['id']);
$success = ActivityPub\Transmitter::sendActivity('Follow', $url, 0, $activity_id);
if ($success) {
- DBA::update('contact', ['rel' => Contact::FRIEND], ['id' => $contact['id']]);
+ Contact::update(['rel' => Contact::FRIEND], ['id' => $contact['id']]);
}
return $success;
$success = self::sendContactUndo($url, $contact['id'], 0);
if ($success || $force) {
- DBA::update('contact', ['rel' => Contact::NOTHING], ['id' => $contact['id']]);
+ Contact::update(['rel' => Contact::NOTHING], ['id' => $contact['id']]);
}
return $success;
/**
* Return the ActivityPub profile of the given user
*
- * @param integer $uid User ID
+ * @param int $uid User ID
* @return array with profile data
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ * @throws HTTPException\NotFoundException
+ * @throws HTTPException\InternalServerErrorException
*/
- public static function getProfile($uid)
+ public static function getProfile(int $uid): array
{
$owner = User::getOwnerDataById($uid);
+ if (!isset($owner['id'])) {
+ DI::logger()->error('Unable to find owner data for uid', ['uid' => $uid, 'callstack' => System::callstack(20)]);
+ throw new HTTPException\NotFoundException('User not found.');
+ }
$data = ['@context' => ActivityPub::CONTEXT];
$data['id'] = $owner['url'];
$data['summary'] = BBCode::convertForUriId($owner['uri-id'] ?? 0, $owner['about'], BBCode::EXTERNAL);
}
+ if (!empty($owner['xmpp']) || !empty($owner['matrix'])) {
+ $data['vcard:hasInstantMessage'] = [];
+
+ if (!empty($owner['xmpp'])) {
+ $data['vcard:hasInstantMessage'][] = 'xmpp:' . $owner['xmpp'];
+ }
+ if (!empty($owner['matrix'])) {
+ $data['vcard:hasInstantMessage'][] = 'matrix:' . $owner['matrix'];
+ }
+ }
+
$data['url'] = $owner['url'];
$data['manuallyApprovesFollowers'] = in_array($owner['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP]);
- $data['discoverable'] = $owner['net-publish'];
+ $data['discoverable'] = (bool)$owner['net-publish'];
$data['publicKey'] = ['id' => $owner['url'] . '#main-key',
'owner' => $owner['url'],
'publicKeyPem' => $owner['pubkey']];
$data['endpoints'] = ['sharedInbox' => DI::baseUrl() . '/inbox'];
- $data['icon'] = ['type' => 'Image', 'url' => Contact::getAvatarUrlForId($owner['id'], '', $owner['updated'])];
+ $data['icon'] = ['type' => 'Image', 'url' => User::getAvatarUrlForId($uid)];
$resourceid = Photo::ridFromURI($owner['photo']);
if (!empty($resourceid)) {
}
}
+ $custom_fields = [];
+
+ foreach (DI::profileField()->selectByContactId(0, $uid) as $profile_field) {
+ $custom_fields[] = [
+ 'type' => 'PropertyValue',
+ 'name' => $profile_field->label,
+ 'value' => BBCode::convertForUriId($owner['uri-id'], $profile_field->value)
+ ];
+ };
+
+ if (!empty($custom_fields)) {
+ $data['attachment'] = $custom_fields;
+ }
+
$data['generator'] = self::getService();
// tags: https://kitty.town/@inmysocks/100656097926961126.json
}
$reply = DBA::selectFirst('mail', ['uri', 'uri-id', 'from-url'], ['parent-uri' => $mail['parent-uri'], 'reply' => false]);
+ if (!DBA::isResult($reply)) {
+ $reply = $mail;
+ }
// Making the post more compatible for Mastodon by:
// - Making it a note and not an article (no title)
return $attachments;
}
- /**
- * Callback function to replace a Friendica style mention in a mention that is used on AP
- *
- * @param array $match Matching values for the callback
- * @return string Replaced mention
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- private static function mentionCallback($match)
- {
- if (empty($match[1])) {
- return '';
- }
-
- $data = Contact::getByURL($match[1], false, ['url', 'alias', 'nick']);
- if (empty($data['nick'])) {
- return $match[0];
- }
-
- return '[url=' . $data['url'] . ']@' . $data['nick'] . '[/url]';
- }
-
/**
* Callback function to replace a Friendica style mention in a mention for a summary
*
if ($type == 'Event') {
$data = array_merge($data, self::createEvent($item));
} else {
- $regexp = "/[@!]\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
- $body = preg_replace_callback($regexp, ['self', 'mentionCallback'], $body);
+ $body = BBCode::setMentionsToNicknames($body);
$data['content'] = BBCode::convertForUriId($item['uri-id'], $body, BBCode::ACTIVITYPUB);
}
// The contentMap does contain the unmodified HTML.
$language = self::getLanguage($item);
if (!empty($language)) {
- $regexp = "/[@!]\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
- $richbody = preg_replace_callback($regexp, ['self', 'mentionCallback'], $item['body']);
+ $richbody = BBCode::setMentionsToNicknames($item['body'] ?? '');
$richbody = BBCode::removeAttachment($richbody);
$data['contentMap'][$language] = BBCode::convertForUriId($item['uri-id'], $richbody, BBCode::EXTERNAL);
* @param string $inbox Target inbox
*
* @return boolean was the transmission successful?
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ * @throws HTTPException\InternalServerErrorException
+ * @throws HTTPException\NotFoundException
* @throws \ImagickException
*/
- public static function sendProfileUpdate($uid, $inbox)
+ public static function sendProfileUpdate(int $uid, string $inbox): bool
{
$owner = User::getOwnerDataById($uid);
$profile = APContact::getByURL($owner['url']);
* @param string $target Target profile
* @param $id
* @param integer $uid User ID
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ * @return bool Operation success
+ * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
- public static function sendContactReject($target, $id, $uid)
+ public static function sendContactReject($target, $id, $uid): bool
{
$profile = APContact::getByURL($target);
if (empty($profile['inbox'])) {
Logger::warning('No inbox found for target', ['target' => $target, 'profile' => $profile]);
- return;
+ return false;
}
$owner = User::getOwnerDataById($uid);
Logger::debug('Sending reject to ' . $target . ' for user ' . $uid . ' with id ' . $id);
$signed = LDSignature::sign($data, $owner);
- HTTPSignature::transmit($signed, $profile['inbox'], $uid);
+ return HTTPSignature::transmit($signed, $profile['inbox'], $uid);
}
/**