Merge pull request #10769 from MrPetovan/task/10734-unfollow-hook
Rework contact termination to separate protocol-level and contact-level
This commit is contained in:
commit
51c7a7452c
|
@ -494,7 +494,8 @@ Called when unfollowing a remote contact on a non-native network (like Twitter)
|
||||||
|
|
||||||
Hook data:
|
Hook data:
|
||||||
- **contact** (input): the remote contact (uid = local unfollowing user id) array.
|
- **contact** (input): the remote contact (uid = local unfollowing user id) array.
|
||||||
- **dissolve** (input): whether to stop sharing with the remote contact as well.
|
- **two_way** (input): wether to stop sharing with the remote contact as well.
|
||||||
|
- **result** (output): wether the unfollowing is successful or not.
|
||||||
|
|
||||||
## Complete list of hook callbacks
|
## Complete list of hook callbacks
|
||||||
|
|
||||||
|
|
|
@ -3778,11 +3778,11 @@ api_register_func('api/direct_messages/destroy', 'api_direct_messages_destroy',
|
||||||
*
|
*
|
||||||
* @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
|
* @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
|
||||||
* @return string|array
|
* @return string|array
|
||||||
* @throws BadRequestException
|
* @throws HTTPException\BadRequestException
|
||||||
* @throws ForbiddenException
|
* @throws HTTPException\ExpectationFailedException
|
||||||
* @throws ImagickException
|
* @throws HTTPException\ForbiddenException
|
||||||
* @throws InternalServerErrorException
|
* @throws HTTPException\InternalServerErrorException
|
||||||
* @throws NotFoundException
|
* @throws HTTPException\NotFoundException
|
||||||
* @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy.html
|
* @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy.html
|
||||||
*/
|
*/
|
||||||
function api_friendships_destroy($type)
|
function api_friendships_destroy($type)
|
||||||
|
@ -3790,25 +3790,31 @@ function api_friendships_destroy($type)
|
||||||
$uid = api_user();
|
$uid = api_user();
|
||||||
|
|
||||||
if ($uid === false) {
|
if ($uid === false) {
|
||||||
throw new ForbiddenException();
|
throw new HTTPException\ForbiddenException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$owner = User::getOwnerDataById($uid);
|
||||||
|
if (!$owner) {
|
||||||
|
Logger::notice(API_LOG_PREFIX . 'No owner {uid} found', ['module' => 'api', 'action' => 'friendships_destroy', 'uid' => $uid]);
|
||||||
|
throw new HTTPException\NotFoundException('Error Processing Request');
|
||||||
}
|
}
|
||||||
|
|
||||||
$contact_id = $_REQUEST['user_id'] ?? 0;
|
$contact_id = $_REQUEST['user_id'] ?? 0;
|
||||||
|
|
||||||
if (empty($contact_id)) {
|
if (empty($contact_id)) {
|
||||||
Logger::notice(API_LOG_PREFIX . 'No user_id specified', ['module' => 'api', 'action' => 'friendships_destroy']);
|
Logger::notice(API_LOG_PREFIX . 'No user_id specified', ['module' => 'api', 'action' => 'friendships_destroy']);
|
||||||
throw new BadRequestException("no user_id specified");
|
throw new HTTPException\BadRequestException('no user_id specified');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Contact by given id
|
// Get Contact by given id
|
||||||
$contact = DBA::selectFirst('contact', ['url'], ['id' => $contact_id, 'uid' => 0, 'self' => false]);
|
$contact = DBA::selectFirst('contact', ['url'], ['id' => $contact_id, 'uid' => 0, 'self' => false]);
|
||||||
|
|
||||||
if(!DBA::isResult($contact)) {
|
if(!DBA::isResult($contact)) {
|
||||||
Logger::notice(API_LOG_PREFIX . 'No contact found for ID {contact}', ['module' => 'api', 'action' => 'friendships_destroy', 'contact' => $contact_id]);
|
Logger::notice(API_LOG_PREFIX . 'No public contact found for ID {contact}', ['module' => 'api', 'action' => 'friendships_destroy', 'contact' => $contact_id]);
|
||||||
throw new NotFoundException("no contact found to given ID");
|
throw new HTTPException\NotFoundException('no contact found to given ID');
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = $contact["url"];
|
$url = $contact['url'];
|
||||||
|
|
||||||
$condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)",
|
$condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)",
|
||||||
$uid, Contact::SHARING, Contact::FRIEND, Strings::normaliseLink($url),
|
$uid, Contact::SHARING, Contact::FRIEND, Strings::normaliseLink($url),
|
||||||
|
@ -3817,40 +3823,35 @@ function api_friendships_destroy($type)
|
||||||
|
|
||||||
if (!DBA::isResult($contact)) {
|
if (!DBA::isResult($contact)) {
|
||||||
Logger::notice(API_LOG_PREFIX . 'Not following contact', ['module' => 'api', 'action' => 'friendships_destroy']);
|
Logger::notice(API_LOG_PREFIX . 'Not following contact', ['module' => 'api', 'action' => 'friendships_destroy']);
|
||||||
throw new NotFoundException("Not following Contact");
|
throw new HTTPException\NotFoundException('Not following Contact');
|
||||||
}
|
|
||||||
|
|
||||||
if (!in_array($contact['network'], Protocol::NATIVE_SUPPORT)) {
|
|
||||||
Logger::notice(API_LOG_PREFIX . 'Not supported for {network}', ['module' => 'api', 'action' => 'friendships_destroy', 'network' => $contact['network']]);
|
|
||||||
throw new ExpectationFailedException("Not supported");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$dissolve = ($contact['rel'] == Contact::SHARING);
|
$dissolve = ($contact['rel'] == Contact::SHARING);
|
||||||
|
|
||||||
$owner = User::getOwnerDataById($uid);
|
try {
|
||||||
if ($owner) {
|
$result = Contact::terminateFriendship($owner, $contact, $dissolve);
|
||||||
Contact::terminateFriendship($owner, $contact, $dissolve);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Logger::notice(API_LOG_PREFIX . 'No owner {uid} found', ['module' => 'api', 'action' => 'friendships_destroy', 'uid' => $uid]);
|
|
||||||
throw new NotFoundException("Error Processing Request");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sharing-only contacts get deleted as there no relationship any more
|
if ($result === null) {
|
||||||
if ($dissolve) {
|
Logger::notice(API_LOG_PREFIX . 'Not supported for {network}', ['module' => 'api', 'action' => 'friendships_destroy', 'network' => $contact['network']]);
|
||||||
Contact::remove($contact['id']);
|
throw new HTTPException\ExpectationFailedException('Unfollowing is currently not supported by this contact\'s network.');
|
||||||
} else {
|
}
|
||||||
Contact::update(['rel' => Contact::FOLLOWER], ['id' => $contact['id']]);
|
|
||||||
|
if ($result === false) {
|
||||||
|
throw new HTTPException\ServiceUnavailableException('Unable to unfollow this contact, please retry in a few minutes or contact your administrator.');
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Logger::error(API_LOG_PREFIX . $e->getMessage(), ['owner' => $owner, 'contact' => $contact, 'dissolve' => $dissolve]);
|
||||||
|
throw new HTTPException\InternalServerErrorException('Unable to unfollow this contact, please contact your administrator');
|
||||||
}
|
}
|
||||||
|
|
||||||
// "uid" and "self" are only needed for some internal stuff, so remove it from here
|
// "uid" and "self" are only needed for some internal stuff, so remove it from here
|
||||||
unset($contact["uid"]);
|
unset($contact['uid']);
|
||||||
unset($contact["self"]);
|
unset($contact['self']);
|
||||||
|
|
||||||
// Set screen_name since Twidere requests it
|
// Set screen_name since Twidere requests it
|
||||||
$contact["screen_name"] = $contact["nick"];
|
$contact['screen_name'] = $contact['nick'];
|
||||||
|
|
||||||
return api_format_data("friendships-destroy", $type, ['user' => $contact]);
|
return api_format_data('friendships-destroy', $type, ['user' => $contact]);
|
||||||
}
|
}
|
||||||
api_register_func('api/friendships/destroy', 'api_friendships_destroy', true, API_METHOD_POST);
|
api_register_func('api/friendships/destroy', 'api_friendships_destroy', true, API_METHOD_POST);
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,12 @@ function unfollow_process(string $url)
|
||||||
|
|
||||||
$uid = local_user();
|
$uid = local_user();
|
||||||
|
|
||||||
|
$owner = User::getOwnerDataById($uid);
|
||||||
|
if (!$owner) {
|
||||||
|
\Friendica\Module\Security\Logout::init();
|
||||||
|
// NOTREACHED
|
||||||
|
}
|
||||||
|
|
||||||
$condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)",
|
$condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)",
|
||||||
$uid, Contact::SHARING, Contact::FRIEND, Strings::normaliseLink($url),
|
$uid, Contact::SHARING, Contact::FRIEND, Strings::normaliseLink($url),
|
||||||
Strings::normaliseLink($url), $url];
|
Strings::normaliseLink($url), $url];
|
||||||
|
@ -131,27 +137,30 @@ function unfollow_process(string $url)
|
||||||
// NOTREACHED
|
// NOTREACHED
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array($contact['network'], Protocol::NATIVE_SUPPORT)) {
|
|
||||||
notice(DI::l10n()->t('Unfollowing is currently not supported by your network.'));
|
|
||||||
DI::baseUrl()->redirect($base_return_path . '/' . $contact['id']);
|
|
||||||
// NOTREACHED
|
|
||||||
}
|
|
||||||
|
|
||||||
$dissolve = ($contact['rel'] == Contact::SHARING);
|
$dissolve = ($contact['rel'] == Contact::SHARING);
|
||||||
|
|
||||||
$owner = User::getOwnerDataById($uid);
|
$notice_message = '';
|
||||||
if ($owner) {
|
$return_path = $base_return_path . '/' . $contact['id'];
|
||||||
Contact::terminateFriendship($owner, $contact, $dissolve);
|
|
||||||
}
|
try {
|
||||||
|
$result = Contact::terminateFriendship($owner, $contact, $dissolve);
|
||||||
// Sharing-only contacts get deleted as there no relationship anymore
|
|
||||||
if ($dissolve) {
|
if ($result === null) {
|
||||||
Contact::remove($contact['id']);
|
$notice_message = DI::l10n()->t('Unfollowing is currently not supported by this contact\'s network.');
|
||||||
$return_path = $base_return_path;
|
}
|
||||||
} else {
|
|
||||||
Contact::update(['rel' => Contact::FOLLOWER], ['id' => $contact['id']]);
|
if ($result === false) {
|
||||||
$return_path = $base_return_path . '/' . $contact['id'];
|
$notice_message = DI::l10n()->t('Unable to unfollow this contact, please retry in a few minutes or contact your administrator.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result === true) {
|
||||||
|
$notice_message = DI::l10n()->t('Contact was successfully unfollowed');
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
DI::logger()->error($e->getMessage(), ['owner' => $owner, 'contact' => $contact, 'dissolve' => $dissolve]);
|
||||||
|
$notice_message = DI::l10n()->t('Unable to unfollow this contact, please contact your administrator');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
notice($notice_message);
|
||||||
DI::baseUrl()->redirect($return_path);
|
DI::baseUrl()->redirect($return_path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace Friendica\Console;
|
||||||
|
|
||||||
use Console_Table;
|
use Console_Table;
|
||||||
use Friendica\App;
|
use Friendica\App;
|
||||||
|
use Friendica\DI;
|
||||||
use Friendica\Model\Contact as ContactModel;
|
use Friendica\Model\Contact as ContactModel;
|
||||||
use Friendica\Model\User as UserModel;
|
use Friendica\Model\User as UserModel;
|
||||||
use Friendica\Network\Probe;
|
use Friendica\Network\Probe;
|
||||||
|
@ -177,11 +178,12 @@ HELP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an unfriend message. Does not remove the contact
|
* Sends an unfriend message.
|
||||||
*
|
*
|
||||||
* @return bool True, if the command was successful
|
* @return bool True, if the command was successful
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private function terminateContact()
|
private function terminateContact(): bool
|
||||||
{
|
{
|
||||||
$cid = $this->getArgument(1);
|
$cid = $this->getArgument(1);
|
||||||
if (empty($cid)) {
|
if (empty($cid)) {
|
||||||
|
@ -199,7 +201,23 @@ HELP;
|
||||||
|
|
||||||
$user = UserModel::getById($contact['uid']);
|
$user = UserModel::getById($contact['uid']);
|
||||||
|
|
||||||
$result = ContactModel::terminateFriendship($user, $contact);
|
try {
|
||||||
|
$result = ContactModel::terminateFriendship($user, $contact);
|
||||||
|
if ($result === null) {
|
||||||
|
throw new RuntimeException('Unfollowing is currently not supported by this contact\'s network.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result === false) {
|
||||||
|
throw new RuntimeException('Unable to unfollow this contact, please retry in a few minutes or check the logs.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out('Contact was successfully unfollowed');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DI::logger()->error($e->getMessage(), ['owner' => $user, 'contact' => $contact]);
|
||||||
|
throw new RuntimeException('Unable to unfollow this contact, please check the log');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,6 +22,12 @@
|
||||||
namespace Friendica\Core;
|
namespace Friendica\Core;
|
||||||
|
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Network\HTTPException;
|
||||||
|
use Friendica\Protocol\Activity;
|
||||||
|
use Friendica\Protocol\ActivityPub;
|
||||||
|
use Friendica\Protocol\Diaspora;
|
||||||
|
use Friendica\Protocol\OStatus;
|
||||||
|
use Friendica\Protocol\Salmon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage compatibility with federated networks
|
* Manage compatibility with federated networks
|
||||||
|
@ -157,4 +163,63 @@ class Protocol
|
||||||
{
|
{
|
||||||
return $display_name . ' (' . self::getAddrFromProfileUrl($profile_url) . ')';
|
return $display_name . ' (' . self::getAddrFromProfileUrl($profile_url) . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an unfriend message. Does not remove the contact
|
||||||
|
*
|
||||||
|
* @param array $user User unfriending
|
||||||
|
* @param array $contact Contact unfriended
|
||||||
|
* @param boolean $two_way Revoke eventual inbound follow as well
|
||||||
|
* @return bool|null true if successful, false if not, null if no action was performed
|
||||||
|
* @throws HTTPException\InternalServerErrorException
|
||||||
|
* @throws \ImagickException
|
||||||
|
*/
|
||||||
|
public static function terminateFriendship(array $user, array $contact, bool $two_way = false): bool
|
||||||
|
{
|
||||||
|
if (empty($contact['network'])) {
|
||||||
|
throw new \InvalidArgumentException('Missing network key in contact array');
|
||||||
|
}
|
||||||
|
|
||||||
|
$protocol = $contact['network'];
|
||||||
|
if (($protocol == Protocol::DFRN) && !empty($contact['protocol'])) {
|
||||||
|
$protocol = $contact['protocol'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($protocol, [Protocol::OSTATUS, Protocol::DFRN])) {
|
||||||
|
// create an unfollow slap
|
||||||
|
$item = [];
|
||||||
|
$item['verb'] = Activity::O_UNFOLLOW;
|
||||||
|
$item['gravity'] = GRAVITY_ACTIVITY;
|
||||||
|
$item['follow'] = $contact['url'];
|
||||||
|
$item['body'] = '';
|
||||||
|
$item['title'] = '';
|
||||||
|
$item['guid'] = '';
|
||||||
|
$item['uri-id'] = 0;
|
||||||
|
$slap = OStatus::salmon($item, $user);
|
||||||
|
|
||||||
|
if (empty($contact['notify'])) {
|
||||||
|
throw new \InvalidArgumentException('Missing expected "notify" key in OStatus/DFRN contact');
|
||||||
|
}
|
||||||
|
|
||||||
|
return Salmon::slapper($user, $contact['notify'], $slap) === 0;
|
||||||
|
} elseif ($protocol == Protocol::DIASPORA) {
|
||||||
|
return Diaspora::sendUnshare($user, $contact) > 0;
|
||||||
|
} elseif ($protocol == Protocol::ACTIVITYPUB) {
|
||||||
|
if ($two_way) {
|
||||||
|
ActivityPub\Transmitter::sendContactReject($contact['url'], $contact['hub-verify'], $user['uid']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ActivityPub\Transmitter::sendContactUndo($contact['url'], $contact['id'], $user['uid']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Catch-all addon hook
|
||||||
|
$hook_data = [
|
||||||
|
'contact' => $contact,
|
||||||
|
'two_way' => $two_way,
|
||||||
|
'result' => null
|
||||||
|
];
|
||||||
|
Hook::callAll('unfollow', $hook_data);
|
||||||
|
|
||||||
|
return $hook_data['result'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -809,7 +809,6 @@ class Contact
|
||||||
* Marks a contact for removal
|
* Marks a contact for removal
|
||||||
*
|
*
|
||||||
* @param int $id contact id
|
* @param int $id contact id
|
||||||
* @return null
|
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public static function remove($id)
|
public static function remove($id)
|
||||||
|
@ -828,56 +827,26 @@ class Contact
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an unfriend message. Does not remove the contact
|
* Sends an unfriend message. Removes the contact for two-way unfriending or sharing only protocols (feed an mail)
|
||||||
*
|
*
|
||||||
* @param array $user User unfriending
|
* @param array $user User unfriending
|
||||||
* @param array $contact Contact unfriended
|
* @param array $contact Contact unfriended
|
||||||
* @param boolean $dissolve Remove the contact on the remote side
|
* @param boolean $two_way Revoke eventual inbound follow as well
|
||||||
* @return void
|
* @return bool|null true if successful, false if not, null if no action was performed
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws HTTPException\InternalServerErrorException
|
||||||
* @throws \ImagickException
|
* @throws \ImagickException
|
||||||
*/
|
*/
|
||||||
public static function terminateFriendship(array $user, array $contact, $dissolve = false)
|
public static function terminateFriendship(array $user, array $contact, bool $two_way = false): bool
|
||||||
{
|
{
|
||||||
if (empty($contact['network'])) {
|
$result = Protocol::terminateFriendship($user, $contact, $two_way);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$protocol = $contact['network'];
|
if ($two_way || in_array($contact['network'], [Protocol::FEED, Protocol::MAIL])) {
|
||||||
if (($protocol == Protocol::DFRN) && !empty($contact['protocol'])) {
|
self::remove($contact['id']);
|
||||||
$protocol = $contact['protocol'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array($protocol, [Protocol::OSTATUS, Protocol::DFRN])) {
|
|
||||||
// create an unfollow slap
|
|
||||||
$item = [];
|
|
||||||
$item['verb'] = Activity::O_UNFOLLOW;
|
|
||||||
$item['gravity'] = GRAVITY_ACTIVITY;
|
|
||||||
$item['follow'] = $contact["url"];
|
|
||||||
$item['body'] = '';
|
|
||||||
$item['title'] = '';
|
|
||||||
$item['guid'] = '';
|
|
||||||
$item['uri-id'] = 0;
|
|
||||||
$slap = OStatus::salmon($item, $user);
|
|
||||||
|
|
||||||
if (!empty($contact['notify'])) {
|
|
||||||
Salmon::slapper($user, $contact['notify'], $slap);
|
|
||||||
}
|
|
||||||
} elseif ($protocol == Protocol::DIASPORA) {
|
|
||||||
Diaspora::sendUnshare($user, $contact);
|
|
||||||
} elseif ($protocol == Protocol::ACTIVITYPUB) {
|
|
||||||
ActivityPub\Transmitter::sendContactUndo($contact['url'], $contact['id'], $user['uid']);
|
|
||||||
|
|
||||||
if ($dissolve) {
|
|
||||||
ActivityPub\Transmitter::sendContactReject($contact['url'], $contact['hub-verify'], $user['uid']);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$hook_data = [
|
self::update(['rel' => Contact::FOLLOWER], ['id' => $contact['id']]);
|
||||||
'contact' => $contact,
|
|
||||||
'dissolve' => $dissolve,
|
|
||||||
];
|
|
||||||
Hook::callAll('unfollow', $hook_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -703,7 +703,7 @@ class Notifier
|
||||||
}
|
}
|
||||||
|
|
||||||
while($contact = DBA::fetch($contacts_stmt)) {
|
while($contact = DBA::fetch($contacts_stmt)) {
|
||||||
Contact::terminateFriendship($owner, $contact, true);
|
Protocol::terminateFriendship($owner, $contact, true);
|
||||||
}
|
}
|
||||||
DBA::close($contacts_stmt);
|
DBA::close($contacts_stmt);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 2021.12-dev\n"
|
"Project-Id-Version: 2021.12-dev\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-10-02 11:56+0000\n"
|
"POT-Creation-Date: 2021-10-02 08:34-0400\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -37,7 +37,7 @@ msgstr[1] ""
|
||||||
msgid "Monthly posting limit of %d post reached. The post was rejected."
|
msgid "Monthly posting limit of %d post reached. The post was rejected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: include/api.php:4429 mod/photos.php:89 mod/photos.php:198 mod/photos.php:626
|
#: include/api.php:4430 mod/photos.php:89 mod/photos.php:198 mod/photos.php:626
|
||||||
#: mod/photos.php:1035 mod/photos.php:1052 mod/photos.php:1599
|
#: mod/photos.php:1035 mod/photos.php:1052 mod/photos.php:1599
|
||||||
#: src/Model/User.php:1169 src/Model/User.php:1177 src/Model/User.php:1185
|
#: src/Model/User.php:1169 src/Model/User.php:1177 src/Model/User.php:1185
|
||||||
#: src/Module/Settings/Profile/Photo/Crop.php:101
|
#: src/Module/Settings/Profile/Photo/Crop.php:101
|
||||||
|
@ -718,7 +718,7 @@ msgid "OStatus support is disabled. Contact can't be added."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mod/follow.php:138 src/Content/Item.php:463 src/Content/Widget.php:76
|
#: mod/follow.php:138 src/Content/Item.php:463 src/Content/Widget.php:76
|
||||||
#: src/Model/Contact.php:1077 src/Model/Contact.php:1090
|
#: src/Model/Contact.php:1046 src/Model/Contact.php:1059
|
||||||
#: view/theme/vier/theme.php:172
|
#: view/theme/vier/theme.php:172
|
||||||
msgid "Connect/Follow"
|
msgid "Connect/Follow"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -2278,11 +2278,11 @@ msgid ""
|
||||||
"select \"Export account\""
|
"select \"Export account\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mod/unfollow.php:65 mod/unfollow.php:129
|
#: mod/unfollow.php:65 mod/unfollow.php:135
|
||||||
msgid "You aren't following this contact."
|
msgid "You aren't following this contact."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mod/unfollow.php:71 mod/unfollow.php:135
|
#: mod/unfollow.php:71
|
||||||
msgid "Unfollowing is currently not supported by your network."
|
msgid "Unfollowing is currently not supported by your network."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2290,6 +2290,24 @@ msgstr ""
|
||||||
msgid "Disconnect/Unfollow"
|
msgid "Disconnect/Unfollow"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: mod/unfollow.php:149
|
||||||
|
msgid "Unfollowing is currently not supported by this contact's network."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mod/unfollow.php:153
|
||||||
|
msgid ""
|
||||||
|
"Unable to unfollow this contact, please retry in a few minutes or contact "
|
||||||
|
"your administrator."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mod/unfollow.php:157
|
||||||
|
msgid "Contact was successfully unfollowed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mod/unfollow.php:161
|
||||||
|
msgid "Unable to unfollow this contact, please contact your administrator"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: mod/videos.php:120
|
#: mod/videos.php:120
|
||||||
msgid "No videos selected"
|
msgid "No videos selected"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -3002,31 +3020,31 @@ msgstr ""
|
||||||
msgid "Follow Thread"
|
msgid "Follow Thread"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Item.php:443 src/Model/Contact.php:1082
|
#: src/Content/Item.php:443 src/Model/Contact.php:1051
|
||||||
msgid "View Status"
|
msgid "View Status"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Item.php:444 src/Content/Item.php:466 src/Model/Contact.php:1008
|
#: src/Content/Item.php:444 src/Content/Item.php:466 src/Model/Contact.php:977
|
||||||
#: src/Model/Contact.php:1074 src/Model/Contact.php:1083
|
#: src/Model/Contact.php:1043 src/Model/Contact.php:1052
|
||||||
#: src/Module/Directory.php:160 src/Module/Settings/Profile/Index.php:223
|
#: src/Module/Directory.php:160 src/Module/Settings/Profile/Index.php:223
|
||||||
msgid "View Profile"
|
msgid "View Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Item.php:445 src/Model/Contact.php:1084
|
#: src/Content/Item.php:445 src/Model/Contact.php:1053
|
||||||
msgid "View Photos"
|
msgid "View Photos"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Item.php:446 src/Model/Contact.php:1075
|
#: src/Content/Item.php:446 src/Model/Contact.php:1044
|
||||||
#: src/Model/Contact.php:1085
|
#: src/Model/Contact.php:1054
|
||||||
msgid "Network Posts"
|
msgid "Network Posts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Item.php:447 src/Model/Contact.php:1076
|
#: src/Content/Item.php:447 src/Model/Contact.php:1045
|
||||||
#: src/Model/Contact.php:1086
|
#: src/Model/Contact.php:1055
|
||||||
msgid "View Contact"
|
msgid "View Contact"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Item.php:448 src/Model/Contact.php:1088
|
#: src/Content/Item.php:448 src/Model/Contact.php:1057
|
||||||
msgid "Send PM"
|
msgid "Send PM"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3049,7 +3067,7 @@ msgstr ""
|
||||||
msgid "Languages"
|
msgid "Languages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Item.php:458 src/Model/Contact.php:1089
|
#: src/Content/Item.php:458 src/Model/Contact.php:1058
|
||||||
msgid "Poke"
|
msgid "Poke"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3499,7 +3517,7 @@ msgstr ""
|
||||||
msgid "Organisations"
|
msgid "Organisations"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Widget.php:529 src/Model/Contact.php:1505
|
#: src/Content/Widget.php:529 src/Model/Contact.php:1474
|
||||||
msgid "News"
|
msgid "News"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -4363,85 +4381,85 @@ msgstr ""
|
||||||
msgid "Legacy module file not found: %s"
|
msgid "Legacy module file not found: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:1078 src/Model/Contact.php:1091
|
#: src/Model/Contact.php:1047 src/Model/Contact.php:1060
|
||||||
msgid "UnFollow"
|
msgid "UnFollow"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:1087
|
#: src/Model/Contact.php:1056
|
||||||
msgid "Drop Contact"
|
msgid "Drop Contact"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:1097 src/Module/Admin/Users/Pending.php:107
|
#: src/Model/Contact.php:1066 src/Module/Admin/Users/Pending.php:107
|
||||||
#: src/Module/Notifications/Introductions.php:111
|
#: src/Module/Notifications/Introductions.php:111
|
||||||
#: src/Module/Notifications/Introductions.php:183
|
#: src/Module/Notifications/Introductions.php:183
|
||||||
msgid "Approve"
|
msgid "Approve"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:1501
|
#: src/Model/Contact.php:1470
|
||||||
msgid "Organisation"
|
msgid "Organisation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:1509
|
#: src/Model/Contact.php:1478
|
||||||
msgid "Forum"
|
msgid "Forum"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2365
|
#: src/Model/Contact.php:2334
|
||||||
msgid "Disallowed profile URL."
|
msgid "Disallowed profile URL."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2370 src/Module/Friendica.php:81
|
#: src/Model/Contact.php:2339 src/Module/Friendica.php:81
|
||||||
msgid "Blocked domain"
|
msgid "Blocked domain"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2375
|
#: src/Model/Contact.php:2344
|
||||||
msgid "Connect URL missing."
|
msgid "Connect URL missing."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2384
|
#: src/Model/Contact.php:2353
|
||||||
msgid ""
|
msgid ""
|
||||||
"The contact could not be added. Please check the relevant network "
|
"The contact could not be added. Please check the relevant network "
|
||||||
"credentials in your Settings -> Social Networks page."
|
"credentials in your Settings -> Social Networks page."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2421
|
#: src/Model/Contact.php:2390
|
||||||
msgid "The profile address specified does not provide adequate information."
|
msgid "The profile address specified does not provide adequate information."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2423
|
#: src/Model/Contact.php:2392
|
||||||
msgid "No compatible communication protocols or feeds were discovered."
|
msgid "No compatible communication protocols or feeds were discovered."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2426
|
#: src/Model/Contact.php:2395
|
||||||
msgid "An author or name was not found."
|
msgid "An author or name was not found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2429
|
#: src/Model/Contact.php:2398
|
||||||
msgid "No browser URL could be matched to this address."
|
msgid "No browser URL could be matched to this address."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2432
|
#: src/Model/Contact.php:2401
|
||||||
msgid ""
|
msgid ""
|
||||||
"Unable to match @-style Identity Address with a known protocol or email "
|
"Unable to match @-style Identity Address with a known protocol or email "
|
||||||
"contact."
|
"contact."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2433
|
#: src/Model/Contact.php:2402
|
||||||
msgid "Use mailto: in front of address to force email check."
|
msgid "Use mailto: in front of address to force email check."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2439
|
#: src/Model/Contact.php:2408
|
||||||
msgid ""
|
msgid ""
|
||||||
"The profile address specified belongs to a network which has been disabled "
|
"The profile address specified belongs to a network which has been disabled "
|
||||||
"on this site."
|
"on this site."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2444
|
#: src/Model/Contact.php:2413
|
||||||
msgid ""
|
msgid ""
|
||||||
"Limited profile. This person will be unable to receive direct/personal "
|
"Limited profile. This person will be unable to receive direct/personal "
|
||||||
"notifications from you."
|
"notifications from you."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Contact.php:2503
|
#: src/Model/Contact.php:2472
|
||||||
msgid "Unable to retrieve contact information."
|
msgid "Unable to retrieve contact information."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue