* @throws HTTPException\InternalServerErrorException
* @see json_encode()
*/
- public function jsonExit($content, string $content_type = 'application/json', int $options = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
+ public function jsonExit($content, string $content_type = 'application/json; charset=utf-8', int $options = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
{
$this->httpExit(json_encode($content, $options), ICanCreateResponses::TYPE_JSON, $content_type);
}
$pcid,
$contact,
Contact\User::isBlocked($cid, $uid),
- Contact\User::isIgnored($cid, $uid)
+ Contact\User::isIgnored($cid, $uid),
+ Contact\User::isIsBlocked($cid, $uid),
);
}
}
], $request);
if (empty($request['id'])) {
- $this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity());
+ $this->jsonExit([]);
}
if (!is_array($request['id'])) {
$limit = min($request['limit'], 40);
+ if (Network::isValidHttpUrl($request['q']) && ($request['offset'] == 0)) {
+ $this->searchLinks($uid, $request['q'], $request['type']);
+ }
+
$result = ['accounts' => [], 'statuses' => [], 'hashtags' => []];
if (empty($request['type']) || ($request['type'] == 'accounts')) {
$this->jsonExit($result);
}
+ /**
+ * Search for links (either accounts or statuses). Return an empty result otherwise
+ *
+ * @param integer $uid User id
+ * @param string $q Search term (HTTP link)
+ * @param string $type Search type (or empty if not provided)
+ */
+ private function searchLinks(int $uid, string $q, string $type)
+ {
+ $result = ['accounts' => [], 'statuses' => [], 'hashtags' => []];
+
+ $data = ['uri-id' => -1, 'type' => Post\Media::UNKNOWN, 'url' => $q];
+ $data = Post\Media::fetchAdditionalData($data);
+
+ if ((empty($type) || ($type == 'statuses')) && in_array($data['type'], [Post\Media::HTML, Post\Media::ACTIVITY, Post\Media::UNKNOWN])) {
+ $q = Network::convertToIdn($q);
+ // If the user-specific search failed, we search and probe a public post
+ $item_id = Item::fetchByLink($q, $uid) ?: Item::fetchByLink($q);
+ if ($item_id && $item = Post::selectFirst(['uri-id'], ['id' => $item_id])) {
+ $result['statuses'] = [DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid, self::appSupportsQuotes())];
+ $this->jsonExit($result);
+ }
+ }
+
+ if ((empty($type) || ($type == 'accounts')) && in_array($data['type'], [Post\Media::HTML, Post\Media::ACCOUNT, Post\Media::UNKNOWN])) {
+ $id = Contact::getIdForURL($q, 0, false);
+ if ($id) {
+ $result['accounts'] = [DI::mstdnAccount()->createFromContactId($id, $uid)];
+ $this->jsonExit($result);
+ }
+ }
+
+ if (in_array($data['type'], [Post\Media::HTML, Post\Media::TEXT, Post\Media::ACCOUNT, Post\Media::ACTIVITY, Post\Media::UNKNOWN])) {
+ $this->jsonExit($result);
+ }
+ }
+
/**
* @param int $uid
* @param string $q
*/
private function searchAccounts(int $uid, string $q, bool $resolve, int $limit, int $offset, bool $following)
{
- if (($offset == 0) && (strrpos($q, '@') > 0 || Network::isValidHttpUrl($q))
- && $id = Contact::getIdForURL($q, 0, $resolve ? null : false)
- ) {
+ if (($offset == 0) && (strrpos($q, '@') > 0) && $id = Contact::getIdForURL($q, 0, $resolve ? null : false)) {
return DI::mstdnAccount()->createFromContactId($id, $uid);
}
*/
private function searchStatuses(int $uid, string $q, string $account_id, int $max_id, int $min_id, int $limit, int $offset)
{
- if (Network::isValidHttpUrl($q)) {
- // Unique post search, any offset greater than 0 should return empty result
- if ($offset > 0) {
- return [];
- }
- $q = Network::convertToIdn($q);
- // If the user-specific search failed, we search and probe a public post
- $item_id = Item::fetchByLink($q, $uid) ?: Item::fetchByLink($q);
- if ($item_id && $item = Post::selectFirst(['uri-id'], ['id' => $item_id])) {
- return DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid, self::appSupportsQuotes());
- }
- }
-
$params = ['order' => ['uri-id' => true], 'limit' => [$offset, $limit]];
if (substr($q, 0, 1) == '#') {
/** @var bool */
protected $discoverable;
/** @var bool */
+ protected $indexable;
+ /** @var bool */
protected $group;
/** @var string|null (Datetime) */
protected $created_at;
protected $note;
/** @var string (URL)*/
protected $url;
+ /** @var string (URL)*/
+ protected $uri;
/** @var string (URL) */
protected $avatar;
/** @var string (URL) */
protected $statuses_count;
/** @var string|null (Datetime) */
protected $last_status_at = null;
+ /** @var bool */
+ protected $hide_collections = false;
/** @var Emoji[] */
protected $emojis;
/** @var Account|null */
$this->locked = (bool)$account['manually-approve'];
$this->bot = ($account['contact-type'] == Contact::TYPE_NEWS);
$this->discoverable = !$account['unsearchable'];
+ $this->indexable = $this->discoverable;
$this->group = ($account['contact-type'] == Contact::TYPE_COMMUNITY);
$this->created_at = DateTimeFormat::utc($account['created'] ?: DBA::NULL_DATETIME, DateTimeFormat::JSON);
$this->note = BBCode::convertForUriId($account['uri-id'], $account['about'], BBCode::EXTERNAL);
- $this->url = $account['url'];
+ $this->url = $account['alias'] ?: $account['url'];
+ $this->uri = $account['url'];
$this->avatar = Contact::getAvatarUrlForId($account['id'] ?? 0 ?: $account['pid'], Proxy::SIZE_SMALL, $account['updated'], $account['guid'] ?? '');
$this->avatar_static = Contact::getAvatarUrlForId($account['id'] ?? 0 ?: $account['pid'], Proxy::SIZE_SMALL, $account['updated'], $account['guid'] ?? '', true);
$this->header = Contact::getHeaderUrlForId($account['id'] ?? 0 ?: $account['pid'], '', $account['updated'], $account['guid'] ?? '');
unset($application['redirect_uri']);
}
- if (empty($application['website'])) {
- unset($application['website']);
+ if (empty($application['vapid_key'])) {
+ unset($application['vapid_key']);
}
return $application;
/** @var string */
protected $remote_url;
/** @var string */
+ protected $preview_remote_url;
+ /** @var string */
protected $text_url;
/** @var string */
protected $description;
$this->url = $url;
$this->preview_url = $preview;
$this->remote_url = $remote;
- $this->text_url = $this->remote_url ?? $this->url;
$this->description = $attachment['description'];
$this->blurhash = $attachment['blurhash'];
if ($type === 'image') {
/** @var string */
protected $image;
/** @var string */
+ protected $image_description = '';
+ /** @var string */
protected $embed_url;
/** @var string */
protected $blurhash;
+ /** @var string|null (Datetime) */
+ protected $published_at;
+ /** @var array */
+ protected $authors = [];
/** @var array */
protected $history;
return [];
}
+ if (empty($this->history)) {
+ unset($this->history);
+ }
+
return parent::toArray();
}
}
protected $blocking = false;
/** @var bool */
protected $domain_blocking = false;
+ /** @var bool */
+ protected $blocked_by = false;
/**
* Unsupported
- * @var bool
+ * @var array
*/
- protected $blocked_by = false;
+ protected $languages = [];
/**
* Unsupported
- * @var string
+ * @var bool
*/
+ protected $requested_by = false;
+ /** @var string */
protected $note = '';
/**
* @param bool $blocked "true" if user is blocked
* @param bool $muted "true" if user is muted
*/
- public function __construct(int $contactId, array $contactRecord, bool $blocked = false, bool $muted = false)
+ public function __construct(int $contactId, array $contactRecord, bool $blocked = false, bool $muted = false, bool $isBlocked = false)
{
$this->id = (string)$contactId;
$this->following = false;
$this->muting = (bool)($contactRecord['readonly'] ?? false) || $muted;
$this->notifying = (bool)$contactRecord['notify_new_posts'] ?? false;
$this->blocking = (bool)($contactRecord['blocked'] ?? false) || $blocked;
+ $this->blocked_by = $isBlocked;
$this->note = $contactRecord['info'];
}
protected $pinned = false;
/** @var string */
protected $content;
+ /** @var array */
+ protected $filtered = [];
/** @var Status|null */
protected $reblog = null;
/** @var Status|null - Akkoma extension, see issue https://github.com/friendica/friendica/issues/12603 */
$this->history = $history;
$this->following = $following;
}
+
+ public function toArray(): array
+ {
+ if (empty($this->history)) {
+ unset($this->history);
+ }
+
+ return parent::toArray();
+ }
}