diff --git a/doc/API-Entities.md b/doc/API-Entities.md index bd84cb7076..23fc2cec48 100644 --- a/doc/API-Entities.md +++ b/doc/API-Entities.md @@ -410,13 +410,13 @@ Ex: Wed May 23 06:01:13 +0000 2007 -startTime +start_time String (UTC YYYY-MM-DD HH:II:SS)) -endTime +end_time String (UTC YYYY-MM-DD HH:II:SS)) Optional (null date is 0001-01-01 00:00:00 diff --git a/doc/API-Friendica.md b/doc/API-Friendica.md index 726accf62a..8460fd4ab6 100644 --- a/doc/API-Friendica.md +++ b/doc/API-Friendica.md @@ -24,6 +24,32 @@ Returns a list of [Event](help/API-Entities#Event) entities for the current logg - `since_id`: (optional) minimum event id for pagination - `count`: maximum number of items returned, default 20 +### POST api/friendica/event_create + +Create a new event for the current logged in user. + +#### Parameters + +- `id` : (optional) id of event, event will be amended if supplied +- `name` : name of the event (required) +- `start_time` : start of the event (ISO), required +- `end_time` : (optional) end of the event, event is open end, if not supplied +- `desc` : (optional) description of the event +- `place` : (optional) location of the event +- `publish` : (optional) create message for event +- `allow_cid` : (optional) ACL-formatted list of allowed contact ids if private event +- `allow_gid` : (optional) ACL-formatted list of disallowed contact ids if private event +- `deny_cid` : (optional) ACL-formatted list of allowed group ids if private event +- `deny_gid` : (optional) ACL-formatted list of disallowed group ids if private event + +### POST api/friendica/event_delete + +Delete event from calendar (not the message) + +#### Parameters + +- `id` : id of event to be deleted + ### GET api/externalprofile/show Returns a [Contact](help/API-Entities#Contact) entity for the provided profile URL. diff --git a/mod/pubsub.php b/mod/pubsub.php index 918c55ee14..a740b7b81d 100644 --- a/mod/pubsub.php +++ b/mod/pubsub.php @@ -145,7 +145,7 @@ function pubsub_post(App $a) } // We only import feeds from OStatus here - if ($contact['network'] != Protocol::OSTATUS) { + if (!in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS])) { Logger::warning('Unexpected network', ['contact' => $contact]); hub_post_return(); } diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index a46b55f388..69f5fa6e81 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -1867,11 +1867,13 @@ class BBCode if ($try_oembed) { $text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", $try_oembed_callback, $text); $text = preg_replace_callback("/\[youtube\](www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", $try_oembed_callback, $text); + $text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/shorts\/.*?)\[\/youtube\]/ism", $try_oembed_callback, $text); $text = preg_replace_callback("/\[youtube\](https?:\/\/youtu.be\/.*?)\[\/youtube\]/ism", $try_oembed_callback, $text); } $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); + $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/shorts\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); $text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); if ($try_oembed) { diff --git a/src/Content/Text/HTML.php b/src/Content/Text/HTML.php index 9121087296..93afeac4d0 100644 --- a/src/Content/Text/HTML.php +++ b/src/Content/Text/HTML.php @@ -114,7 +114,7 @@ class HTML /** @var \DOMNode $child */ foreach ($node->childNodes as $key => $child) { /* Remove empty text nodes at the start or at the end of the children list */ - if ($key > 0 && $key < $node->childNodes->length - 1 || $child->nodeName != '#text' || trim($child->nodeValue)) { + if ($key > 0 && $key < $node->childNodes->length - 1 || $child->nodeName != '#text' || trim($child->nodeValue) !== '') { $newNode = $child->cloneNode(true); $node->parentNode->insertBefore($newNode, $node); } @@ -144,10 +144,10 @@ class HTML public static function toBBCode(string $message, string $basepath = ''): string { /* - * Check if message is empty to prevent a lot code below being executed + * Check if message is empty to prevent a lot of code below from being executed * for just an empty message. */ - if (empty($message)) { + if ($message === '') { return ''; } diff --git a/src/Content/Text/Markdown.php b/src/Content/Text/Markdown.php index 8173a62af7..3575c69a8b 100644 --- a/src/Content/Text/Markdown.php +++ b/src/Content/Text/Markdown.php @@ -126,6 +126,7 @@ class Markdown //$s = preg_replace("/([^\]\=]|^)(https?\:\/\/)(vimeo|youtu|www\.youtube|soundcloud)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[url=$2$3$4]$2$3$4[/url]',$s); $s = BBCode::pregReplaceInTag('/\[url\=?(.*?)\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/url\]/ism', '[youtube]$2[/youtube]', 'url', $s); $s = BBCode::pregReplaceInTag('/\[url\=https?:\/\/www.youtube.com\/watch\?v\=(.*?)\].*?\[\/url\]/ism' , '[youtube]$1[/youtube]', 'url', $s); + $s = BBCode::pregReplaceInTag('/\[url\=https?:\/\/www.youtube.com\/shorts\/(.*?)\].*?\[\/url\]/ism' , '[youtube]$1[/youtube]', 'url', $s); $s = BBCode::pregReplaceInTag('/\[url\=?(.*?)\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/url\]/ism' , '[vimeo]$2[/vimeo]' , 'url', $s); $s = BBCode::pregReplaceInTag('/\[url\=https?:\/\/vimeo.com\/([0-9]+)\](.*?)\[\/url\]/ism' , '[vimeo]$1[/vimeo]' , 'url', $s); diff --git a/src/Core/Worker/Cron.php b/src/Core/Worker/Cron.php index 2accbea1ce..0f2c4b41e7 100644 --- a/src/Core/Worker/Cron.php +++ b/src/Core/Worker/Cron.php @@ -193,7 +193,7 @@ class Cron */ private static function addIntros() { - $contacts = DBA::p("SELECT `uid`, `id`, `created` FROM `contact` WHERE `rel` = ? AND `pending` AND NOT EXISTS (SELECT `id` FROM `intro` WHERE `contact-id` = `contact`.`id`)", Contact::FOLLOWER); + $contacts = DBA::p("SELECT `uid`, `id`, `created` FROM `contact` WHERE `rel` = ? AND `pending` AND NOT `id` IN (SELECT `contact-id` FROM `intro`)", Contact::FOLLOWER); while ($contact = DBA::fetch($contacts)) { $fields = [ 'uid' => $contact['uid'], diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index 82fe70e3f1..62b023fb6f 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -1153,6 +1153,10 @@ class PostUpdate while ($contact = DBA::fetch($contacts)) { $id = $contact['id']; + if (is_null($contact['uri-id'])) { + $contact['uri-id'] = ItemURI::getIdByURI($contact['url']); + DBA::update('contact', ['uri-id' => $contact['uri-id']], ['id' => $contact['id']]); + } Contact::setAccountUser($contact['id'], $contact['uid'], $contact['uri-id'], $contact['url']); ++$rows; } diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 0448765d08..043f33c313 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -577,15 +577,15 @@ class APContact */ public static function isRelay(array $apcontact): bool { - if ($apcontact['nick'] != 'relay') { + if (empty($apcontact['nick']) || $apcontact['nick'] != 'relay') { return false; } - if ($apcontact['type'] == 'Application') { + if (!empty($apcontact['type']) && $apcontact['type'] == 'Application') { return true; } - if (in_array($apcontact['type'], ['Group', 'Service']) && is_null($apcontact['outbox'])) { + if (!empty($apcontact['type']) && in_array($apcontact['type'], ['Group', 'Service']) && is_null($apcontact['outbox'])) { return true; } diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 9e363bf372..a035d0021d 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -3388,7 +3388,7 @@ class Contact if (empty($contact['id']) && Network::isValidHttpUrl($url)) { Worker::add(PRIORITY_LOW, 'AddContact', 0, $url); ++$added; - } elseif (Probe::isProbable($contact['network']) && ($contact['next-update'] < DateTimeFormat::utcNow())) { + } elseif (!empty($contact['network']) && Probe::isProbable($contact['network']) && ($contact['next-update'] < DateTimeFormat::utcNow())) { Worker::add(['priority' => PRIORITY_LOW, 'dont_fork' => true], 'UpdateContact', $contact['id']); ++$updated; } else { diff --git a/src/Model/Nodeinfo.php b/src/Model/Nodeinfo.php index 84a14a294d..5ce7f89513 100644 --- a/src/Model/Nodeinfo.php +++ b/src/Model/Nodeinfo.php @@ -61,9 +61,9 @@ class Nodeinfo $logger->info('user statistics', $userStats); - $posts = DBA::count('post-thread', ["EXISTS(SELECT `uri-id` FROM `post-user` WHERE NOT `deleted` AND `origin` AND `uri-id` = `post-thread`.`uri-id`)"]); - $comments = DBA::count('post', ["NOT `deleted` AND `gravity` = ? AND EXISTS(SELECT `uri-id` FROM `post-user` WHERE `origin` AND `uri-id` = `post`.`uri-id`)", GRAVITY_COMMENT]); - $config->set('nodeinfo', 'local_posts', $posts); + $posts = DBA::count('post-thread', ["`uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE NOT `deleted` AND `origin`)"]); + $comments = DBA::count('post', ["NOT `deleted` AND `gravity` = ? AND `uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE `origin`)", GRAVITY_COMMENT]); + $config->set('nodeinfo', 'local_posts', $posts); $config->set('nodeinfo', 'local_comments', $comments); $logger->info('User actitivy', ['posts' => $posts, 'comments' => $comments]); diff --git a/src/Module/Api/Friendica/Events/Create.php b/src/Module/Api/Friendica/Events/Create.php new file mode 100644 index 0000000000..eb45b4974c --- /dev/null +++ b/src/Module/Api/Friendica/Events/Create.php @@ -0,0 +1,115 @@ +. + * + */ + +namespace Friendica\Module\Api\Friendica\Events; + +use Friendica\Core\Protocol; +use Friendica\Core\Worker; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\Event; +use Friendica\Model\Conversation; +use Friendica\Model\Item; +use Friendica\Module\BaseApi; +use Friendica\Network\HTTPException; +use Friendica\Util\DateTimeFormat; +use Friendica\Worker\Delivery; + +/** + * API endpoint: /api/friendica/event_create + */ +class Create extends BaseApi +{ + protected function post(array $request = []) + { + BaseApi::checkAllowedScope(BaseApi::SCOPE_WRITE); + $uid = BaseApi::getCurrentUserID(); + + // params + $request = $this->getRequest([ + 'id' => 0, //if provided, event will be amended + 'name' => '', //summary of the event + 'desc' => '', //description in BBCode + 'start_time' => '', //start_time, required + 'end_time' => '', //endtime, required if nofinish false + 'place' => '', //location of the event + 'publish' => 0, //publish message + 'allow_cid' => '', //array of allowed person, if access restricted + 'allow_gid' => '', //array of allowed groups, if access restricted + 'deny_cid' => '', //array of denied person, if access restricted + 'deny_gid' => '', //array of denied groups, if access restricted + ], $request); + + // error if no name specified + if (empty($request['name'])) { + throw new HTTPException\BadRequestException('event name not specified'); + } + + // error startDate is not specified + if (empty($request['start_time'])) { + throw new HTTPException\BadRequestException('startDate not specified'); + } + + // nofinish if end_time is not specified + if (empty($request['end_time'])) { + $finish = DBA::NULL_DATETIME; + $nofinish = true; + } else { + $finish = DateTimeFormat::convert($request['end_time'], 'UTC', DI::app()->getTimeZone()); + $nofinish = false; + } + + $start = DateTimeFormat::convert($request['start_time'], 'UTC', DI::app()->getTimeZone()); + + // create event + $event = []; + + $event['id'] = $request['id']; + $event['uid'] = $uid; + $event['type'] = 'event'; + $event['summary'] = $request['name']; + $event['desc'] = $request['desc']; + $event['location'] = $request['place']; + $event['start_time'] = $start; + $event['end_time'] = $finish; + $event['nofinish'] = $nofinish; + + $event['allow_cid'] = $request['allow_cid']; + $event['allow_gid'] = $request['allow_gid']; + $event['deny_cid'] = $request['deny_cid']; + $event['deny_gid'] = $request['deny_gid']; + $event['publish'] = $request['publish']; + + $event_id = Event::store($event); + + if (!empty($request['publish'])) { + $item = ['network' => Protocol::DFRN, 'protocol' => Conversation::PARCEL_DIRECT, 'direction' => Conversation::PUSH]; + $item = Event::getItemArrayForId($event_id, $item); + if (Item::insert($item)) { + Worker::add(PRIORITY_HIGH, "Notifier", Delivery::POST, (int)$item['uri-id'], $uid); + } + } + + $result = ['success' => true, 'event_id' => $event_id, 'event' => $event]; + + $this->response->exit('event_create', ['$result' => $result], $this->parameters['extension'] ?? null); + } +} diff --git a/src/Module/Api/Friendica/Events/Delete.php b/src/Module/Api/Friendica/Events/Delete.php new file mode 100644 index 0000000000..cf23b91ce0 --- /dev/null +++ b/src/Module/Api/Friendica/Events/Delete.php @@ -0,0 +1,64 @@ +. + * + */ + +namespace Friendica\Module\Api\Friendica\Events; + +use Friendica\Database\DBA; +use Friendica\Model\Event; +use Friendica\Module\BaseApi; +use Friendica\Network\HTTPException; + +/** + * API endpoint: /api/friendica/event_delete + */ + + +class Delete extends BaseApi +{ + protected function post(array $request = []) + { + self::checkAllowedScope(self::SCOPE_WRITE); + $uid = self::getCurrentUserID(); + + $request = $this->getRequest([ + 'id' => 0 + ], $request); + + // params + + // error if no id specified + if ($request['id'] == 0) { + throw new HTTPException\BadRequestException('id not specified'); + } + + // error message if specified id is not in database + if (!DBA::exists('event', ['uid' => $uid, 'id' => $request['id']])) { + throw new HTTPException\BadRequestException('id not available'); + } + + // delete event + $eventid = $request['id']; + Event::delete($eventid); + + $success = ['id' => $eventid, 'status' => 'deleted']; + $this->response->exit('event_delete', ['$result' => $success], $this->parameters['extension'] ?? null); + } +} diff --git a/src/Module/Api/Friendica/Events/Index.php b/src/Module/Api/Friendica/Events/Index.php index 257c9f06f4..3e930f614b 100644 --- a/src/Module/Api/Friendica/Events/Index.php +++ b/src/Module/Api/Friendica/Events/Index.php @@ -49,23 +49,23 @@ class Index extends BaseApi $items = []; foreach ($events as $event) { $items[] = [ - 'id' => intval($event['id']), - 'uid' => intval($event['uid']), - 'cid' => $event['cid'], - 'uri' => $event['uri'], - 'name' => $event['summary'], - 'desc' => BBCode::convertForUriId($event['uri-id'], $event['desc']), - 'startTime' => $event['start'], - 'endTime' => $event['finish'], - 'type' => $event['type'], - 'nofinish' => $event['nofinish'], - 'place' => $event['location'], - 'adjust' => 1, - 'ignore' => $event['ignore'], - 'allow_cid' => $event['allow_cid'], - 'allow_gid' => $event['allow_gid'], - 'deny_cid' => $event['deny_cid'], - 'deny_gid' => $event['deny_gid'] + 'id' => intval($event['id']), + 'uid' => intval($event['uid']), + 'cid' => $event['cid'], + 'uri' => $event['uri'], + 'name' => $event['summary'], + 'desc' => BBCode::convertForUriId($event['uri-id'], $event['desc']), + 'start_time' => $event['start'], + 'end_time' => $event['finish'], + 'type' => $event['type'], + 'nofinish' => $event['nofinish'], + 'place' => $event['location'], + 'adjust' => 1, + 'ignore' => $event['ignore'], + 'allow_cid' => $event['allow_cid'], + 'allow_gid' => $event['allow_gid'], + 'deny_cid' => $event['deny_cid'], + 'deny_gid' => $event['deny_gid'] ]; } diff --git a/src/Module/Api/Mastodon/Notifications.php b/src/Module/Api/Mastodon/Notifications.php index 490f4f83d5..4ab71d88f9 100644 --- a/src/Module/Api/Mastodon/Notifications.php +++ b/src/Module/Api/Mastodon/Notifications.php @@ -79,13 +79,13 @@ class Notifications extends BaseApi if (in_array(Notification::TYPE_INTRODUCTION, $request['exclude_types'])) { $condition = DBA::mergeConditions($condition, - ["(`vid` != ? OR `type` != ? OR NOT EXISTS (SELECT `id` FROM `contact` WHERE `id` = `actor-id` AND `pending`))", + ["(`vid` != ? OR `type` != ? OR NOT `actor-id` IN (SELECT `id` FROM `contact` WHERE `pending`))", Verb::getID(Activity::FOLLOW), Post\UserNotification::TYPE_NONE]); } if (in_array(Notification::TYPE_FOLLOW, $request['exclude_types'])) { $condition = DBA::mergeConditions($condition, - ["(`vid` != ? OR `type` != ? OR NOT EXISTS (SELECT `id` FROM `contact` WHERE `id` = `actor-id` AND NOT `pending`))", + ["(`vid` != ? OR `type` != ? OR NOT `actor-id` IN (SELECT `id` FROM `contact` WHERE NOT `pending`))", Verb::getID(Activity::FOLLOW), Post\UserNotification::TYPE_NONE]); } diff --git a/src/Module/Api/Mastodon/PushSubscription.php b/src/Module/Api/Mastodon/PushSubscription.php index 945ca63920..31e1b0eb12 100644 --- a/src/Module/Api/Mastodon/PushSubscription.php +++ b/src/Module/Api/Mastodon/PushSubscription.php @@ -21,19 +21,36 @@ namespace Friendica\Module\Api\Mastodon; -use Friendica\Core\Logger; -use Friendica\Core\System; -use Friendica\DI; +use Friendica\App; +use Friendica\Core\L10n; +use Friendica\Factory\Api\Mastodon\Error; +use Friendica\Factory\Api\Mastodon\Subscription as SubscriptionFactory; use Friendica\Model\Subscription; +use Friendica\Module\Api\ApiResponse; use Friendica\Module\BaseApi; use Friendica\Object\Api\Mastodon\Notification; +use Friendica\Util\Profiler; +use Psr\Log\LoggerInterface; /** * @see https://docs.joinmastodon.org/methods/notifications/push/ */ class PushSubscription extends BaseApi { - protected function post(array $request = []) + /** @var SubscriptionFactory */ + protected $subscriptionFac; + /** @var Error */ + protected $errorFac; + + public function __construct(App $app, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, ApiResponse $response, SubscriptionFactory $subscriptionFac, Error $errorFac, array $server, array $parameters = []) + { + parent::__construct($app, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); + + $this->subscriptionFac = $subscriptionFac; + $this->errorFac = $errorFac; + } + + protected function post(array $request = []): void { self::checkAllowedScope(self::SCOPE_PUSH); $uid = self::getCurrentUserID(); @@ -61,12 +78,13 @@ class PushSubscription extends BaseApi $ret = Subscription::replace($subscription); - Logger::info('Subscription stored', ['ret' => $ret, 'subscription' => $subscription]); + $this->logger->info('Subscription stored', ['ret' => $ret, 'subscription' => $subscription]); - return DI::mstdnSubscription()->createForApplicationIdAndUserId($application['id'], $uid)->toArray(); + $subscriptionObj = $this->subscriptionFac->createForApplicationIdAndUserId($application['id'], $uid); + $this->response->exitWithJson($subscriptionObj->toArray()); } - public function put(array $request = []) + public function put(array $request = []): void { self::checkAllowedScope(self::SCOPE_PUSH); $uid = self::getCurrentUserID(); @@ -78,8 +96,8 @@ class PushSubscription extends BaseApi $subscription = Subscription::select($application['id'], $uid, ['id']); if (empty($subscription)) { - Logger::info('Subscription not found', ['application-id' => $application['id'], 'uid' => $uid]); - DI::mstdnError()->RecordNotFound(); + $this->logger->info('Subscription not found', ['application-id' => $application['id'], 'uid' => $uid]); + $this->errorFac->RecordNotFound(); } $fields = [ @@ -94,12 +112,18 @@ class PushSubscription extends BaseApi $ret = Subscription::update($application['id'], $uid, $fields); - Logger::info('Subscription updated', ['result' => $ret, 'application-id' => $application['id'], 'uid' => $uid, 'fields' => $fields]); + $this->logger->info('Subscription updated', [ + 'result' => $ret, + 'application-id' => $application['id'], + 'uid' => $uid, + 'fields' => $fields, + ]); - return DI::mstdnSubscription()->createForApplicationIdAndUserId($application['id'], $uid)->toArray(); + $subscriptionObj = $this->subscriptionFac->createForApplicationIdAndUserId($application['id'], $uid); + $this->response->exitWithJson($subscriptionObj->toArray()); } - protected function delete(array $request = []) + protected function delete(array $request = []): void { self::checkAllowedScope(self::SCOPE_PUSH); $uid = self::getCurrentUserID(); @@ -107,24 +131,29 @@ class PushSubscription extends BaseApi $ret = Subscription::delete($application['id'], $uid); - Logger::info('Subscription deleted', ['result' => $ret, 'application-id' => $application['id'], 'uid' => $uid]); + $this->logger->info('Subscription deleted', [ + 'result' => $ret, + 'application-id' => $application['id'], + 'uid' => $uid, + ]); - System::jsonExit([]); + $this->response->exitWithJson([]); } - protected function rawContent(array $request = []) + protected function rawContent(array $request = []): void { self::checkAllowedScope(self::SCOPE_PUSH); $uid = self::getCurrentUserID(); $application = self::getCurrentApplication(); if (!Subscription::exists($application['id'], $uid)) { - Logger::info('Subscription not found', ['application-id' => $application['id'], 'uid' => $uid]); - DI::mstdnError()->RecordNotFound(); + $this->logger->info('Subscription not found', ['application-id' => $application['id'], 'uid' => $uid]); + $this->errorFac->RecordNotFound(); } - Logger::info('Fetch subscription', ['application-id' => $application['id'], 'uid' => $uid]); + $this->logger->info('Fetch subscription', ['application-id' => $application['id'], 'uid' => $uid]); - return DI::mstdnSubscription()->createForApplicationIdAndUserId($application['id'], $uid)->toArray(); + $subscriptionObj = $this->subscriptionFac->createForApplicationIdAndUserId($application['id'], $uid); + $this->response->exitWithJson($subscriptionObj->toArray()); } } diff --git a/src/Module/Api/Mastodon/Search.php b/src/Module/Api/Mastodon/Search.php index e3f462325e..27f99f00bf 100644 --- a/src/Module/Api/Mastodon/Search.php +++ b/src/Module/Api/Mastodon/Search.php @@ -180,7 +180,7 @@ class Search extends BaseApi $params = ['order' => ['name'], 'limit' => [$offset, $limit]]; - $condition = ["EXISTS(SELECT `tid` FROM `post-tag` WHERE `type` = ? AND `tid` = `id`) AND `name` LIKE ?", Tag::HASHTAG, $q . '%']; + $condition = ["`id` IN (SELECT `tid` FROM `post-tag` WHERE `type` = ?) AND `name` LIKE ?", Tag::HASHTAG, $q . '%']; $tags = DBA::select('tag', ['name'], $condition, $params); diff --git a/src/Module/Api/Mastodon/Timelines/PublicTimeline.php b/src/Module/Api/Mastodon/Timelines/PublicTimeline.php index b851974c38..d34deac079 100644 --- a/src/Module/Api/Mastodon/Timelines/PublicTimeline.php +++ b/src/Module/Api/Mastodon/Timelines/PublicTimeline.php @@ -92,7 +92,7 @@ class PublicTimeline extends BaseApi if (!empty($uid)) { $condition = DBA::mergeConditions($condition, - ["NOT EXISTS (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` = `parent-author-id` AND (`blocked` OR `ignored`))", $uid]); + ["NOT `parent-author-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND (`blocked` OR `ignored`))", $uid]); } $items = Post::selectPostsForUser($uid, ['uri-id'], $condition, $params); diff --git a/src/Module/Contact.php b/src/Module/Contact.php index ccc61d3438..05c4e05081 100644 --- a/src/Module/Contact.php +++ b/src/Module/Contact.php @@ -210,7 +210,7 @@ class Contact extends BaseModule switch ($type) { case 'blocked': - $sql_extra = " AND EXISTS(SELECT `id` from `user-contact` WHERE `contact`.`id` = `user-contact`.`cid` and `user-contact`.`uid` = ? and `user-contact`.`blocked`)"; + $sql_extra = " AND `id` IN (SELECT `cid` FROM `user-contact` WHERE `user-contact`.`uid` = ? AND `user-contact`.`blocked`)"; // This makes the query look for contact.uid = 0 array_unshift($sql_values, 0); break; @@ -218,7 +218,7 @@ class Contact extends BaseModule $sql_extra = " AND `hidden` AND NOT `blocked` AND NOT `pending`"; break; case 'ignored': - $sql_extra = " AND EXISTS(SELECT `id` from `user-contact` WHERE `contact`.`id` = `user-contact`.`cid` and `user-contact`.`uid` = ? and `user-contact`.`ignored`)"; + $sql_extra = " AND `id` IN (SELECT `cid` FROM `user-contact` WHERE `user-contact`.`uid` = ? AND `user-contact`.`ignored`)"; // This makes the query look for contact.uid = 0 array_unshift($sql_values, 0); break; @@ -227,8 +227,9 @@ class Contact extends BaseModule break; case 'pending': $sql_extra = " AND `pending` AND NOT `archive` AND NOT `failed` AND ((`rel` = ?) - OR EXISTS (SELECT `id` FROM `intro` WHERE `contact-id` = `contact`.`id` AND NOT `ignore`))"; + OR `id` IN (SELECT `contact-id` FROM `intro` WHERE `intro`.`uid` = ? AND NOT `ignore`))"; $sql_values[] = Model\Contact::SHARING; + $sql_values[] = local_user(); break; default: $sql_extra = " AND NOT `archive` AND NOT `blocked` AND NOT `pending`"; @@ -275,7 +276,7 @@ class Contact extends BaseModule } if ($group) { - $sql_extra .= " AND EXISTS(SELECT `id` FROM `group_member` WHERE `gid` = ? AND `contact`.`id` = `contact-id`)"; + $sql_extra .= " AND `id` IN (SELECT `contact-id` FROM `group_member` WHERE `gid` = ?)"; $sql_values[] = $group; } diff --git a/src/Module/Conversation/Community.php b/src/Module/Conversation/Community.php index 16e0f38afd..8d73f825f9 100644 --- a/src/Module/Conversation/Community.php +++ b/src/Module/Conversation/Community.php @@ -53,11 +53,17 @@ class Community extends BaseModule { $this->parseRequest(); + $t = Renderer::getMarkupTemplate("community.tpl"); + $o = Renderer::replaceMacros($t, [ + '$content' => '', + '$header' => '', + '$show_global_community_hint' => (self::$content == 'global') && DI::config()->get('system', 'show_global_community_hint'), + '$global_community_hint' => DI::l10n()->t("This community stream shows all public posts received by this node. They may not reflect the opinions of this node’s users.") + ]); + if (DI::pConfig()->get(local_user(), 'system', 'infinite_scroll')) { $tpl = Renderer::getMarkupTemplate('infinite_scroll_head.tpl'); - $o = Renderer::replaceMacros($tpl, ['$reload_uri' => DI::args()->getQueryString()]); - } else { - $o = ''; + $o .= Renderer::replaceMacros($tpl, ['$reload_uri' => DI::args()->getQueryString()]); } if (empty($_GET['mode']) || ($_GET['mode'] != 'raw')) { @@ -154,13 +160,7 @@ class Community extends BaseModule $o .= $pager->renderMinimal(count($items)); } - $t = Renderer::getMarkupTemplate("community.tpl"); - return Renderer::replaceMacros($t, [ - '$content' => $o, - '$header' => '', - '$show_global_community_hint' => (self::$content == 'global') && DI::config()->get('system', 'show_global_community_hint'), - '$global_community_hint' => DI::l10n()->t("This community stream shows all public posts received by this node. They may not reflect the opinions of this node’s users.") - ]); + return $o; } /** @@ -323,7 +323,7 @@ class Community extends BaseModule $condition[] = $item_id; } else { if (local_user() && !empty($_REQUEST['no_sharer'])) { - $condition[0] .= " AND NOT EXISTS (SELECT `uri-id` FROM `post-user` WHERE `post-user`.`uri-id` = `post-thread-user-view`.`uri-id` AND `post-user`.`uid` = ?)"; + $condition[0] .= " AND NOT `uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE `post-user`.`uid` = ?)"; $condition[] = local_user(); } diff --git a/src/Module/Conversation/Network.php b/src/Module/Conversation/Network.php index 848f36ce3e..c36876b347 100644 --- a/src/Module/Conversation/Network.php +++ b/src/Module/Conversation/Network.php @@ -413,7 +413,7 @@ class Network extends BaseModule $conditionStrings = DBA::mergeConditions($conditionStrings, ["`contact-id` IN (SELECT `contact-id` FROM `group_member` WHERE `gid` = ?)", self::$groupId]); } elseif (self::$forumContactId) { $conditionStrings = DBA::mergeConditions($conditionStrings, - ["((`contact-id` = ?) OR EXISTS(SELECT `uri-id` FROM `post-user-view` WHERE `post-user-view`.`parent-uri-id` = " . DBA::quoteIdentifier($table) . ".`uri-id` AND (`contact-id` = ? AND `gravity` = ? AND `vid` = ? AND `uid` = ?)))", + ["((`contact-id` = ?) OR `uri-id` IN (SELECT `parent-uri-id` FROM `post-user-view` WHERE (`contact-id` = ? AND `gravity` = ? AND `vid` = ? AND `uid` = ?)))", self::$forumContactId, self::$forumContactId, GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), local_user()]); } diff --git a/src/Module/Profile/Status.php b/src/Module/Profile/Status.php index f3015692f3..d851d5f474 100644 --- a/src/Module/Profile/Status.php +++ b/src/Module/Profile/Status.php @@ -175,10 +175,8 @@ class Status extends BaseProfile $condition = DBA::mergeConditions($condition, ["((`gravity` = ? AND `wall`) OR (`gravity` = ? AND `vid` = ? AND `origin` - AND EXISTS(SELECT `uri-id` FROM `post` WHERE `gravity` = ? AND `network` IN (?, ?, ?, ?) - AND `uri-id` = `post-user-view`.`thr-parent-id`)))", - GRAVITY_PARENT, GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), GRAVITY_PARENT, - Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::DIASPORA, Protocol::OSTATUS]); + AND `thr-parent-id` IN (SELECT `uri-id` FROM `post` WHERE `gravity` = ? AND `network` = ?)))", + GRAVITY_PARENT, GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), GRAVITY_PARENT, Protocol::ACTIVITYPUB]); $condition = DBA::mergeConditions($condition, ['uid' => $profile['uid'], 'network' => Protocol::FEDERATED, 'visible' => true, 'deleted' => false]); diff --git a/src/Network/Probe.php b/src/Network/Probe.php index f075a514ae..98d195ca18 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -77,7 +77,7 @@ class Probe public static function cleanURI(string $rawUri): string { // At first remove leading and trailing junk - $rawUri = trim($rawUri, "@#?:/ \t\n\r\0\x0B"); + $rawUri = trim($rawUri, "@#?: \t\n\r\0\x0B"); $rawUri = Network::convertToIdn($rawUri); diff --git a/src/Worker/UpdateServerPeers.php b/src/Worker/UpdateServerPeers.php index 8c916504ed..9ddbdcd56c 100644 --- a/src/Worker/UpdateServerPeers.php +++ b/src/Worker/UpdateServerPeers.php @@ -22,6 +22,7 @@ namespace Friendica\Worker; use Friendica\Core\Logger; +use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\GServer; diff --git a/static/routes.config.php b/static/routes.config.php index f009cc6b32..e19e3b7570 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -82,6 +82,8 @@ $apiRoutes = [ '/direct_messages_setseen[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\DirectMessages\Setseen::class, [ R::POST]], '/direct_messages_search[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\DirectMessages\Search ::class, [R::GET ]], '/events[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Events\Index::class, [R::GET ]], + '/event_create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Events\Create::class, [ R::POST]], + '/event_delete[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Events\Delete::class, [ R::POST]], '/group_show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Group\Show::class, [R::GET ]], '/group_create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Group\Create::class, [ R::POST]], '/group_delete[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Group\Delete::class, [ R::POST]], diff --git a/tests/src/Content/Text/HTMLTest.php b/tests/src/Content/Text/HTMLTest.php index 3fcdf064c4..bc352e5427 100644 --- a/tests/src/Content/Text/HTMLTest.php +++ b/tests/src/Content/Text/HTMLTest.php @@ -82,6 +82,10 @@ its surprisingly good", 'html' => "

Now playing

echo "main(i){for(i=0;;i++)putchar(((i*(i>>8|i>>9)&46&i>>8))^(i&i>>13|i>>6));}" | gcc -o a.out -x c - 2> /dev/null
 ./a.out | aplay -q 2> /dev/null

its surprisingly good

", ], + 'bug-11851-content-0' => [ + 'expectedBBCode' => '[url=https://dev-friendica.mrpetovan.com/profile/hypolite]@hypolite[/url] 0', + 'html' => '

@hypolite 0

', + ], ]; } diff --git a/tests/src/Module/Api/Mastodon/PushSubscriptionTest.php b/tests/src/Module/Api/Mastodon/PushSubscriptionTest.php new file mode 100644 index 0000000000..ae453e4586 --- /dev/null +++ b/tests/src/Module/Api/Mastodon/PushSubscriptionTest.php @@ -0,0 +1,62 @@ +. + * + */ + +namespace Friendica\Test\src\Module\Api\Mastodon; + +use Friendica\Test\src\Module\Api\ApiTest; + +class PushSubscriptionTest extends ApiTest +{ + /** + * Test the api_account_verify_credentials() function. + * + * @return void + */ + public function testApiAccountVerifyCredentials(): void + { + $this->markTestIncomplete('Needs mocking of whole applictaions/Apps first'); + + // $this->useHttpMethod(Router::POST); + // + // $response = (new PushSubscription(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), DI::mstdnSubscription(), DI::mstdnError(), [])) + // ->run(); + // + // $json = $this->toJson($response); + // print_r($json); + // + // $this->assertEquals(1,1); + } + + /** + * Test the api_account_verify_credentials() function without an authenticated user. + * + * @return void + */ + public function testApiAccountVerifyCredentialsWithoutAuthenticatedUser(): void + { + self::markTestIncomplete('Needs dynamic BasicAuth first'); + + // $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class); + // BasicAuth::setCurrentUserID(); + // $_SESSION['authenticated'] = false; + // api_account_verify_credentials('json'); + } +} diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index ef63672aa6..080bd7366a 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2022.09-rc\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-11 02:40-0400\n" +"POT-Creation-Date: 2022-09-25 07:08+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,7 +19,7 @@ msgstr "" #: mod/cal.php:46 mod/cal.php:50 mod/follow.php:39 mod/redir.php:36 -#: mod/redir.php:177 src/Module/Conversation/Community.php:181 +#: mod/redir.php:177 src/Module/Conversation/Community.php:183 #: src/Module/Debug/ItemBody.php:38 src/Module/Diaspora/Receive.php:57 #: src/Module/Item/Follow.php:42 src/Module/Item/Ignore.php:41 #: src/Module/Item/Pin.php:42 src/Module/Item/Pin.php:57 @@ -105,7 +105,7 @@ msgid "calendar" msgstr "" #: mod/display.php:143 mod/photos.php:802 -#: src/Module/Conversation/Community.php:175 src/Module/Directory.php:49 +#: src/Module/Conversation/Community.php:177 src/Module/Directory.php:49 #: src/Module/Search/Index.php:65 msgid "Public access denied." msgstr "" @@ -426,7 +426,7 @@ msgstr "" msgid "Basic" msgstr "" -#: mod/events.php:517 src/Module/Admin/Site.php:441 src/Module/Contact.php:474 +#: mod/events.php:517 src/Module/Admin/Site.php:441 src/Module/Contact.php:475 #: src/Module/Profile/Profile.php:249 msgid "Advanced" msgstr "" @@ -470,7 +470,7 @@ msgid "OStatus support is disabled. Contact can't be added." msgstr "" #: mod/follow.php:138 src/Content/Item.php:397 src/Content/Widget.php:80 -#: src/Model/Contact.php:1121 src/Model/Contact.php:1132 +#: src/Model/Contact.php:1146 src/Model/Contact.php:1157 #: view/theme/vier/theme.php:181 msgid "Connect/Follow" msgstr "" @@ -507,7 +507,7 @@ msgid "Add a personal note:" msgstr "" #: mod/follow.php:163 mod/unfollow.php:109 src/Module/BaseProfile.php:59 -#: src/Module/Contact.php:444 +#: src/Module/Contact.php:445 msgid "Status Messages and Posts" msgstr "" @@ -1070,7 +1070,7 @@ msgid "Rotate CCW (left)" msgstr "" #: mod/photos.php:1333 mod/photos.php:1389 mod/photos.php:1463 -#: src/Module/Contact.php:544 src/Module/Item/Compose.php:160 +#: src/Module/Contact.php:545 src/Module/Item/Compose.php:160 #: src/Object/Post.php:989 msgid "This is you" msgstr "" @@ -1411,7 +1411,7 @@ msgstr "" msgid "Friend Suggestions" msgstr "" -#: mod/tagger.php:78 src/Content/Item.php:297 src/Model/Item.php:2834 +#: mod/tagger.php:78 src/Content/Item.php:297 src/Model/Item.php:2846 msgid "photo" msgstr "" @@ -1557,17 +1557,17 @@ msgstr "" msgid "Apologies but the website is unavailable at the moment." msgstr "" -#: src/App/Page.php:276 +#: src/App/Page.php:281 msgid "Delete this item?" msgstr "" -#: src/App/Page.php:277 +#: src/App/Page.php:282 msgid "" "Block this author? They won't be able to follow you nor see your public " "posts, and you won't be able to see their posts and their notifications." msgstr "" -#: src/App/Page.php:347 +#: src/App/Page.php:352 msgid "toggle mobile" msgstr "" @@ -1595,16 +1595,16 @@ msgid "All contacts" msgstr "" #: src/BaseModule.php:424 src/Content/Widget.php:235 src/Core/ACL.php:194 -#: src/Module/Contact.php:367 src/Module/PermissionTooltip.php:122 +#: src/Module/Contact.php:368 src/Module/PermissionTooltip.php:122 #: src/Module/PermissionTooltip.php:144 msgid "Followers" msgstr "" -#: src/BaseModule.php:429 src/Content/Widget.php:236 src/Module/Contact.php:368 +#: src/BaseModule.php:429 src/Content/Widget.php:236 src/Module/Contact.php:369 msgid "Following" msgstr "" -#: src/BaseModule.php:434 src/Content/Widget.php:237 src/Module/Contact.php:369 +#: src/BaseModule.php:434 src/Content/Widget.php:237 src/Module/Contact.php:370 msgid "Mutual friends" msgstr "" @@ -1644,63 +1644,63 @@ msgstr "" msgid "The contact has been blocked from the node" msgstr "" -#: src/Console/MergeContacts.php:74 +#: src/Console/MergeContacts.php:75 #, php-format msgid "%d %s, %d duplicates." msgstr "" -#: src/Console/MergeContacts.php:77 +#: src/Console/MergeContacts.php:78 #, php-format msgid "uri-id is empty for contact %s." msgstr "" -#: src/Console/MergeContacts.php:90 +#: src/Console/MergeContacts.php:91 #, php-format msgid "No valid first contact found for uri-id %d." msgstr "" -#: src/Console/MergeContacts.php:101 +#: src/Console/MergeContacts.php:102 #, php-format msgid "Wrong duplicate found for uri-id %d in %d (url: %s != %s)." msgstr "" -#: src/Console/MergeContacts.php:105 +#: src/Console/MergeContacts.php:106 #, php-format msgid "Wrong duplicate found for uri-id %d in %d (nurl: %s != %s)." msgstr "" -#: src/Console/MergeContacts.php:141 +#: src/Console/MergeContacts.php:142 #, php-format msgid "Deletion of id %d failed" msgstr "" -#: src/Console/MergeContacts.php:143 +#: src/Console/MergeContacts.php:144 #, php-format msgid "Deletion of id %d was successful" msgstr "" -#: src/Console/MergeContacts.php:149 +#: src/Console/MergeContacts.php:150 #, php-format msgid "Updating \"%s\" in \"%s\" from %d to %d" msgstr "" -#: src/Console/MergeContacts.php:151 +#: src/Console/MergeContacts.php:152 msgid " - found" msgstr "" -#: src/Console/MergeContacts.php:158 +#: src/Console/MergeContacts.php:159 msgid " - failed" msgstr "" -#: src/Console/MergeContacts.php:160 +#: src/Console/MergeContacts.php:161 msgid " - success" msgstr "" -#: src/Console/MergeContacts.php:164 +#: src/Console/MergeContacts.php:165 msgid " - deleted" msgstr "" -#: src/Console/MergeContacts.php:167 +#: src/Console/MergeContacts.php:168 msgid " - done" msgstr "" @@ -2292,7 +2292,7 @@ msgstr "" msgid "show more" msgstr "" -#: src/Content/Item.php:288 src/Model/Item.php:2832 +#: src/Content/Item.php:288 src/Model/Item.php:2844 msgid "event" msgstr "" @@ -2300,42 +2300,42 @@ msgstr "" msgid "Follow Thread" msgstr "" -#: src/Content/Item.php:381 src/Model/Contact.php:1126 +#: src/Content/Item.php:381 src/Model/Contact.php:1151 msgid "View Status" msgstr "" -#: src/Content/Item.php:382 src/Content/Item.php:400 src/Model/Contact.php:1064 -#: src/Model/Contact.php:1118 src/Model/Contact.php:1127 +#: src/Content/Item.php:382 src/Content/Item.php:400 src/Model/Contact.php:1089 +#: src/Model/Contact.php:1143 src/Model/Contact.php:1152 #: src/Module/Directory.php:158 src/Module/Settings/Profile/Index.php:225 msgid "View Profile" msgstr "" -#: src/Content/Item.php:383 src/Model/Contact.php:1128 +#: src/Content/Item.php:383 src/Model/Contact.php:1153 msgid "View Photos" msgstr "" -#: src/Content/Item.php:384 src/Model/Contact.php:1119 -#: src/Model/Contact.php:1129 +#: src/Content/Item.php:384 src/Model/Contact.php:1144 +#: src/Model/Contact.php:1154 msgid "Network Posts" msgstr "" -#: src/Content/Item.php:385 src/Model/Contact.php:1120 -#: src/Model/Contact.php:1130 +#: src/Content/Item.php:385 src/Model/Contact.php:1145 +#: src/Model/Contact.php:1155 msgid "View Contact" msgstr "" -#: src/Content/Item.php:386 src/Model/Contact.php:1131 +#: src/Content/Item.php:386 src/Model/Contact.php:1156 msgid "Send PM" msgstr "" #: src/Content/Item.php:387 src/Module/Admin/Blocklist/Contact.php:100 #: src/Module/Admin/Users/Active.php:140 src/Module/Admin/Users/Index.php:154 -#: src/Module/Contact.php:398 src/Module/Contact/Profile.php:348 +#: src/Module/Contact.php:399 src/Module/Contact/Profile.php:348 #: src/Module/Contact/Profile.php:449 msgid "Block" msgstr "" -#: src/Content/Item.php:388 src/Module/Contact.php:399 +#: src/Content/Item.php:388 src/Module/Contact.php:400 #: src/Module/Contact/Profile.php:349 src/Module/Contact/Profile.php:457 #: src/Module/Notifications/Introductions.php:132 #: src/Module/Notifications/Introductions.php:204 @@ -2381,7 +2381,7 @@ msgid "Sign in" msgstr "" #: src/Content/Nav.php:192 src/Module/BaseProfile.php:56 -#: src/Module/Contact.php:433 src/Module/Contact/Profile.php:380 +#: src/Module/Contact.php:434 src/Module/Contact/Profile.php:380 #: src/Module/Settings/TwoFactor/Index.php:120 view/theme/frio/theme.php:236 msgid "Status" msgstr "" @@ -2392,7 +2392,7 @@ msgid "Your posts and conversations" msgstr "" #: src/Content/Nav.php:193 src/Module/BaseProfile.php:48 -#: src/Module/BaseSettings.php:55 src/Module/Contact.php:457 +#: src/Module/BaseSettings.php:55 src/Module/Contact.php:458 #: src/Module/Contact/Profile.php:382 src/Module/Profile/Profile.php:241 #: src/Module/Welcome.php:57 view/theme/frio/theme.php:237 msgid "Profile" @@ -2407,7 +2407,7 @@ msgid "Your photos" msgstr "" #: src/Content/Nav.php:195 src/Module/BaseProfile.php:72 -#: src/Module/BaseProfile.php:75 src/Module/Contact.php:449 +#: src/Module/BaseProfile.php:75 src/Module/Contact.php:450 #: view/theme/frio/theme.php:239 msgid "Media" msgstr "" @@ -2481,8 +2481,8 @@ msgstr "" #: src/Content/Nav.php:237 src/Content/Nav.php:296 #: src/Content/Text/HTML.php:899 src/Module/BaseProfile.php:125 -#: src/Module/BaseProfile.php:128 src/Module/Contact.php:370 -#: src/Module/Contact.php:464 view/theme/frio/theme.php:247 +#: src/Module/BaseProfile.php:128 src/Module/Contact.php:371 +#: src/Module/Contact.php:465 view/theme/frio/theme.php:247 msgid "Contacts" msgstr "" @@ -2639,8 +2639,8 @@ msgid "" "%2$s %3$s" msgstr "" -#: src/Content/Text/BBCode.php:1213 src/Model/Item.php:3408 -#: src/Model/Item.php:3414 src/Model/Item.php:3415 +#: src/Content/Text/BBCode.php:1213 src/Model/Item.php:3420 +#: src/Model/Item.php:3426 src/Model/Item.php:3427 msgid "Link to source" msgstr "" @@ -2712,7 +2712,7 @@ msgstr "" msgid "Examples: Robert Morgenstein, Fishing" msgstr "" -#: src/Content/Widget.php:82 src/Module/Contact.php:391 +#: src/Content/Widget.php:82 src/Module/Contact.php:392 #: src/Module/Directory.php:97 view/theme/vier/theme.php:183 msgid "Find" msgstr "" @@ -2739,7 +2739,7 @@ msgid "Local Directory" msgstr "" #: src/Content/Widget.php:211 src/Model/Group.php:587 -#: src/Module/Contact.php:354 src/Module/Welcome.php:76 +#: src/Module/Contact.php:355 src/Module/Welcome.php:76 msgid "Groups" msgstr "" @@ -2751,7 +2751,7 @@ msgstr "" msgid "Relationships" msgstr "" -#: src/Content/Widget.php:244 src/Module/Contact.php:306 +#: src/Content/Widget.php:244 src/Module/Contact.php:307 #: src/Module/Group.php:293 msgid "All Contacts" msgstr "" @@ -2795,7 +2795,7 @@ msgstr "" msgid "Organisations" msgstr "" -#: src/Content/Widget.php:523 src/Model/Contact.php:1553 +#: src/Content/Widget.php:523 src/Model/Contact.php:1582 msgid "News" msgstr "" @@ -3588,81 +3588,81 @@ msgstr "" msgid "Legacy module file not found: %s" msgstr "" -#: src/Model/Contact.php:1122 src/Model/Contact.php:1133 +#: src/Model/Contact.php:1147 src/Model/Contact.php:1158 msgid "UnFollow" msgstr "" -#: src/Model/Contact.php:1139 src/Module/Admin/Users/Pending.php:107 +#: src/Model/Contact.php:1164 src/Module/Admin/Users/Pending.php:107 #: src/Module/Notifications/Introductions.php:130 #: src/Module/Notifications/Introductions.php:202 msgid "Approve" msgstr "" -#: src/Model/Contact.php:1549 +#: src/Model/Contact.php:1578 msgid "Organisation" msgstr "" -#: src/Model/Contact.php:1557 +#: src/Model/Contact.php:1586 msgid "Forum" msgstr "" -#: src/Model/Contact.php:2710 +#: src/Model/Contact.php:2774 msgid "Disallowed profile URL." msgstr "" -#: src/Model/Contact.php:2715 src/Module/Friendica.php:81 +#: src/Model/Contact.php:2779 src/Module/Friendica.php:81 msgid "Blocked domain" msgstr "" -#: src/Model/Contact.php:2720 +#: src/Model/Contact.php:2784 msgid "Connect URL missing." msgstr "" -#: src/Model/Contact.php:2729 +#: src/Model/Contact.php:2793 msgid "" "The contact could not be added. Please check the relevant network " "credentials in your Settings -> Social Networks page." msgstr "" -#: src/Model/Contact.php:2771 +#: src/Model/Contact.php:2835 msgid "The profile address specified does not provide adequate information." msgstr "" -#: src/Model/Contact.php:2773 +#: src/Model/Contact.php:2837 msgid "No compatible communication protocols or feeds were discovered." msgstr "" -#: src/Model/Contact.php:2776 +#: src/Model/Contact.php:2840 msgid "An author or name was not found." msgstr "" -#: src/Model/Contact.php:2779 +#: src/Model/Contact.php:2843 msgid "No browser URL could be matched to this address." msgstr "" -#: src/Model/Contact.php:2782 +#: src/Model/Contact.php:2846 msgid "" "Unable to match @-style Identity Address with a known protocol or email " "contact." msgstr "" -#: src/Model/Contact.php:2783 +#: src/Model/Contact.php:2847 msgid "Use mailto: in front of address to force email check." msgstr "" -#: src/Model/Contact.php:2789 +#: src/Model/Contact.php:2853 msgid "" "The profile address specified belongs to a network which has been disabled " "on this site." msgstr "" -#: src/Model/Contact.php:2794 +#: src/Model/Contact.php:2858 msgid "" "Limited profile. This person will be unable to receive direct/personal " "notifications from you." msgstr "" -#: src/Model/Contact.php:2853 +#: src/Model/Contact.php:2917 msgid "Unable to retrieve contact information." msgstr "" @@ -3782,66 +3782,66 @@ msgstr "" msgid "Edit groups" msgstr "" -#: src/Model/Item.php:1944 +#: src/Model/Item.php:1956 #, php-format msgid "Detected languages in this post:\\n%s" msgstr "" -#: src/Model/Item.php:2836 +#: src/Model/Item.php:2848 msgid "activity" msgstr "" -#: src/Model/Item.php:2838 +#: src/Model/Item.php:2850 msgid "comment" msgstr "" -#: src/Model/Item.php:2841 +#: src/Model/Item.php:2853 msgid "post" msgstr "" -#: src/Model/Item.php:2957 +#: src/Model/Item.php:2969 #, php-format msgid "Content warning: %s" msgstr "" -#: src/Model/Item.php:3320 +#: src/Model/Item.php:3332 msgid "bytes" msgstr "" -#: src/Model/Item.php:3351 +#: src/Model/Item.php:3363 #, php-format msgid "%2$s (%3$d%%, %1$d vote)" msgid_plural "%2$s (%3$d%%, %1$d votes)" msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3353 +#: src/Model/Item.php:3365 #, php-format msgid "%2$s (%1$d vote)" msgid_plural "%2$s (%1$d votes)" msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3358 +#: src/Model/Item.php:3370 #, php-format msgid "%d voter. Poll end: %s" msgid_plural "%d voters. Poll end: %s" msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3360 +#: src/Model/Item.php:3372 #, php-format msgid "%d voter." msgid_plural "%d voters." msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3362 +#: src/Model/Item.php:3374 #, php-format msgid "Poll end: %s" msgstr "" -#: src/Model/Item.php:3396 src/Model/Item.php:3397 +#: src/Model/Item.php:3408 src/Model/Item.php:3409 msgid "View on separate page" msgstr "" @@ -4357,8 +4357,8 @@ msgstr "" msgid "List of active accounts" msgstr "" -#: src/Module/Admin/BaseUsers.php:67 src/Module/Contact.php:314 -#: src/Module/Contact.php:374 +#: src/Module/Admin/BaseUsers.php:67 src/Module/Contact.php:315 +#: src/Module/Contact.php:375 msgid "Pending" msgstr "" @@ -4366,8 +4366,8 @@ msgstr "" msgid "List of pending registrations" msgstr "" -#: src/Module/Admin/BaseUsers.php:75 src/Module/Contact.php:322 -#: src/Module/Contact.php:375 +#: src/Module/Admin/BaseUsers.php:75 src/Module/Contact.php:323 +#: src/Module/Contact.php:376 msgid "Blocked" msgstr "" @@ -4460,7 +4460,7 @@ msgstr "" #: src/Module/Admin/Blocklist/Contact.php:101 #: src/Module/Admin/Users/Blocked.php:142 src/Module/Admin/Users/Index.php:156 -#: src/Module/Contact.php:398 src/Module/Contact/Profile.php:348 +#: src/Module/Contact.php:399 src/Module/Contact/Profile.php:348 #: src/Module/Contact/Profile.php:449 msgid "Unblock" msgstr "" @@ -6733,7 +6733,7 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: src/Module/BaseProfile.php:51 src/Module/Contact.php:460 +#: src/Module/BaseProfile.php:51 src/Module/Contact.php:461 msgid "Profile Details" msgstr "" @@ -6807,110 +6807,110 @@ msgid_plural "%d contacts edited." msgstr[0] "" msgstr[1] "" -#: src/Module/Contact.php:309 +#: src/Module/Contact.php:310 msgid "Show all contacts" msgstr "" -#: src/Module/Contact.php:317 +#: src/Module/Contact.php:318 msgid "Only show pending contacts" msgstr "" -#: src/Module/Contact.php:325 +#: src/Module/Contact.php:326 msgid "Only show blocked contacts" msgstr "" -#: src/Module/Contact.php:330 src/Module/Contact.php:377 +#: src/Module/Contact.php:331 src/Module/Contact.php:378 #: src/Object/Post.php:339 msgid "Ignored" msgstr "" -#: src/Module/Contact.php:333 +#: src/Module/Contact.php:334 msgid "Only show ignored contacts" msgstr "" -#: src/Module/Contact.php:338 src/Module/Contact.php:378 +#: src/Module/Contact.php:339 src/Module/Contact.php:379 msgid "Archived" msgstr "" -#: src/Module/Contact.php:341 +#: src/Module/Contact.php:342 msgid "Only show archived contacts" msgstr "" -#: src/Module/Contact.php:346 src/Module/Contact.php:376 +#: src/Module/Contact.php:347 src/Module/Contact.php:377 msgid "Hidden" msgstr "" -#: src/Module/Contact.php:349 +#: src/Module/Contact.php:350 msgid "Only show hidden contacts" msgstr "" -#: src/Module/Contact.php:357 +#: src/Module/Contact.php:358 msgid "Organize your contact groups" msgstr "" -#: src/Module/Contact.php:389 +#: src/Module/Contact.php:390 msgid "Search your contacts" msgstr "" -#: src/Module/Contact.php:390 src/Module/Search/Index.php:207 +#: src/Module/Contact.php:391 src/Module/Search/Index.php:207 #, php-format msgid "Results for: %s" msgstr "" -#: src/Module/Contact.php:397 +#: src/Module/Contact.php:398 msgid "Update" msgstr "" -#: src/Module/Contact.php:399 src/Module/Contact/Profile.php:349 +#: src/Module/Contact.php:400 src/Module/Contact/Profile.php:349 #: src/Module/Contact/Profile.php:457 msgid "Unignore" msgstr "" -#: src/Module/Contact.php:401 +#: src/Module/Contact.php:402 msgid "Batch Actions" msgstr "" -#: src/Module/Contact.php:436 +#: src/Module/Contact.php:437 msgid "Conversations started by this contact" msgstr "" -#: src/Module/Contact.php:441 +#: src/Module/Contact.php:442 msgid "Posts and Comments" msgstr "" -#: src/Module/Contact.php:452 +#: src/Module/Contact.php:453 msgid "Posts containing media objects" msgstr "" -#: src/Module/Contact.php:467 +#: src/Module/Contact.php:468 msgid "View all known contacts" msgstr "" -#: src/Module/Contact.php:477 +#: src/Module/Contact.php:478 msgid "Advanced Contact Settings" msgstr "" -#: src/Module/Contact.php:511 +#: src/Module/Contact.php:512 msgid "Mutual Friendship" msgstr "" -#: src/Module/Contact.php:515 +#: src/Module/Contact.php:516 msgid "is a fan of yours" msgstr "" -#: src/Module/Contact.php:519 +#: src/Module/Contact.php:520 msgid "you are a fan of" msgstr "" -#: src/Module/Contact.php:537 +#: src/Module/Contact.php:538 msgid "Pending outgoing contact request" msgstr "" -#: src/Module/Contact.php:539 +#: src/Module/Contact.php:540 msgid "Pending incoming contact request" msgstr "" -#: src/Module/Contact.php:552 src/Module/Contact/Profile.php:334 +#: src/Module/Contact.php:553 src/Module/Contact/Profile.php:334 #, php-format msgid "Visit %s's profile [%s]" msgstr "" @@ -7256,50 +7256,50 @@ msgstr "" msgid "Yes" msgstr "" -#: src/Module/Conversation/Community.php:68 -msgid "Local Community" -msgstr "" - -#: src/Module/Conversation/Community.php:71 -msgid "Posts from local users on this server" -msgstr "" - -#: src/Module/Conversation/Community.php:79 -msgid "Global Community" -msgstr "" - -#: src/Module/Conversation/Community.php:82 -msgid "Posts from users of the whole federated network" -msgstr "" - -#: src/Module/Conversation/Community.php:115 -msgid "Own Contacts" -msgstr "" - -#: src/Module/Conversation/Community.php:119 -msgid "Include" -msgstr "" - -#: src/Module/Conversation/Community.php:120 -msgid "Hide" -msgstr "" - -#: src/Module/Conversation/Community.php:137 src/Module/Search/Index.php:152 -#: src/Module/Search/Index.php:194 -msgid "No results." -msgstr "" - -#: src/Module/Conversation/Community.php:162 +#: src/Module/Conversation/Community.php:61 msgid "" "This community stream shows all public posts received by this node. They may " "not reflect the opinions of this node’s users." msgstr "" -#: src/Module/Conversation/Community.php:199 +#: src/Module/Conversation/Community.php:76 +msgid "Local Community" +msgstr "" + +#: src/Module/Conversation/Community.php:79 +msgid "Posts from local users on this server" +msgstr "" + +#: src/Module/Conversation/Community.php:87 +msgid "Global Community" +msgstr "" + +#: src/Module/Conversation/Community.php:90 +msgid "Posts from users of the whole federated network" +msgstr "" + +#: src/Module/Conversation/Community.php:123 +msgid "Own Contacts" +msgstr "" + +#: src/Module/Conversation/Community.php:127 +msgid "Include" +msgstr "" + +#: src/Module/Conversation/Community.php:128 +msgid "Hide" +msgstr "" + +#: src/Module/Conversation/Community.php:145 src/Module/Search/Index.php:152 +#: src/Module/Search/Index.php:194 +msgid "No results." +msgstr "" + +#: src/Module/Conversation/Community.php:201 msgid "Community option not available." msgstr "" -#: src/Module/Conversation/Community.php:215 +#: src/Module/Conversation/Community.php:217 msgid "Not available." msgstr "" @@ -11079,11 +11079,11 @@ msgstr "" msgid "(no subject)" msgstr "" -#: src/Worker/PushSubscription.php:111 +#: src/Worker/PushSubscription.php:110 msgid "Notification from Friendica" msgstr "" -#: src/Worker/PushSubscription.php:112 +#: src/Worker/PushSubscription.php:111 msgid "Empty Post" msgstr ""