1
0
Fork 0

Merge remote-tracking branch 'upstream/develop' into contact-media

This commit is contained in:
Michael 2021-10-02 18:35:43 +00:00
commit 2408ac8227
19 changed files with 738 additions and 462 deletions

View file

@ -479,6 +479,22 @@ Hook data:
- **uid** (input): the user to return the contact data for (can be empty for public contacts). - **uid** (input): the user to return the contact data for (can be empty for public contacts).
- **result** (output): Set by the hook function to indicate a successful detection. - **result** (output): Set by the hook function to indicate a successful detection.
### support_follow
Called to assert whether a connector addon provides follow capabilities.
Hook data:
- **protocol** (input): shorthand for the protocol. List of values is available in `src/Core/Protocol.php`.
- **result** (output): should be true if the connector provides follow capabilities, left alone otherwise.
### support_revoke_follow
Called to assert whether a connector addon provides follow revocation capabilities.
Hook data:
- **protocol** (input): shorthand for the protocol. List of values is available in `src/Core/Protocol.php`.
- **result** (output): should be true if the connector provides follow revocation capabilities, left alone otherwise.
### follow ### follow
Called before adding a new contact for a user to handle non-native network remote contact (like Twitter). Called before adding a new contact for a user to handle non-native network remote contact (like Twitter).
@ -497,6 +513,14 @@ Hook data:
- **two_way** (input): wether 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. - **result** (output): wether the unfollowing is successful or not.
### revoke_follow
Called when making a remote contact on a non-native network (like Twitter) unfollow you.
Hook data:
- **contact** (input): the remote contact (uid = local revoking user id) array.
- **result** (output): a boolean value indicating wether the operation was successful or not.
## Complete list of hook callbacks ## Complete list of hook callbacks
Here is a complete list of all hook callbacks with file locations (as of 24-Sep-2018). Please see the source for details of any hooks not documented above. Here is a complete list of all hook callbacks with file locations (as of 24-Sep-2018). Please see the source for details of any hooks not documented above.
@ -666,7 +690,6 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
Hook::callAll('contact_photo_menu', $args); Hook::callAll('contact_photo_menu', $args);
Hook::callAll('follow', $arr); Hook::callAll('follow', $arr);
Hook::callAll('unfollow', $hook_data);
### src/Model/Profile.php ### src/Model/Profile.php
@ -750,6 +773,13 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
Hook::callAll('logged_in', $a->user); Hook::callAll('logged_in', $a->user);
### src/Core/Protocol.php
Hook::callAll('support_follow', $hook_data);
Hook::callAll('support_revoke_follow', $hook_data);
Hook::callAll('unfollow', $hook_data);
Kook::callAll('revoke_follow', $hook_data);
### src/Core/StorageManager ### src/Core/StorageManager
Hook::callAll('storage_instance', $data); Hook::callAll('storage_instance', $data);

View file

@ -356,7 +356,6 @@ Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Ap
Hook::callAll('contact_photo_menu', $args); Hook::callAll('contact_photo_menu', $args);
Hook::callAll('follow', $arr); Hook::callAll('follow', $arr);
Hook::callAll('unfollow', $hook_data);
### src/Model/Profile.php ### src/Model/Profile.php
@ -413,7 +412,14 @@ Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Ap
### src/Core/Authentication.php ### src/Core/Authentication.php
Hook::callAll('logged_in', $a->user); Hook::callAll('logged_in', $a->user);
### src/Core/Protocol.php
Hook::callAll('support_follow', $hook_data);
Hook::callAll('support_revoke_follow', $hook_data);
Hook::callAll('unfollow', $hook_data);
Kook::callAll('revoke_follow', $hook_data);
### src/Core/StorageManager ### src/Core/StorageManager
Hook::callAll('storage_instance', $data); Hook::callAll('storage_instance', $data);

View file

@ -1020,13 +1020,15 @@ function photos_content(App $a)
$drop_url = DI::args()->getQueryString(); $drop_url = DI::args()->getQueryString();
return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [ return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [
'$method' => 'post', '$l10n' => [
'$message' => DI::l10n()->t('Do you really want to delete this photo album and all its photos?'), 'message' => DI::l10n()->t('Do you really want to delete this photo album and all its photos?'),
'$confirm' => DI::l10n()->t('Delete Album'), 'confirm' => DI::l10n()->t('Delete Album'),
'$confirm_url' => $drop_url, 'cancel' => DI::l10n()->t('Cancel'),
'$confirm_name' => 'dropalbum', ],
'$method' => 'post',
'$confirm_url' => $drop_url,
'$confirm_name' => 'dropalbum',
'$confirm_value' => 'dropalbum', '$confirm_value' => 'dropalbum',
'$cancel' => DI::l10n()->t('Cancel'),
]); ]);
} }
@ -1127,13 +1129,15 @@ function photos_content(App $a)
$drop_url = DI::args()->getQueryString(); $drop_url = DI::args()->getQueryString();
return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [ return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [
'$method' => 'post', '$l10n' => [
'$message' => DI::l10n()->t('Do you really want to delete this photo?'), 'message' => DI::l10n()->t('Do you really want to delete this photo?'),
'$confirm' => DI::l10n()->t('Delete Photo'), 'confirm' => DI::l10n()->t('Delete Photo'),
'$confirm_url' => $drop_url, 'cancel' => DI::l10n()->t('Cancel'),
'$confirm_name' => 'delete', ],
'$method' => 'post',
'$confirm_url' => $drop_url,
'$confirm_name' => 'delete',
'$confirm_value' => 'delete', '$confirm_value' => 'delete',
'$cancel' => DI::l10n()->t('Cancel'),
]); ]);
} }

View file

@ -71,6 +71,44 @@ class Protocol
const PHANTOM = 'unkn'; // Place holder const PHANTOM = 'unkn'; // Place holder
/**
* Returns whether the provided protocol supports following
*
* @param $protocol
* @return bool
* @throws HTTPException\InternalServerErrorException
*/
public static function supportsFollow($protocol): bool
{
if (in_array($protocol, self::NATIVE_SUPPORT)) {
return true;
}
$result = null;
Hook::callAll('support_follow', $result);
return $result === true;
}
/**
* Returns whether the provided protocol supports revoking inbound follows
*
* @param $protocol
* @return bool
* @throws HTTPException\InternalServerErrorException
*/
public static function supportsRevokeFollow($protocol): bool
{
if (in_array($protocol, self::NATIVE_SUPPORT)) {
return true;
}
$result = null;
Hook::callAll('support_revoke_follow', $result);
return $result === true;
}
/** /**
* Returns the address string for the provided profile URL * Returns the address string for the provided profile URL
* *
@ -212,7 +250,7 @@ class Protocol
return ActivityPub\Transmitter::sendContactUndo($contact['url'], $contact['id'], $user['uid']); return ActivityPub\Transmitter::sendContactUndo($contact['url'], $contact['id'], $user['uid']);
} }
// Catch-all addon hook // Catch-all hook for connector addons
$hook_data = [ $hook_data = [
'contact' => $contact, 'contact' => $contact,
'two_way' => $two_way, 'two_way' => $two_way,
@ -222,4 +260,36 @@ class Protocol
return $hook_data['result']; return $hook_data['result'];
} }
/**
* Revoke an incoming follow from the provided contact
*
* @param array $contact Private contact (uid != 0) array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function revokeFollow(array $contact)
{
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 ($protocol == Protocol::ACTIVITYPUB) {
return ActivityPub\Transmitter::sendContactReject($contact['url'], $contact['hub-verify'], $contact['uid']);
}
// Catch-all hook for connector addons
$hook_data = [
'contact' => $contact,
'result' => null,
];
Hook::callAll('revoke_follow', $hook_data);
return $hook_data['result'];
}
} }

View file

@ -849,6 +849,36 @@ class Contact
return $result; return $result;
} }
/**
* Revoke follow privileges of the remote user contact
*
* @param array $contact Contact unfriended
* @return bool|null Whether the remote operation is successful or null if no remote operation was performed
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function revokeFollow(array $contact): bool
{
if (empty($contact['network'])) {
throw new \InvalidArgumentException('Empty network in contact array');
}
if (empty($contact['uid'])) {
throw new \InvalidArgumentException('Unexpected public contact record');
}
$result = Protocol::revokeFollow($contact);
// A null value here means the remote network doesn't support explicit follow revocation, we can still
// break the locally recorded relationship
if ($result !== false) {
DBA::update('contact', ['rel' => $contact['rel'] == self::FRIEND ? self::SHARING : self::NOTHING], ['id' => $contact['id']]);
}
return $result;
}
/** /**
* Marks a contact for archival after a communication issue delay * Marks a contact for archival after a communication issue delay
* *
@ -1022,7 +1052,7 @@ class Contact
$follow_link = ''; $follow_link = '';
$unfollow_link = ''; $unfollow_link = '';
if (!$contact['self'] && in_array($contact['network'], Protocol::NATIVE_SUPPORT)) { if (!$contact['self'] && Protocol::supportsFollow($contact['network'])) {
if ($contact['uid'] && in_array($contact['rel'], [self::SHARING, self::FRIEND])) { if ($contact['uid'] && in_array($contact['rel'], [self::SHARING, self::FRIEND])) {
$unfollow_link = 'unfollow?url=' . urlencode($contact['url']) . '&auto=1'; $unfollow_link = 'unfollow?url=' . urlencode($contact['url']) . '&auto=1';
} elseif(!$contact['pending']) { } elseif(!$contact['pending']) {

View file

@ -437,15 +437,17 @@ class Contact extends BaseModule
DI::page()['aside'] = ''; DI::page()['aside'] = '';
return Renderer::replaceMacros(Renderer::getMarkupTemplate('contact_drop_confirm.tpl'), [ return Renderer::replaceMacros(Renderer::getMarkupTemplate('contact_drop_confirm.tpl'), [
'$header' => DI::l10n()->t('Drop contact'), '$l10n' => [
'header' => DI::l10n()->t('Drop contact'),
'message' => DI::l10n()->t('Do you really want to delete this contact?'),
'confirm' => DI::l10n()->t('Yes'),
'cancel' => DI::l10n()->t('Cancel'),
],
'$contact' => self::getContactTemplateVars($orig_record), '$contact' => self::getContactTemplateVars($orig_record),
'$method' => 'get', '$method' => 'get',
'$message' => DI::l10n()->t('Do you really want to delete this contact?'),
'$confirm' => DI::l10n()->t('Yes'),
'$confirm_url' => DI::args()->getCommand(), '$confirm_url' => DI::args()->getCommand(),
'$confirm_name' => 't', '$confirm_name' => 't',
'$confirm_value' => BaseModule::getFormSecurityToken('contact_action'), '$confirm_value' => BaseModule::getFormSecurityToken('contact_action'),
'$cancel' => DI::l10n()->t('Cancel'),
]); ]);
} }
// Now check how the user responded to the confirmation query // Now check how the user responded to the confirmation query
@ -1159,6 +1161,16 @@ class Contact extends BaseModule
]; ];
if ($contact['uid'] != 0) { if ($contact['uid'] != 0) {
if (Protocol::supportsRevokeFollow($contact['network']) && in_array($contact['rel'], [Model\Contact::FOLLOWER, Model\Contact::FRIEND])) {
$contact_actions['revoke_follow'] = [
'label' => DI::l10n()->t('Revoke Follow'),
'url' => 'contact/' . $contact['id'] . '/revoke',
'title' => DI::l10n()->t('Revoke the follow from this contact'),
'sel' => '',
'id' => 'revoke_follow',
];
}
$contact_actions['delete'] = [ $contact_actions['delete'] = [
'label' => DI::l10n()->t('Delete'), 'label' => DI::l10n()->t('Delete'),
'url' => 'contact/' . $contact['id'] . '/drop?t=' . $formSecurityToken, 'url' => 'contact/' . $contact['id'] . '/drop?t=' . $formSecurityToken,

View file

@ -0,0 +1,108 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Contact;
use Friendica\BaseModule;
use Friendica\Content\Nav;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model;
use Friendica\Module\Contact;
use Friendica\Module\Security\Login;
use Friendica\Network\HTTPException;
class Revoke extends BaseModule
{
/** @var array */
private static $contact;
public static function init(array $parameters = [])
{
if (!local_user()) {
return;
}
$data = Model\Contact::getPublicAndUserContactID($parameters['id'], local_user());
if (!DBA::isResult($data)) {
throw new HTTPException\NotFoundException(DI::l10n()->t('Unknown contact.'));
}
if (empty($data['user'])) {
throw new HTTPException\ForbiddenException();
}
self::$contact = Model\Contact::getById($data['user']);
if (self::$contact['deleted']) {
throw new HTTPException\NotFoundException(DI::l10n()->t('Contact is deleted.'));
}
if (!empty(self::$contact['network']) && self::$contact['network'] == Protocol::PHANTOM) {
throw new HTTPException\NotFoundException(DI::l10n()->t('Contact is being deleted.'));
}
}
public static function post(array $parameters = [])
{
if (!local_user()) {
throw new HTTPException\UnauthorizedException();
}
self::checkFormSecurityTokenRedirectOnError('contact/' . $parameters['id'], 'contact_revoke');
$result = Model\Contact::revokeFollow(self::$contact);
if ($result === true) {
notice(DI::l10n()->t('Follow was successfully revoked.'));
} elseif ($result === null) {
notice(DI::l10n()->t('Follow was successfully revoked, however the remote contact won\'t be aware of this revokation.'));
} else {
notice(DI::l10n()->t('Unable to revoke follow, please try again later or contact the administrator.'));
}
DI::baseUrl()->redirect('contact/' . $parameters['id']);
}
public static function content(array $parameters = []): string
{
if (!local_user()) {
return Login::form($_SERVER['REQUEST_URI']);
}
Nav::setSelected('contact');
return Renderer::replaceMacros(Renderer::getMarkupTemplate('contact_drop_confirm.tpl'), [
'$l10n' => [
'header' => DI::l10n()->t('Revoke Follow'),
'message' => DI::l10n()->t('Do you really want to revoke this contact\'s follow? This cannot be undone and they will have to manually follow you back again.'),
'confirm' => DI::l10n()->t('Yes'),
'cancel' => DI::l10n()->t('Cancel'),
],
'$contact' => Contact::getContactTemplateVars(self::$contact),
'$method' => 'post',
'$confirm_url' => DI::args()->getCommand(),
'$confirm_name' => 'form_security_token',
'$confirm_value' => BaseModule::getFormSecurityToken('contact_revoke'),
]);
}
}

View file

@ -1037,9 +1037,12 @@ class Processor
self::switchContact($cid); self::switchContact($cid);
if (DBA::exists('contact', ['id' => $cid, 'rel' => Contact::SHARING])) { $contact = Contact::getById($cid, ['rel']);
if ($contact['rel'] == Contact::SHARING) {
Contact::remove($cid); Contact::remove($cid);
Logger::info('Rejected contact request - contact removed', ['contact' => $cid, 'user' => $uid]); Logger::info('Rejected contact request - contact removed', ['contact' => $cid, 'user' => $uid]);
} elseif ($contact['rel'] == Contact::FRIEND) {
Contact::update(['rel' => Contact::FOLLOWER], ['id' => $cid]);
} else { } else {
Logger::info('Rejected contact request', ['contact' => $cid, 'user' => $uid]); Logger::info('Rejected contact request', ['contact' => $cid, 'user' => $uid]);
} }

View file

@ -2047,15 +2047,16 @@ class Transmitter
* @param string $target Target profile * @param string $target Target profile
* @param $id * @param $id
* @param integer $uid User ID * @param integer $uid User ID
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @return bool Operation success
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function sendContactReject($target, $id, $uid) public static function sendContactReject($target, $id, $uid): bool
{ {
$profile = APContact::getByURL($target); $profile = APContact::getByURL($target);
if (empty($profile['inbox'])) { if (empty($profile['inbox'])) {
Logger::warning('No inbox found for target', ['target' => $target, 'profile' => $profile]); Logger::warning('No inbox found for target', ['target' => $target, 'profile' => $profile]);
return; return false;
} }
$owner = User::getOwnerDataById($uid); $owner = User::getOwnerDataById($uid);
@ -2075,7 +2076,7 @@ class Transmitter
Logger::debug('Sending reject to ' . $target . ' for user ' . $uid . ' with id ' . $id); Logger::debug('Sending reject to ' . $target . ' for user ' . $uid . ' with id ' . $id);
$signed = LDSignature::sign($data, $owner); $signed = LDSignature::sign($data, $owner);
HTTPSignature::transmit($signed, $profile['inbox'], $uid); return HTTPSignature::transmit($signed, $profile['inbox'], $uid);
} }
/** /**

View file

@ -118,14 +118,14 @@ class Diaspora
$basedom = XML::parseString($envelope, true); $basedom = XML::parseString($envelope, true);
if (!is_object($basedom)) { if (!is_object($basedom)) {
Logger::log("Envelope is no XML file"); Logger::notice("Envelope is no XML file");
return false; return false;
} }
$children = $basedom->children('http://salmon-protocol.org/ns/magic-env'); $children = $basedom->children('http://salmon-protocol.org/ns/magic-env');
if (sizeof($children) == 0) { if (sizeof($children) == 0) {
Logger::log("XML has no children"); Logger::notice("XML has no children");
return false; return false;
} }
@ -150,19 +150,19 @@ class Diaspora
$signable_data = $msg.".".Strings::base64UrlEncode($type).".".Strings::base64UrlEncode($encoding).".".Strings::base64UrlEncode($alg); $signable_data = $msg.".".Strings::base64UrlEncode($type).".".Strings::base64UrlEncode($encoding).".".Strings::base64UrlEncode($alg);
if ($handle == '') { if ($handle == '') {
Logger::log('No author could be decoded. Discarding. Message: ' . $envelope); Logger::notice('No author could be decoded. Discarding. Message: ' . $envelope);
return false; return false;
} }
$key = self::key($handle); $key = self::key($handle);
if ($key == '') { if ($key == '') {
Logger::log("Couldn't get a key for handle " . $handle . ". Discarding."); Logger::notice("Couldn't get a key for handle " . $handle . ". Discarding.");
return false; return false;
} }
$verify = Crypto::rsaVerify($signable_data, $sig, $key); $verify = Crypto::rsaVerify($signable_data, $sig, $key);
if (!$verify) { if (!$verify) {
Logger::log('Message from ' . $handle . ' did not verify. Discarding.'); Logger::notice('Message from ' . $handle . ' did not verify. Discarding.');
return false; return false;
} }
@ -225,7 +225,7 @@ class Diaspora
$j_outer_key_bundle = json_decode($outer_key_bundle); $j_outer_key_bundle = json_decode($outer_key_bundle);
if (!is_object($j_outer_key_bundle)) { if (!is_object($j_outer_key_bundle)) {
Logger::log('Outer Salmon did not verify. Discarding.'); Logger::notice('Outer Salmon did not verify. Discarding.');
if ($no_exit) { if ($no_exit) {
return false; return false;
} else { } else {
@ -244,7 +244,7 @@ class Diaspora
$basedom = XML::parseString($xml, true); $basedom = XML::parseString($xml, true);
if (!is_object($basedom)) { if (!is_object($basedom)) {
Logger::log('Received data does not seem to be an XML. Discarding. '.$xml); Logger::notice('Received data does not seem to be an XML. Discarding. '.$xml);
if ($no_exit) { if ($no_exit) {
return false; return false;
} else { } else {
@ -270,7 +270,7 @@ class Diaspora
$key_id = $base->sig[0]->attributes()->key_id[0]; $key_id = $base->sig[0]->attributes()->key_id[0];
$author_addr = base64_decode($key_id); $author_addr = base64_decode($key_id);
if ($author_addr == '') { if ($author_addr == '') {
Logger::log('No author could be decoded. Discarding. Message: ' . $xml); Logger::notice('No author could be decoded. Discarding. Message: ' . $xml);
if ($no_exit) { if ($no_exit) {
return false; return false;
} else { } else {
@ -280,7 +280,7 @@ class Diaspora
$key = self::key($author_addr); $key = self::key($author_addr);
if ($key == '') { if ($key == '') {
Logger::log("Couldn't get a key for handle " . $author_addr . ". Discarding."); Logger::notice("Couldn't get a key for handle " . $author_addr . ". Discarding.");
if ($no_exit) { if ($no_exit) {
return false; return false;
} else { } else {
@ -290,7 +290,7 @@ class Diaspora
$verify = Crypto::rsaVerify($signed_data, $signature, $key); $verify = Crypto::rsaVerify($signed_data, $signature, $key);
if (!$verify) { if (!$verify) {
Logger::log('Message did not verify. Discarding.'); Logger::notice('Message did not verify. Discarding.');
if ($no_exit) { if ($no_exit) {
return false; return false;
} else { } else {
@ -378,7 +378,7 @@ class Diaspora
} }
if (!$base) { if (!$base) {
Logger::log('unable to locate salmon data in xml'); Logger::notice('unable to locate salmon data in xml');
throw new \Friendica\Network\HTTPException\BadRequestException(); throw new \Friendica\Network\HTTPException\BadRequestException();
} }
@ -416,29 +416,29 @@ class Diaspora
} }
if (!$author_link) { if (!$author_link) {
Logger::log('Could not retrieve author URI.'); Logger::notice('Could not retrieve author URI.');
throw new \Friendica\Network\HTTPException\BadRequestException(); throw new \Friendica\Network\HTTPException\BadRequestException();
} }
// Once we have the author URI, go to the web and try to find their public key // Once we have the author URI, go to the web and try to find their public key
// (first this will look it up locally if it is in the fcontact cache) // (first this will look it up locally if it is in the fcontact cache)
// This will also convert diaspora public key from pkcs#1 to pkcs#8 // This will also convert diaspora public key from pkcs#1 to pkcs#8
Logger::log('Fetching key for '.$author_link); Logger::notice('Fetching key for '.$author_link);
$key = self::key($author_link); $key = self::key($author_link);
if (!$key) { if (!$key) {
Logger::log('Could not retrieve author key.'); Logger::notice('Could not retrieve author key.');
throw new \Friendica\Network\HTTPException\BadRequestException(); throw new \Friendica\Network\HTTPException\BadRequestException();
} }
$verify = Crypto::rsaVerify($signed_data, $signature, $key); $verify = Crypto::rsaVerify($signed_data, $signature, $key);
if (!$verify) { if (!$verify) {
Logger::log('Message did not verify. Discarding.'); Logger::notice('Message did not verify. Discarding.');
throw new \Friendica\Network\HTTPException\BadRequestException(); throw new \Friendica\Network\HTTPException\BadRequestException();
} }
Logger::log('Message verified.'); Logger::notice('Message verified.');
return ['message' => (string)$inner_decrypted, return ['message' => (string)$inner_decrypted,
'author' => XML::unescape($author_link), 'author' => XML::unescape($author_link),
@ -460,12 +460,12 @@ class Diaspora
{ {
$enabled = intval(DI::config()->get("system", "diaspora_enabled")); $enabled = intval(DI::config()->get("system", "diaspora_enabled"));
if (!$enabled) { if (!$enabled) {
Logger::log("diaspora is disabled"); Logger::notice("diaspora is disabled");
return false; return false;
} }
if (!($fields = self::validPosting($msg))) { if (!($fields = self::validPosting($msg))) {
Logger::log("Invalid posting"); Logger::notice("Invalid posting");
return false; return false;
} }
@ -497,7 +497,7 @@ class Diaspora
if (is_null($fields)) { if (is_null($fields)) {
$private = true; $private = true;
if (!($fields = self::validPosting($msg))) { if (!($fields = self::validPosting($msg))) {
Logger::log("Invalid posting"); Logger::notice("Invalid posting");
return false; return false;
} }
} else { } else {
@ -511,7 +511,7 @@ class Diaspora
switch ($type) { switch ($type) {
case "account_migration": case "account_migration":
if (!$private) { if (!$private) {
Logger::log('Message with type ' . $type . ' is not private, quitting.'); Logger::notice('Message with type ' . $type . ' is not private, quitting.');
return false; return false;
} }
return self::receiveAccountMigration($importer, $fields); return self::receiveAccountMigration($importer, $fields);
@ -524,14 +524,14 @@ class Diaspora
case "contact": case "contact":
if (!$private) { if (!$private) {
Logger::log('Message with type ' . $type . ' is not private, quitting.'); Logger::notice('Message with type ' . $type . ' is not private, quitting.');
return false; return false;
} }
return self::receiveContactRequest($importer, $fields); return self::receiveContactRequest($importer, $fields);
case "conversation": case "conversation":
if (!$private) { if (!$private) {
Logger::log('Message with type ' . $type . ' is not private, quitting.'); Logger::notice('Message with type ' . $type . ' is not private, quitting.');
return false; return false;
} }
return self::receiveConversation($importer, $msg, $fields); return self::receiveConversation($importer, $msg, $fields);
@ -541,14 +541,14 @@ class Diaspora
case "message": case "message":
if (!$private) { if (!$private) {
Logger::log('Message with type ' . $type . ' is not private, quitting.'); Logger::notice('Message with type ' . $type . ' is not private, quitting.');
return false; return false;
} }
return self::receiveMessage($importer, $fields); return self::receiveMessage($importer, $fields);
case "participation": case "participation":
if (!$private) { if (!$private) {
Logger::log('Message with type ' . $type . ' is not private, quitting.'); Logger::notice('Message with type ' . $type . ' is not private, quitting.');
return false; return false;
} }
return self::receiveParticipation($importer, $fields, $fetched); return self::receiveParticipation($importer, $fields, $fetched);
@ -561,7 +561,7 @@ class Diaspora
case "profile": case "profile":
if (!$private) { if (!$private) {
Logger::log('Message with type ' . $type . ' is not private, quitting.'); Logger::notice('Message with type ' . $type . ' is not private, quitting.');
return false; return false;
} }
return self::receiveProfile($importer, $fields); return self::receiveProfile($importer, $fields);
@ -576,7 +576,7 @@ class Diaspora
return self::receiveStatusMessage($importer, $fields, $msg["message"], $fetched); return self::receiveStatusMessage($importer, $fields, $msg["message"], $fetched);
default: default:
Logger::log("Unknown message type ".$type); Logger::notice("Unknown message type ".$type);
return false; return false;
} }
} }
@ -616,7 +616,7 @@ class Diaspora
$type = $element->getName(); $type = $element->getName();
$orig_type = $type; $orig_type = $type;
Logger::log("Got message type ".$type.": ".$msg["message"], Logger::DATA); Logger::debug("Got message type ".$type.": ".$msg["message"]);
// All retractions are handled identically from now on. // All retractions are handled identically from now on.
// In the new version there will only be "retraction". // In the new version there will only be "retraction".
@ -692,7 +692,7 @@ class Diaspora
// This is something that shouldn't happen at all. // This is something that shouldn't happen at all.
if (in_array($type, ["status_message", "reshare", "profile"])) { if (in_array($type, ["status_message", "reshare", "profile"])) {
if ($msg["author"] != $fields->author) { if ($msg["author"] != $fields->author) {
Logger::log("Message handle is not the same as envelope sender. Quitting this message."); Logger::notice("Message handle is not the same as envelope sender. Quitting this message.");
return false; return false;
} }
} }
@ -703,7 +703,7 @@ class Diaspora
} }
// No author_signature? This is a must, so we quit. // No author_signature? This is a must, so we quit.
if (!isset($author_signature)) { if (!isset($author_signature)) {
Logger::log("No author signature for type ".$type." - Message: ".$msg["message"], Logger::DEBUG); Logger::info("No author signature for type ".$type." - Message: ".$msg["message"]);
return false; return false;
} }
@ -715,7 +715,7 @@ class Diaspora
} }
if (!Crypto::rsaVerify($signed_data, $parent_author_signature, $key, "sha256")) { if (!Crypto::rsaVerify($signed_data, $parent_author_signature, $key, "sha256")) {
Logger::log("No valid parent author signature for parent author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature, Logger::DEBUG); Logger::info("No valid parent author signature for parent author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature);
return false; return false;
} }
} }
@ -727,7 +727,7 @@ class Diaspora
} }
if (!Crypto::rsaVerify($signed_data, $author_signature, $key, "sha256")) { if (!Crypto::rsaVerify($signed_data, $author_signature, $key, "sha256")) {
Logger::log("No valid author signature for author ".$fields->author. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature, Logger::DEBUG); Logger::info("No valid author signature for author ".$fields->author. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature);
return false; return false;
} else { } else {
return $fields; return $fields;
@ -747,7 +747,7 @@ class Diaspora
{ {
$handle = strval($handle); $handle = strval($handle);
Logger::log("Fetching diaspora key for: ".$handle); Logger::notice("Fetching diaspora key for: ".$handle);
$r = FContact::getByURL($handle); $r = FContact::getByURL($handle);
if ($r) { if ($r) {
@ -768,36 +768,19 @@ class Diaspora
*/ */
private static function handleFromContact($contact_id, $pcontact_id = 0) private static function handleFromContact($contact_id, $pcontact_id = 0)
{ {
$handle = false; $handle = '';
Logger::log("contact id is ".$contact_id." - pcontact id is ".$pcontact_id, Logger::DEBUG);
if ($pcontact_id != 0) { if ($pcontact_id != 0) {
$contact = DBA::selectFirst('contact', ['addr'], ['id' => $pcontact_id]); $contact = Contact::getById($pcontact_id, ['addr']);
if (DBA::isResult($contact)) {
if (DBA::isResult($contact) && !empty($contact["addr"])) { $handle = $contact['addr'];
return strtolower($contact["addr"]);
} }
} }
$r = q( if (empty($handle)) {
"SELECT `network`, `addr`, `self`, `url`, `nick` FROM `contact` WHERE `id` = %d", $contact = Contact::getById($contact_id, ['addr']);
intval($contact_id) if (DBA::isResult($contact)) {
);
if (DBA::isResult($r)) {
$contact = $r[0];
Logger::log("contact 'self' = ".$contact['self']." 'url' = ".$contact['url'], Logger::DEBUG);
if ($contact['addr'] != "") {
$handle = $contact['addr']; $handle = $contact['addr'];
} else {
$baseurl_start = strpos($contact['url'], '://') + 3;
// allows installations in a subdirectory--not sure how Diaspora will handle
$baseurl_length = strpos($contact['url'], '/profile') - $baseurl_start;
$baseurl = substr($contact['url'], $baseurl_start, $baseurl_length);
$handle = $contact['nick'].'@'.$baseurl;
} }
} }
@ -861,7 +844,7 @@ class Diaspora
// ); // );
// //
// $contact["rel"] = Contact::FRIEND; // $contact["rel"] = Contact::FRIEND;
// Logger::log("defining user ".$contact["nick"]." as friend"); // Logger::notice("defining user ".$contact["nick"]." as friend");
//} //}
// Contact server is blocked // Contact server is blocked
@ -902,7 +885,7 @@ class Diaspora
{ {
$contact = self::contactByHandle($importer["uid"], $handle); $contact = self::contactByHandle($importer["uid"], $handle);
if (!$contact) { if (!$contact) {
Logger::log("A Contact for handle ".$handle." and user ".$importer["uid"]." was not found"); Logger::notice("A Contact for handle ".$handle." and user ".$importer["uid"]." was not found");
// If a contact isn't found, we accept it anyway if it is a comment // If a contact isn't found, we accept it anyway if it is a comment
if ($is_comment && ($importer["uid"] != 0)) { if ($is_comment && ($importer["uid"] != 0)) {
return self::contactByHandle(0, $handle); return self::contactByHandle(0, $handle);
@ -914,7 +897,7 @@ class Diaspora
} }
if (!self::postAllow($importer, $contact, $is_comment)) { if (!self::postAllow($importer, $contact, $is_comment)) {
Logger::log("The handle: ".$handle." is not allowed to post to user ".$importer["uid"]); Logger::notice("The handle: ".$handle." is not allowed to post to user ".$importer["uid"]);
return false; return false;
} }
return $contact; return $contact;
@ -933,7 +916,7 @@ class Diaspora
{ {
$item = Post::selectFirst(['id'], ['uid' => $uid, 'guid' => $guid]); $item = Post::selectFirst(['id'], ['uid' => $uid, 'guid' => $guid]);
if (DBA::isResult($item)) { if (DBA::isResult($item)) {
Logger::log("message ".$guid." already exists for user ".$uid); Logger::notice("message ".$guid." already exists for user ".$uid);
return $item["id"]; return $item["id"];
} }
@ -1039,7 +1022,7 @@ class Diaspora
$server = $serverparts["scheme"]."://".$serverparts["host"]; $server = $serverparts["scheme"]."://".$serverparts["host"];
Logger::log("Trying to fetch item ".$guid." from ".$server, Logger::DEBUG); Logger::info("Trying to fetch item ".$guid." from ".$server);
$msg = self::message($guid, $server); $msg = self::message($guid, $server);
@ -1047,7 +1030,7 @@ class Diaspora
return false; return false;
} }
Logger::log("Successfully fetched item ".$guid." from ".$server, Logger::DEBUG); Logger::info("Successfully fetched item ".$guid." from ".$server);
// Now call the dispatcher // Now call the dispatcher
return self::dispatchPublic($msg, true); return self::dispatchPublic($msg, true);
@ -1075,16 +1058,16 @@ class Diaspora
// This will work for new Diaspora servers and Friendica servers from 3.5 // This will work for new Diaspora servers and Friendica servers from 3.5
$source_url = $server."/fetch/post/".urlencode($guid); $source_url = $server."/fetch/post/".urlencode($guid);
Logger::log("Fetch post from ".$source_url, Logger::DEBUG); Logger::info("Fetch post from ".$source_url);
$envelope = DI::httpClient()->fetch($source_url); $envelope = DI::httpClient()->fetch($source_url);
if ($envelope) { if ($envelope) {
Logger::log("Envelope was fetched.", Logger::DEBUG); Logger::info("Envelope was fetched.");
$x = self::verifyMagicEnvelope($envelope); $x = self::verifyMagicEnvelope($envelope);
if (!$x) { if (!$x) {
Logger::log("Envelope could not be verified.", Logger::DEBUG); Logger::info("Envelope could not be verified.");
} else { } else {
Logger::log("Envelope was verified.", Logger::DEBUG); Logger::info("Envelope was verified.");
} }
} else { } else {
$x = false; $x = false;
@ -1102,11 +1085,11 @@ class Diaspora
if ($source_xml->post->reshare) { if ($source_xml->post->reshare) {
// Reshare of a reshare - old Diaspora version // Reshare of a reshare - old Diaspora version
Logger::log("Message is a reshare", Logger::DEBUG); Logger::info("Message is a reshare");
return self::message($source_xml->post->reshare->root_guid, $server, ++$level); return self::message($source_xml->post->reshare->root_guid, $server, ++$level);
} elseif ($source_xml->getName() == "reshare") { } elseif ($source_xml->getName() == "reshare") {
// Reshare of a reshare - new Diaspora version // Reshare of a reshare - new Diaspora version
Logger::log("Message is a new reshare", Logger::DEBUG); Logger::info("Message is a new reshare");
return self::message($source_xml->root_guid, $server, ++$level); return self::message($source_xml->root_guid, $server, ++$level);
} }
@ -1121,7 +1104,7 @@ class Diaspora
// If this isn't a "status_message" then quit // If this isn't a "status_message" then quit
if (!$author) { if (!$author) {
Logger::log("Message doesn't seem to be a status message", Logger::DEBUG); Logger::info("Message doesn't seem to be a status message");
return false; return false;
} }
@ -1200,17 +1183,17 @@ class Diaspora
} }
if ($result) { if ($result) {
Logger::log("Fetched missing item ".$guid." - result: ".$result, Logger::DEBUG); Logger::info("Fetched missing item ".$guid." - result: ".$result);
$item = Post::selectFirst($fields, $condition); $item = Post::selectFirst($fields, $condition);
} }
} }
if (!DBA::isResult($item)) { if (!DBA::isResult($item)) {
Logger::log("parent item not found: parent: ".$guid." - user: ".$uid); Logger::notice("parent item not found: parent: ".$guid." - user: ".$uid);
return false; return false;
} else { } else {
Logger::log("parent item found: parent: ".$guid." - user: ".$uid); Logger::notice("parent item found: parent: ".$guid." - user: ".$uid);
return $item; return $item;
} }
} }
@ -1331,23 +1314,23 @@ class Diaspora
*/ */
private static function receiveAccountMigration(array $importer, $data) private static function receiveAccountMigration(array $importer, $data)
{ {
$old_handle = Strings::escapeTags(XML::unescape($data->author)); $old_handle = XML::unescape($data->author);
$new_handle = Strings::escapeTags(XML::unescape($data->profile->author)); $new_handle = XML::unescape($data->profile->author);
$signature = Strings::escapeTags(XML::unescape($data->signature)); $signature = XML::unescape($data->signature);
$contact = self::contactByHandle($importer["uid"], $old_handle); $contact = self::contactByHandle($importer["uid"], $old_handle);
if (!$contact) { if (!$contact) {
Logger::log("cannot find contact for sender: ".$old_handle." and user ".$importer["uid"]); Logger::notice("cannot find contact for sender: ".$old_handle." and user ".$importer["uid"]);
return false; return false;
} }
Logger::log("Got migration for ".$old_handle.", to ".$new_handle." with user ".$importer["uid"]); Logger::notice("Got migration for ".$old_handle.", to ".$new_handle." with user ".$importer["uid"]);
// Check signature // Check signature
$signed_text = 'AccountMigration:'.$old_handle.':'.$new_handle; $signed_text = 'AccountMigration:'.$old_handle.':'.$new_handle;
$key = self::key($old_handle); $key = self::key($old_handle);
if (!Crypto::rsaVerify($signed_text, $signature, $key, "sha256")) { if (!Crypto::rsaVerify($signed_text, $signature, $key, "sha256")) {
Logger::log('No valid signature for migration.'); Logger::notice('No valid signature for migration.');
return false; return false;
} }
@ -1357,7 +1340,7 @@ class Diaspora
// change the technical stuff in contact // change the technical stuff in contact
$data = Probe::uri($new_handle); $data = Probe::uri($new_handle);
if ($data['network'] == Protocol::PHANTOM) { if ($data['network'] == Protocol::PHANTOM) {
Logger::log('Account for '.$new_handle." couldn't be probed."); Logger::notice('Account for '.$new_handle." couldn't be probed.");
return false; return false;
} }
@ -1369,7 +1352,7 @@ class Diaspora
Contact::update($fields, ['addr' => $old_handle]); Contact::update($fields, ['addr' => $old_handle]);
Logger::log('Contacts are updated.'); Logger::notice('Contacts are updated.');
return true; return true;
} }
@ -1384,7 +1367,7 @@ class Diaspora
*/ */
private static function receiveAccountDeletion($data) private static function receiveAccountDeletion($data)
{ {
$author = Strings::escapeTags(XML::unescape($data->author)); $author = XML::unescape($data->author);
$contacts = DBA::select('contact', ['id'], ['addr' => $author]); $contacts = DBA::select('contact', ['id'], ['addr' => $author]);
while ($contact = DBA::fetch($contacts)) { while ($contact = DBA::fetch($contacts)) {
@ -1392,7 +1375,7 @@ class Diaspora
} }
DBA::close($contacts); DBA::close($contacts);
Logger::log('Removed contacts for ' . $author); Logger::notice('Removed contacts for ' . $author);
return true; return true;
} }
@ -1475,19 +1458,19 @@ class Diaspora
*/ */
private static function receiveComment(array $importer, $sender, $data, $xml, bool $fetched) private static function receiveComment(array $importer, $sender, $data, $xml, bool $fetched)
{ {
$author = Strings::escapeTags(XML::unescape($data->author)); $author = XML::unescape($data->author);
$guid = Strings::escapeTags(XML::unescape($data->guid)); $guid = XML::unescape($data->guid);
$parent_guid = Strings::escapeTags(XML::unescape($data->parent_guid)); $parent_guid = XML::unescape($data->parent_guid);
$text = XML::unescape($data->text); $text = XML::unescape($data->text);
if (isset($data->created_at)) { if (isset($data->created_at)) {
$created_at = DateTimeFormat::utc(Strings::escapeTags(XML::unescape($data->created_at))); $created_at = DateTimeFormat::utc(XML::unescape($data->created_at));
} else { } else {
$created_at = DateTimeFormat::utcNow(); $created_at = DateTimeFormat::utcNow();
} }
if (isset($data->thread_parent_guid)) { if (isset($data->thread_parent_guid)) {
$thread_parent_guid = Strings::escapeTags(XML::unescape($data->thread_parent_guid)); $thread_parent_guid = XML::unescape($data->thread_parent_guid);
$thr_parent = self::getUriFromGuid("", $thread_parent_guid, true); $thr_parent = self::getUriFromGuid("", $thread_parent_guid, true);
} else { } else {
$thr_parent = ""; $thr_parent = "";
@ -1514,7 +1497,7 @@ class Diaspora
$person = FContact::getByURL($author); $person = FContact::getByURL($author);
if (!is_array($person)) { if (!is_array($person)) {
Logger::log("unable to find author details"); Logger::notice("unable to find author details");
return false; return false;
} }
@ -1588,7 +1571,7 @@ class Diaspora
} }
if ($message_id) { if ($message_id) {
Logger::log("Stored comment ".$datarray["guid"]." with message id ".$message_id, Logger::DEBUG); Logger::info("Stored comment ".$datarray["guid"]." with message id ".$message_id);
if ($datarray['uid'] == 0) { if ($datarray['uid'] == 0) {
Item::distribute($message_id, json_encode($data)); Item::distribute($message_id, json_encode($data));
} }
@ -1612,27 +1595,27 @@ class Diaspora
*/ */
private static function receiveConversationMessage(array $importer, array $contact, $data, $msg, $mesg, $conversation) private static function receiveConversationMessage(array $importer, array $contact, $data, $msg, $mesg, $conversation)
{ {
$author = Strings::escapeTags(XML::unescape($data->author)); $author = XML::unescape($data->author);
$guid = Strings::escapeTags(XML::unescape($data->guid)); $guid = XML::unescape($data->guid);
$subject = Strings::escapeTags(XML::unescape($data->subject)); $subject = XML::unescape($data->subject);
// "diaspora_handle" is the element name from the old version // "diaspora_handle" is the element name from the old version
// "author" is the element name from the new version // "author" is the element name from the new version
if ($mesg->author) { if ($mesg->author) {
$msg_author = Strings::escapeTags(XML::unescape($mesg->author)); $msg_author = XML::unescape($mesg->author);
} elseif ($mesg->diaspora_handle) { } elseif ($mesg->diaspora_handle) {
$msg_author = Strings::escapeTags(XML::unescape($mesg->diaspora_handle)); $msg_author = XML::unescape($mesg->diaspora_handle);
} else { } else {
return false; return false;
} }
$msg_guid = Strings::escapeTags(XML::unescape($mesg->guid)); $msg_guid = XML::unescape($mesg->guid);
$msg_conversation_guid = Strings::escapeTags(XML::unescape($mesg->conversation_guid)); $msg_conversation_guid = XML::unescape($mesg->conversation_guid);
$msg_text = XML::unescape($mesg->text); $msg_text = XML::unescape($mesg->text);
$msg_created_at = DateTimeFormat::utc(Strings::escapeTags(XML::unescape($mesg->created_at))); $msg_created_at = DateTimeFormat::utc(XML::unescape($mesg->created_at));
if ($msg_conversation_guid != $guid) { if ($msg_conversation_guid != $guid) {
Logger::log("message conversation guid does not belong to the current conversation."); Logger::notice("message conversation guid does not belong to the current conversation.");
return false; return false;
} }
@ -1669,16 +1652,16 @@ class Diaspora
*/ */
private static function receiveConversation(array $importer, $msg, $data) private static function receiveConversation(array $importer, $msg, $data)
{ {
$author = Strings::escapeTags(XML::unescape($data->author)); $author = XML::unescape($data->author);
$guid = Strings::escapeTags(XML::unescape($data->guid)); $guid = XML::unescape($data->guid);
$subject = Strings::escapeTags(XML::unescape($data->subject)); $subject = XML::unescape($data->subject);
$created_at = DateTimeFormat::utc(Strings::escapeTags(XML::unescape($data->created_at))); $created_at = DateTimeFormat::utc(XML::unescape($data->created_at));
$participants = Strings::escapeTags(XML::unescape($data->participants)); $participants = XML::unescape($data->participants);
$messages = $data->message; $messages = $data->message;
if (!count($messages)) { if (!count($messages)) {
Logger::log("empty conversation"); Logger::notice("empty conversation");
return false; return false;
} }
@ -1693,23 +1676,20 @@ class Diaspora
$conversation = DBA::selectFirst('conv', [], ['uid' => $importer["uid"], 'guid' => $guid]); $conversation = DBA::selectFirst('conv', [], ['uid' => $importer["uid"], 'guid' => $guid]);
if (!DBA::isResult($conversation)) { if (!DBA::isResult($conversation)) {
$r = q( $r = DBA::insert('conv', [
"INSERT INTO `conv` (`uid`, `guid`, `creator`, `created`, `updated`, `subject`, `recips`) 'uid' => $importer['uid'],
VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s')", 'guid' => $guid,
intval($importer["uid"]), 'creator' => $author,
DBA::escape($guid), 'created' => $created_at,
DBA::escape($author), 'updated' => DateTimeFormat::utcNow(),
DBA::escape($created_at), 'subject' => $subject,
DBA::escape(DateTimeFormat::utcNow()), 'recips' => $participants]);
DBA::escape($subject),
DBA::escape($participants)
);
if ($r) { if ($r) {
$conversation = DBA::selectFirst('conv', [], ['uid' => $importer["uid"], 'guid' => $guid]); $conversation = DBA::selectFirst('conv', [], ['uid' => $importer["uid"], 'guid' => $guid]);
} }
} }
if (!$conversation) { if (!$conversation) {
Logger::log("unable to create conversation."); Logger::notice("unable to create conversation.");
return false; return false;
} }
@ -1733,11 +1713,11 @@ class Diaspora
*/ */
private static function receiveLike(array $importer, $sender, $data, bool $fetched) private static function receiveLike(array $importer, $sender, $data, bool $fetched)
{ {
$author = Strings::escapeTags(XML::unescape($data->author)); $author = XML::unescape($data->author);
$guid = Strings::escapeTags(XML::unescape($data->guid)); $guid = XML::unescape($data->guid);
$parent_guid = Strings::escapeTags(XML::unescape($data->parent_guid)); $parent_guid = XML::unescape($data->parent_guid);
$parent_type = Strings::escapeTags(XML::unescape($data->parent_type)); $parent_type = XML::unescape($data->parent_type);
$positive = Strings::escapeTags(XML::unescape($data->positive)); $positive = XML::unescape($data->positive);
// likes on comments aren't supported by Diaspora - only on posts // likes on comments aren't supported by Diaspora - only on posts
// But maybe this will be supported in the future, so we will accept it. // But maybe this will be supported in the future, so we will accept it.
@ -1766,7 +1746,7 @@ class Diaspora
$person = FContact::getByURL($author); $person = FContact::getByURL($author);
if (!is_array($person)) { if (!is_array($person)) {
Logger::log("unable to find author details"); Logger::notice("unable to find author details");
return false; return false;
} }
@ -1833,7 +1813,7 @@ class Diaspora
} }
if ($message_id) { if ($message_id) {
Logger::log("Stored like ".$datarray["guid"]." with message id ".$message_id, Logger::DEBUG); Logger::info("Stored like ".$datarray["guid"]." with message id ".$message_id);
if ($datarray['uid'] == 0) { if ($datarray['uid'] == 0) {
Item::distribute($message_id, json_encode($data)); Item::distribute($message_id, json_encode($data));
} }
@ -1853,11 +1833,11 @@ class Diaspora
*/ */
private static function receiveMessage(array $importer, $data) private static function receiveMessage(array $importer, $data)
{ {
$author = Strings::escapeTags(XML::unescape($data->author)); $author = XML::unescape($data->author);
$guid = Strings::escapeTags(XML::unescape($data->guid)); $guid = XML::unescape($data->guid);
$conversation_guid = Strings::escapeTags(XML::unescape($data->conversation_guid)); $conversation_guid = XML::unescape($data->conversation_guid);
$text = XML::unescape($data->text); $text = XML::unescape($data->text);
$created_at = DateTimeFormat::utc(Strings::escapeTags(XML::unescape($data->created_at))); $created_at = DateTimeFormat::utc(XML::unescape($data->created_at));
$contact = self::allowedContactByHandle($importer, $author, true); $contact = self::allowedContactByHandle($importer, $author, true);
if (!$contact) { if (!$contact) {
@ -1874,7 +1854,7 @@ class Diaspora
$conversation = DBA::selectFirst('conv', [], $condition); $conversation = DBA::selectFirst('conv', [], $condition);
if (!DBA::isResult($conversation)) { if (!DBA::isResult($conversation)) {
Logger::log("conversation not available."); Logger::notice("conversation not available.");
return false; return false;
} }
@ -1882,7 +1862,7 @@ class Diaspora
$person = FContact::getByURL($author); $person = FContact::getByURL($author);
if (!$person) { if (!$person) {
Logger::log("unable to find author details"); Logger::notice("unable to find author details");
return false; return false;
} }
@ -1919,9 +1899,9 @@ class Diaspora
*/ */
private static function receiveParticipation(array $importer, $data, bool $fetched) private static function receiveParticipation(array $importer, $data, bool $fetched)
{ {
$author = strtolower(Strings::escapeTags(XML::unescape($data->author))); $author = strtolower(XML::unescape($data->author));
$guid = Strings::escapeTags(XML::unescape($data->guid)); $guid = XML::unescape($data->guid);
$parent_guid = Strings::escapeTags(XML::unescape($data->parent_guid)); $parent_guid = XML::unescape($data->parent_guid);
$contact = self::allowedContactByHandle($importer, $author, true); $contact = self::allowedContactByHandle($importer, $author, true);
if (!$contact) { if (!$contact) {
@ -1952,7 +1932,7 @@ class Diaspora
$person = FContact::getByURL($author); $person = FContact::getByURL($author);
if (!is_array($person)) { if (!is_array($person)) {
Logger::log("Person not found: ".$author); Logger::notice("Person not found: ".$author);
return false; return false;
} }
@ -2064,7 +2044,7 @@ class Diaspora
*/ */
private static function receiveProfile(array $importer, $data) private static function receiveProfile(array $importer, $data)
{ {
$author = strtolower(Strings::escapeTags(XML::unescape($data->author))); $author = strtolower(XML::unescape($data->author));
$contact = self::contactByHandle($importer["uid"], $author); $contact = self::contactByHandle($importer["uid"], $author);
if (!$contact) { if (!$contact) {
@ -2131,7 +2111,7 @@ class Diaspora
Contact::update($fields, ['id' => $contact['id']]); Contact::update($fields, ['id' => $contact['id']]);
Logger::log("Profile of contact ".$contact["id"]." stored for user ".$importer["uid"], Logger::DEBUG); Logger::info("Profile of contact ".$contact["id"]." stored for user ".$importer["uid"]);
return true; return true;
} }
@ -2193,7 +2173,7 @@ class Diaspora
// That makes us friends. // That makes us friends.
if ($contact) { if ($contact) {
if ($following) { if ($following) {
Logger::log("Author ".$author." (Contact ".$contact["id"].") wants to follow us.", Logger::DEBUG); Logger::info("Author ".$author." (Contact ".$contact["id"].") wants to follow us.");
self::receiveRequestMakeFriend($importer, $contact); self::receiveRequestMakeFriend($importer, $contact);
// refetch the contact array // refetch the contact array
@ -2204,36 +2184,36 @@ class Diaspora
if (in_array($contact["rel"], [Contact::FRIEND])) { if (in_array($contact["rel"], [Contact::FRIEND])) {
$user = DBA::selectFirst('user', [], ['uid' => $importer["uid"]]); $user = DBA::selectFirst('user', [], ['uid' => $importer["uid"]]);
if (DBA::isResult($user)) { if (DBA::isResult($user)) {
Logger::log("Sending share message to author ".$author." - Contact: ".$contact["id"]." - User: ".$importer["uid"], Logger::DEBUG); Logger::info("Sending share message to author ".$author." - Contact: ".$contact["id"]." - User: ".$importer["uid"]);
self::sendShare($user, $contact); self::sendShare($user, $contact);
} }
} }
return true; return true;
} else { } else {
Logger::log("Author ".$author." doesn't want to follow us anymore.", Logger::DEBUG); Logger::info("Author ".$author." doesn't want to follow us anymore.");
Contact::removeFollower($contact); Contact::removeFollower($contact);
return true; return true;
} }
} }
if (!$following && $sharing && in_array($importer["page-flags"], [User::PAGE_FLAGS_SOAPBOX, User::PAGE_FLAGS_NORMAL])) { if (!$following && $sharing && in_array($importer["page-flags"], [User::PAGE_FLAGS_SOAPBOX, User::PAGE_FLAGS_NORMAL])) {
Logger::log("Author ".$author." wants to share with us - but doesn't want to listen. Request is ignored.", Logger::DEBUG); Logger::info("Author ".$author." wants to share with us - but doesn't want to listen. Request is ignored.");
return false; return false;
} elseif (!$following && !$sharing) { } elseif (!$following && !$sharing) {
Logger::log("Author ".$author." doesn't want anything - and we don't know the author. Request is ignored.", Logger::DEBUG); Logger::info("Author ".$author." doesn't want anything - and we don't know the author. Request is ignored.");
return false; return false;
} elseif (!$following && $sharing) { } elseif (!$following && $sharing) {
Logger::log("Author ".$author." wants to share with us.", Logger::DEBUG); Logger::info("Author ".$author." wants to share with us.");
} elseif ($following && $sharing) { } elseif ($following && $sharing) {
Logger::log("Author ".$author." wants to have a bidirectional conection.", Logger::DEBUG); Logger::info("Author ".$author." wants to have a bidirectional conection.");
} elseif ($following && !$sharing) { } elseif ($following && !$sharing) {
Logger::log("Author ".$author." wants to listen to us.", Logger::DEBUG); Logger::info("Author ".$author." wants to listen to us.");
} }
$ret = FContact::getByURL($author); $ret = FContact::getByURL($author);
if (!$ret || ($ret["network"] != Protocol::DIASPORA)) { if (!$ret || ($ret["network"] != Protocol::DIASPORA)) {
Logger::log("Cannot resolve diaspora handle ".$author." for ".$recipient); Logger::notice("Cannot resolve diaspora handle ".$author." for ".$recipient);
return false; return false;
} }
@ -2279,7 +2259,7 @@ class Diaspora
public static function originalItem($guid, $orig_author) public static function originalItem($guid, $orig_author)
{ {
if (empty($guid)) { if (empty($guid)) {
Logger::log('Empty guid. Quitting.'); Logger::notice('Empty guid. Quitting.');
return false; return false;
} }
@ -2290,7 +2270,7 @@ class Diaspora
$item = Post::selectFirst($fields, $condition); $item = Post::selectFirst($fields, $condition);
if (DBA::isResult($item)) { if (DBA::isResult($item)) {
Logger::log("reshared message ".$guid." already exists on system."); Logger::notice("reshared message ".$guid." already exists on system.");
// Maybe it is already a reshared item? // Maybe it is already a reshared item?
// Then refetch the content, if it is a reshare from a reshare. // Then refetch the content, if it is a reshare from a reshare.
@ -2310,17 +2290,17 @@ class Diaspora
if (!DBA::isResult($item)) { if (!DBA::isResult($item)) {
if (empty($orig_author)) { if (empty($orig_author)) {
Logger::log('Empty author for guid ' . $guid . '. Quitting.'); Logger::notice('Empty author for guid ' . $guid . '. Quitting.');
return false; return false;
} }
$server = "https://".substr($orig_author, strpos($orig_author, "@") + 1); $server = "https://".substr($orig_author, strpos($orig_author, "@") + 1);
Logger::log("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server); Logger::notice("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server);
$stored = self::storeByGuid($guid, $server); $stored = self::storeByGuid($guid, $server);
if (!$stored) { if (!$stored) {
$server = "http://".substr($orig_author, strpos($orig_author, "@") + 1); $server = "http://".substr($orig_author, strpos($orig_author, "@") + 1);
Logger::log("2nd try: reshared message ".$guid." will be fetched without SSL from the server ".$server); Logger::notice("2nd try: reshared message ".$guid." will be fetched without SSL from the server ".$server);
$stored = self::storeByGuid($guid, $server); $stored = self::storeByGuid($guid, $server);
} }
@ -2412,13 +2392,13 @@ class Diaspora
*/ */
private static function receiveReshare(array $importer, $data, $xml, bool $fetched) private static function receiveReshare(array $importer, $data, $xml, bool $fetched)
{ {
$author = Strings::escapeTags(XML::unescape($data->author)); $author = XML::unescape($data->author);
$guid = Strings::escapeTags(XML::unescape($data->guid)); $guid = XML::unescape($data->guid);
$created_at = DateTimeFormat::utc(Strings::escapeTags(XML::unescape($data->created_at))); $created_at = DateTimeFormat::utc(XML::unescape($data->created_at));
$root_author = Strings::escapeTags(XML::unescape($data->root_author)); $root_author = XML::unescape($data->root_author);
$root_guid = Strings::escapeTags(XML::unescape($data->root_guid)); $root_guid = XML::unescape($data->root_guid);
/// @todo handle unprocessed property "provider_display_name" /// @todo handle unprocessed property "provider_display_name"
$public = Strings::escapeTags(XML::unescape($data->public)); $public = XML::unescape($data->public);
$contact = self::allowedContactByHandle($importer, $author, false); $contact = self::allowedContactByHandle($importer, $author, false);
if (!$contact) { if (!$contact) {
@ -2510,7 +2490,7 @@ class Diaspora
} }
if ($message_id) { if ($message_id) {
Logger::log("Stored reshare ".$datarray["guid"]." with message id ".$message_id, Logger::DEBUG); Logger::info("Stored reshare ".$datarray["guid"]." with message id ".$message_id);
if ($datarray['uid'] == 0) { if ($datarray['uid'] == 0) {
Item::distribute($message_id); Item::distribute($message_id);
} }
@ -2532,13 +2512,13 @@ class Diaspora
*/ */
private static function itemRetraction(array $importer, array $contact, $data) private static function itemRetraction(array $importer, array $contact, $data)
{ {
$author = Strings::escapeTags(XML::unescape($data->author)); $author = XML::unescape($data->author);
$target_guid = Strings::escapeTags(XML::unescape($data->target_guid)); $target_guid = XML::unescape($data->target_guid);
$target_type = Strings::escapeTags(XML::unescape($data->target_type)); $target_type = XML::unescape($data->target_type);
$person = FContact::getByURL($author); $person = FContact::getByURL($author);
if (!is_array($person)) { if (!is_array($person)) {
Logger::log("unable to find author detail for ".$author); Logger::notice("unable to find author detail for ".$author);
return false; return false;
} }
@ -2558,13 +2538,13 @@ class Diaspora
$r = Post::select($fields, $condition); $r = Post::select($fields, $condition);
if (!DBA::isResult($r)) { if (!DBA::isResult($r)) {
Logger::log("Target guid ".$target_guid." was not found on this system for user ".$importer['uid']."."); Logger::notice("Target guid ".$target_guid." was not found on this system for user ".$importer['uid'].".");
return false; return false;
} }
while ($item = Post::fetch($r)) { while ($item = Post::fetch($r)) {
if (DBA::exists('post-category', ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'type' => Post\Category::FILE])) { if (DBA::exists('post-category', ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'type' => Post\Category::FILE])) {
Logger::log("Target guid " . $target_guid . " for user " . $item['uid'] . " is filed. So it won't be deleted.", Logger::DEBUG); Logger::info("Target guid " . $target_guid . " for user " . $item['uid'] . " is filed. So it won't be deleted.");
continue; continue;
} }
@ -2573,13 +2553,13 @@ class Diaspora
// Only delete it if the parent author really fits // Only delete it if the parent author really fits
if (!Strings::compareLink($parent["author-link"], $contact["url"]) && !Strings::compareLink($item["author-link"], $contact["url"])) { if (!Strings::compareLink($parent["author-link"], $contact["url"]) && !Strings::compareLink($item["author-link"], $contact["url"])) {
Logger::log("Thread author ".$parent["author-link"]." and item author ".$item["author-link"]." don't fit to expected contact ".$contact["url"], Logger::DEBUG); Logger::info("Thread author ".$parent["author-link"]." and item author ".$item["author-link"]." don't fit to expected contact ".$contact["url"]);
continue; continue;
} }
Item::markForDeletion(['id' => $item['id']]); Item::markForDeletion(['id' => $item['id']]);
Logger::log("Deleted target ".$target_guid." (".$item["id"].") from user ".$item["uid"]." parent: ".$item['parent'], Logger::DEBUG); Logger::info("Deleted target ".$target_guid." (".$item["id"].") from user ".$item["uid"]." parent: ".$item['parent']);
} }
DBA::close($r); DBA::close($r);
@ -2598,11 +2578,11 @@ class Diaspora
*/ */
private static function receiveRetraction(array $importer, $sender, $data) private static function receiveRetraction(array $importer, $sender, $data)
{ {
$target_type = Strings::escapeTags(XML::unescape($data->target_type)); $target_type = XML::unescape($data->target_type);
$contact = self::contactByHandle($importer["uid"], $sender); $contact = self::contactByHandle($importer["uid"], $sender);
if (!$contact && (in_array($target_type, ["Contact", "Person"]))) { if (!$contact && (in_array($target_type, ["Contact", "Person"]))) {
Logger::log("cannot find contact for sender: ".$sender." and user ".$importer["uid"]); Logger::notice("cannot find contact for sender: ".$sender." and user ".$importer["uid"]);
return false; return false;
} }
@ -2610,7 +2590,7 @@ class Diaspora
$contact = []; $contact = [];
} }
Logger::log("Got retraction for ".$target_type.", sender ".$sender." and user ".$importer["uid"], Logger::DEBUG); Logger::info("Got retraction for ".$target_type.", sender ".$sender." and user ".$importer["uid"]);
switch ($target_type) { switch ($target_type) {
case "Comment": case "Comment":
@ -2626,7 +2606,7 @@ class Diaspora
break; break;
default: default:
Logger::log("Unknown target type ".$target_type); Logger::notice("Unknown target type ".$target_type);
return false; return false;
} }
return true; return true;
@ -2688,12 +2668,12 @@ class Diaspora
*/ */
private static function receiveStatusMessage(array $importer, SimpleXMLElement $data, $xml, bool $fetched) private static function receiveStatusMessage(array $importer, SimpleXMLElement $data, $xml, bool $fetched)
{ {
$author = Strings::escapeTags(XML::unescape($data->author)); $author = XML::unescape($data->author);
$guid = Strings::escapeTags(XML::unescape($data->guid)); $guid = XML::unescape($data->guid);
$created_at = DateTimeFormat::utc(Strings::escapeTags(XML::unescape($data->created_at))); $created_at = DateTimeFormat::utc(XML::unescape($data->created_at));
$public = Strings::escapeTags(XML::unescape($data->public)); $public = XML::unescape($data->public);
$text = XML::unescape($data->text); $text = XML::unescape($data->text);
$provider_display_name = Strings::escapeTags(XML::unescape($data->provider_display_name)); $provider_display_name = XML::unescape($data->provider_display_name);
$contact = self::allowedContactByHandle($importer, $author, false); $contact = self::allowedContactByHandle($importer, $author, false);
if (!$contact) { if (!$contact) {
@ -2712,7 +2692,7 @@ class Diaspora
$address = []; $address = [];
if ($data->location) { if ($data->location) {
foreach ($data->location->children() as $fieldname => $data) { foreach ($data->location->children() as $fieldname => $data) {
$address[$fieldname] = Strings::escapeTags(XML::unescape($data)); $address[$fieldname] = XML::unescape($data);
} }
} }
@ -2808,7 +2788,7 @@ class Diaspora
self::sendParticipation($contact, $datarray); self::sendParticipation($contact, $datarray);
if ($message_id) { if ($message_id) {
Logger::log("Stored item ".$datarray["guid"]." with message id ".$message_id, Logger::DEBUG); Logger::info("Stored item ".$datarray["guid"]." with message id ".$message_id);
if ($datarray['uid'] == 0) { if ($datarray['uid'] == 0) {
Item::distribute($message_id); Item::distribute($message_id);
} }
@ -2862,11 +2842,11 @@ class Diaspora
*/ */
public static function encodePrivateData($msg, array $user, array $contact, $prvkey, $pubkey) public static function encodePrivateData($msg, array $user, array $contact, $prvkey, $pubkey)
{ {
Logger::log("Message: ".$msg, Logger::DATA); Logger::debug("Message: ".$msg);
// without a public key nothing will work // without a public key nothing will work
if (!$pubkey) { if (!$pubkey) {
Logger::log("pubkey missing: contact id: ".$contact["id"]); Logger::notice("pubkey missing: contact id: ".$contact["id"]);
return false; return false;
} }
@ -3013,11 +2993,11 @@ class Diaspora
} }
if (!$dest_url) { if (!$dest_url) {
Logger::log("no url for contact: ".$contact["id"]." batch mode =".$public_batch); Logger::notice("no url for contact: ".$contact["id"]." batch mode =".$public_batch);
return 0; return 0;
} }
Logger::log("transmit: ".$logid."-".$guid." ".$dest_url); Logger::notice("transmit: ".$logid."-".$guid." ".$dest_url);
if (!intval(DI::config()->get("system", "diaspora_test"))) { if (!intval(DI::config()->get("system", "diaspora_test"))) {
$content_type = (($public_batch) ? "application/magic-envelope+xml" : "application/json"); $content_type = (($public_batch) ? "application/magic-envelope+xml" : "application/json");
@ -3025,11 +3005,11 @@ class Diaspora
$postResult = DI::httpClient()->post($dest_url . "/", $envelope, ['Content-Type' => $content_type]); $postResult = DI::httpClient()->post($dest_url . "/", $envelope, ['Content-Type' => $content_type]);
$return_code = $postResult->getReturnCode(); $return_code = $postResult->getReturnCode();
} else { } else {
Logger::log("test_mode"); Logger::notice("test_mode");
return 200; return 200;
} }
Logger::log("transmit: ".$logid."-".$guid." to ".$dest_url." returns: ".$return_code); Logger::notice("transmit: ".$logid."-".$guid." to ".$dest_url." returns: ".$return_code);
return $return_code ? $return_code : -1; return $return_code ? $return_code : -1;
} }
@ -3141,7 +3121,7 @@ class Diaspora
"parent_type" => "Post", "parent_type" => "Post",
"parent_guid" => $item["guid"]]; "parent_guid" => $item["guid"]];
Logger::log("Send participation for ".$item["guid"]." by ".$author, Logger::DEBUG); Logger::info("Send participation for ".$item["guid"]." by ".$author);
// It doesn't matter what we store, we only want to avoid sending repeated notifications for the same item // It doesn't matter what we store, we only want to avoid sending repeated notifications for the same item
DI::cache()->set($cachekey, $item["guid"], Duration::QUARTER_HOUR); DI::cache()->set($cachekey, $item["guid"], Duration::QUARTER_HOUR);
@ -3310,29 +3290,18 @@ class Diaspora
*/ */
private static function buildEvent($event_id) private static function buildEvent($event_id)
{ {
$r = q("SELECT `guid`, `uid`, `start`, `finish`, `nofinish`, `summary`, `desc`, `location`, `adjust` FROM `event` WHERE `id` = %d", intval($event_id)); $event = DBA::selectFirst('event', [], ['id' => $event_id]);
if (!DBA::isResult($r)) { if (!DBA::isResult($event)) {
return []; return [];
} }
$event = $r[0];
$eventdata = []; $eventdata = [];
$r = q("SELECT `timezone` FROM `user` WHERE `uid` = %d", intval($event['uid'])); $owner = User::getOwnerDataById($event['uid']);
if (!DBA::isResult($r)) { if (!$owner) {
return []; return [];
} }
$user = $r[0];
$r = q("SELECT `addr`, `nick` FROM `contact` WHERE `uid` = %d AND `self`", intval($event['uid']));
if (!DBA::isResult($r)) {
return [];
}
$owner = $r[0];
$eventdata['author'] = self::myHandle($owner); $eventdata['author'] = self::myHandle($owner);
if ($event['guid']) { if ($event['guid']) {
@ -3345,8 +3314,8 @@ class Diaspora
$eventdata["all_day"] = "false"; $eventdata["all_day"] = "false";
$eventdata['timezone'] = 'UTC'; $eventdata['timezone'] = 'UTC';
if (!$event['adjust'] && $user['timezone']) { if (!$event['adjust'] && $owner['timezone']) {
$eventdata['timezone'] = $user['timezone']; $eventdata['timezone'] = $owner['timezone'];
} }
if ($event['start']) { if ($event['start']) {
@ -3594,7 +3563,7 @@ class Diaspora
$attend_answer = 'tentative'; $attend_answer = 'tentative';
break; break;
default: default:
Logger::log('Unknown verb '.$item['verb'].' in item '.$item['guid']); Logger::notice('Unknown verb '.$item['verb'].' in item '.$item['guid']);
return false; return false;
} }
@ -3728,7 +3697,7 @@ class Diaspora
$type = "comment"; $type = "comment";
} }
Logger::log("Got relayable data ".$type." for item ".$item["guid"]." (".$item["id"].")", Logger::DEBUG); Logger::info("Got relayable data ".$type." for item ".$item["guid"]." (".$item["id"].")");
$msg = json_decode($item['signed_text'], true); $msg = json_decode($item['signed_text'], true);
@ -3747,7 +3716,7 @@ class Diaspora
$message[$field] = $data; $message[$field] = $data;
} }
} else { } else {
Logger::log("Signature text for item ".$item["guid"]." (".$item["id"].") couldn't be extracted: ".$item['signed_text'], Logger::DEBUG); Logger::info("Signature text for item ".$item["guid"]." (".$item["id"].") couldn't be extracted: ".$item['signed_text']);
} }
$message["parent_author_signature"] = self::signature($owner, $message); $message["parent_author_signature"] = self::signature($owner, $message);
@ -3809,7 +3778,7 @@ class Diaspora
$cnv = DBA::selectFirst('conv', [], ['id' => $item["convid"], 'uid' => $item["uid"]]); $cnv = DBA::selectFirst('conv', [], ['id' => $item["convid"], 'uid' => $item["uid"]]);
if (!DBA::isResult($cnv)) { if (!DBA::isResult($cnv)) {
Logger::log("conversation not found."); Logger::notice("conversation not found.");
return; return;
} }
@ -4004,7 +3973,7 @@ class Diaspora
// @ToDo Split this into single worker jobs // @ToDo Split this into single worker jobs
foreach ($recips as $recip) { foreach ($recips as $recip) {
Logger::log("Send updated profile data for user ".$uid." to contact ".$recip["id"], Logger::DEBUG); Logger::info("Send updated profile data for user ".$uid." to contact ".$recip["id"]);
self::buildAndTransmit($owner, $recip, "profile", $message); self::buildAndTransmit($owner, $recip, "profile", $message);
} }
} }

View file

@ -241,6 +241,7 @@ return [
'/{id:\d+}/media' => [Module\Contact::class, [R::GET]], '/{id:\d+}/media' => [Module\Contact::class, [R::GET]],
'/{id:\d+}/poke' => [Module\Contact\Poke::class, [R::GET, R::POST]], '/{id:\d+}/poke' => [Module\Contact\Poke::class, [R::GET, R::POST]],
'/{id:\d+}/posts' => [Module\Contact::class, [R::GET]], '/{id:\d+}/posts' => [Module\Contact::class, [R::GET]],
'/{id:\d+}/revoke' => [Module\Contact\Revoke::class, [R::GET, R::POST]],
'/{id:\d+}/update' => [Module\Contact::class, [R::GET]], '/{id:\d+}/update' => [Module\Contact::class, [R::GET]],
'/{id:\d+}/updateprofile' => [Module\Contact::class, [R::GET]], '/{id:\d+}/updateprofile' => [Module\Contact::class, [R::GET]],
'/archived' => [Module\Contact::class, [R::GET]], '/archived' => [Module\Contact::class, [R::GET]],

View file

@ -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 15:13+0000\n" "POT-Creation-Date: 2021-10-02 18:34+0000\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"
@ -38,7 +38,7 @@ msgid "Monthly posting limit of %d post reached. The post was rejected."
msgstr "" msgstr ""
#: include/api.php:4430 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:1037 mod/photos.php:1054 mod/photos.php:1603
#: 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
#: src/Module/Settings/Profile/Photo/Crop.php:117 #: src/Module/Settings/Profile/Photo/Crop.php:117
@ -446,7 +446,7 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: mod/editpost.php:92 mod/photos.php:1375 src/Content/Conversation.php:326 #: mod/editpost.php:92 mod/photos.php:1379 src/Content/Conversation.php:326
#: src/Module/Contact/Poke.php:157 src/Object/Post.php:964 #: src/Module/Contact/Poke.php:157 src/Object/Post.php:964
msgid "Loading..." msgid "Loading..."
msgstr "" msgstr ""
@ -511,7 +511,7 @@ msgid "clear location"
msgstr "" msgstr ""
#: mod/editpost.php:107 mod/message.php:203 mod/message.php:368 #: mod/editpost.php:107 mod/message.php:203 mod/message.php:368
#: mod/photos.php:1526 mod/wallmessage.php:155 src/Content/Conversation.php:355 #: mod/photos.php:1530 mod/wallmessage.php:155 src/Content/Conversation.php:355
#: src/Content/Conversation.php:689 src/Module/Item/Compose.php:165 #: src/Content/Conversation.php:689 src/Module/Item/Compose.php:165
#: src/Object/Post.php:502 #: src/Object/Post.php:502
msgid "Please wait" msgid "Please wait"
@ -543,16 +543,17 @@ msgstr ""
msgid "Example: bob@example.com, mary@example.com" msgid "Example: bob@example.com, mary@example.com"
msgstr "" msgstr ""
#: mod/editpost.php:128 mod/events.php:578 mod/photos.php:1374 #: mod/editpost.php:128 mod/events.php:578 mod/photos.php:1378
#: mod/photos.php:1430 mod/photos.php:1504 src/Content/Conversation.php:370 #: mod/photos.php:1434 mod/photos.php:1508 src/Content/Conversation.php:370
#: src/Module/Item/Compose.php:160 src/Object/Post.php:974 #: src/Module/Item/Compose.php:160 src/Object/Post.php:974
msgid "Preview" msgid "Preview"
msgstr "" msgstr ""
#: mod/editpost.php:130 mod/fbrowser.php:105 mod/fbrowser.php:134 #: mod/editpost.php:130 mod/fbrowser.php:105 mod/fbrowser.php:134
#: mod/follow.php:144 mod/photos.php:1029 mod/photos.php:1136 mod/tagrm.php:37 #: mod/follow.php:144 mod/photos.php:1026 mod/photos.php:1135 mod/tagrm.php:37
#: mod/tagrm.php:129 mod/unfollow.php:97 src/Content/Conversation.php:373 #: mod/tagrm.php:129 mod/unfollow.php:97 src/Content/Conversation.php:373
#: src/Module/Contact.php:448 src/Module/RemoteFollow.php:116 #: src/Module/Contact.php:444 src/Module/Contact/Revoke.php:99
#: src/Module/RemoteFollow.php:116
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr ""
@ -568,7 +569,7 @@ msgid "Browser"
msgstr "" msgstr ""
#: mod/editpost.php:136 mod/events.php:583 mod/photos.php:965 #: mod/editpost.php:136 mod/events.php:583 mod/photos.php:965
#: mod/photos.php:1328 src/Content/Conversation.php:357 #: mod/photos.php:1332 src/Content/Conversation.php:357
msgid "Permissions" msgid "Permissions"
msgstr "" msgstr ""
@ -637,7 +638,7 @@ msgstr ""
#: mod/events.php:568 src/Content/Widget/VCard.php:98 src/Model/Event.php:86 #: mod/events.php:568 src/Content/Widget/VCard.php:98 src/Model/Event.php:86
#: src/Model/Event.php:113 src/Model/Event.php:483 src/Model/Event.php:969 #: src/Model/Event.php:113 src/Model/Event.php:483 src/Model/Event.php:969
#: src/Model/Profile.php:367 src/Module/Contact.php:628 #: src/Model/Profile.php:367 src/Module/Contact.php:630
#: src/Module/Directory.php:150 src/Module/Notifications/Introductions.php:166 #: src/Module/Directory.php:150 src/Module/Notifications/Introductions.php:166
#: src/Module/Profile/Profile.php:194 #: src/Module/Profile/Profile.php:194
msgid "Location:" msgid "Location:"
@ -652,9 +653,9 @@ msgid "Share this event"
msgstr "" msgstr ""
#: mod/events.php:580 mod/message.php:204 mod/message.php:367 #: mod/events.php:580 mod/message.php:204 mod/message.php:367
#: mod/photos.php:947 mod/photos.php:1046 mod/photos.php:1332 #: mod/photos.php:947 mod/photos.php:1048 mod/photos.php:1336
#: mod/photos.php:1373 mod/photos.php:1429 mod/photos.php:1503 #: mod/photos.php:1377 mod/photos.php:1433 mod/photos.php:1507
#: src/Module/Admin/Item/Source.php:65 src/Module/Contact.php:586 #: src/Module/Admin/Item/Source.php:65 src/Module/Contact.php:588
#: src/Module/Contact/Advanced.php:133 src/Module/Contact/Poke.php:158 #: src/Module/Contact/Advanced.php:133 src/Module/Contact/Poke.php:158
#: src/Module/Debug/ActivityPubConversion.php:141 #: src/Module/Debug/ActivityPubConversion.php:141
#: src/Module/Debug/Babel.php:313 src/Module/Debug/Localtime.php:64 #: src/Module/Debug/Babel.php:313 src/Module/Debug/Localtime.php:64
@ -673,7 +674,7 @@ msgstr ""
msgid "Basic" msgid "Basic"
msgstr "" msgstr ""
#: mod/events.php:582 src/Module/Admin/Site.php:505 src/Module/Contact.php:945 #: mod/events.php:582 src/Module/Admin/Site.php:505 src/Module/Contact.php:947
#: src/Module/Profile/Profile.php:249 #: src/Module/Profile/Profile.php:249
msgid "Advanced" msgid "Advanced"
msgstr "" msgstr ""
@ -717,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:1046 src/Model/Contact.php:1059 #: src/Model/Contact.php:1076 src/Model/Contact.php:1089
#: view/theme/vier/theme.php:172 #: view/theme/vier/theme.php:172
msgid "Connect/Follow" msgid "Connect/Follow"
msgstr "" msgstr ""
@ -731,13 +732,13 @@ msgid "Your Identity Address:"
msgstr "" msgstr ""
#: mod/follow.php:141 mod/unfollow.php:100 #: mod/follow.php:141 mod/unfollow.php:100
#: src/Module/Admin/Blocklist/Contact.php:100 src/Module/Contact.php:624 #: src/Module/Admin/Blocklist/Contact.php:100 src/Module/Contact.php:626
#: src/Module/Notifications/Introductions.php:108 #: src/Module/Notifications/Introductions.php:108
#: src/Module/Notifications/Introductions.php:177 #: src/Module/Notifications/Introductions.php:177
msgid "Profile URL" msgid "Profile URL"
msgstr "" msgstr ""
#: mod/follow.php:142 src/Module/Contact.php:636 #: mod/follow.php:142 src/Module/Contact.php:638
#: src/Module/Notifications/Introductions.php:170 #: src/Module/Notifications/Introductions.php:170
#: src/Module/Profile/Profile.php:207 #: src/Module/Profile/Profile.php:207
msgid "Tags:" msgid "Tags:"
@ -753,7 +754,7 @@ msgid "Add a personal note:"
msgstr "" msgstr ""
#: mod/follow.php:163 mod/unfollow.php:109 src/Module/BaseProfile.php:59 #: mod/follow.php:163 mod/unfollow.php:109 src/Module/BaseProfile.php:59
#: src/Module/Contact.php:915 #: src/Module/Contact.php:917
msgid "Status Messages and Posts" msgid "Status Messages and Posts"
msgstr "" msgstr ""
@ -1112,11 +1113,11 @@ msgstr ""
msgid "Photo Albums" msgid "Photo Albums"
msgstr "" msgstr ""
#: mod/photos.php:112 mod/photos.php:1628 #: mod/photos.php:112 mod/photos.php:1632
msgid "Recent Photos" msgid "Recent Photos"
msgstr "" msgstr ""
#: mod/photos.php:114 mod/photos.php:1097 mod/photos.php:1630 #: mod/photos.php:114 mod/photos.php:1099 mod/photos.php:1634
msgid "Upload New Photos" msgid "Upload New Photos"
msgstr "" msgstr ""
@ -1199,7 +1200,7 @@ msgstr ""
msgid "Upload Photos" msgid "Upload Photos"
msgstr "" msgstr ""
#: mod/photos.php:961 mod/photos.php:1042 #: mod/photos.php:961 mod/photos.php:1044
msgid "New album name: " msgid "New album name: "
msgstr "" msgstr ""
@ -1215,149 +1216,149 @@ msgstr ""
msgid "Do you really want to delete this photo album and all its photos?" msgid "Do you really want to delete this photo album and all its photos?"
msgstr "" msgstr ""
#: mod/photos.php:1025 mod/photos.php:1047 #: mod/photos.php:1025 mod/photos.php:1049
msgid "Delete Album" msgid "Delete Album"
msgstr "" msgstr ""
#: mod/photos.php:1053 #: mod/photos.php:1055
msgid "Edit Album" msgid "Edit Album"
msgstr "" msgstr ""
#: mod/photos.php:1054 #: mod/photos.php:1056
msgid "Drop Album" msgid "Drop Album"
msgstr "" msgstr ""
#: mod/photos.php:1059 #: mod/photos.php:1061
msgid "Show Newest First" msgid "Show Newest First"
msgstr "" msgstr ""
#: mod/photos.php:1061 #: mod/photos.php:1063
msgid "Show Oldest First" msgid "Show Oldest First"
msgstr "" msgstr ""
#: mod/photos.php:1082 mod/photos.php:1613 #: mod/photos.php:1084 mod/photos.php:1617
msgid "View Photo" msgid "View Photo"
msgstr "" msgstr ""
#: mod/photos.php:1119 #: mod/photos.php:1121
msgid "Permission denied. Access to this item may be restricted." msgid "Permission denied. Access to this item may be restricted."
msgstr "" msgstr ""
#: mod/photos.php:1121 #: mod/photos.php:1123
msgid "Photo not available" msgid "Photo not available"
msgstr "" msgstr ""
#: mod/photos.php:1131 #: mod/photos.php:1133
msgid "Do you really want to delete this photo?" msgid "Do you really want to delete this photo?"
msgstr "" msgstr ""
#: mod/photos.php:1132 mod/photos.php:1333 #: mod/photos.php:1134 mod/photos.php:1337
msgid "Delete Photo" msgid "Delete Photo"
msgstr "" msgstr ""
#: mod/photos.php:1224 #: mod/photos.php:1228
msgid "View photo" msgid "View photo"
msgstr "" msgstr ""
#: mod/photos.php:1226 #: mod/photos.php:1230
msgid "Edit photo" msgid "Edit photo"
msgstr "" msgstr ""
#: mod/photos.php:1227 #: mod/photos.php:1231
msgid "Delete photo" msgid "Delete photo"
msgstr "" msgstr ""
#: mod/photos.php:1228 #: mod/photos.php:1232
msgid "Use as profile photo" msgid "Use as profile photo"
msgstr "" msgstr ""
#: mod/photos.php:1235 #: mod/photos.php:1239
msgid "Private Photo" msgid "Private Photo"
msgstr "" msgstr ""
#: mod/photos.php:1241 #: mod/photos.php:1245
msgid "View Full Size" msgid "View Full Size"
msgstr "" msgstr ""
#: mod/photos.php:1301 #: mod/photos.php:1305
msgid "Tags: " msgid "Tags: "
msgstr "" msgstr ""
#: mod/photos.php:1304 #: mod/photos.php:1308
msgid "[Select tags to remove]" msgid "[Select tags to remove]"
msgstr "" msgstr ""
#: mod/photos.php:1319 #: mod/photos.php:1323
msgid "New album name" msgid "New album name"
msgstr "" msgstr ""
#: mod/photos.php:1320 #: mod/photos.php:1324
msgid "Caption" msgid "Caption"
msgstr "" msgstr ""
#: mod/photos.php:1321 #: mod/photos.php:1325
msgid "Add a Tag" msgid "Add a Tag"
msgstr "" msgstr ""
#: mod/photos.php:1321 #: mod/photos.php:1325
msgid "Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping" msgid "Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping"
msgstr "" msgstr ""
#: mod/photos.php:1322 #: mod/photos.php:1326
msgid "Do not rotate" msgid "Do not rotate"
msgstr "" msgstr ""
#: mod/photos.php:1323 #: mod/photos.php:1327
msgid "Rotate CW (right)" msgid "Rotate CW (right)"
msgstr "" msgstr ""
#: mod/photos.php:1324 #: mod/photos.php:1328
msgid "Rotate CCW (left)" msgid "Rotate CCW (left)"
msgstr "" msgstr ""
#: mod/photos.php:1370 mod/photos.php:1426 mod/photos.php:1500 #: mod/photos.php:1374 mod/photos.php:1430 mod/photos.php:1504
#: src/Module/Contact.php:1075 src/Module/Item/Compose.php:148 #: src/Module/Contact.php:1077 src/Module/Item/Compose.php:148
#: src/Object/Post.php:960 #: src/Object/Post.php:960
msgid "This is you" msgid "This is you"
msgstr "" msgstr ""
#: mod/photos.php:1372 mod/photos.php:1428 mod/photos.php:1502 #: mod/photos.php:1376 mod/photos.php:1432 mod/photos.php:1506
#: src/Object/Post.php:496 src/Object/Post.php:962 #: src/Object/Post.php:496 src/Object/Post.php:962
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
#: mod/photos.php:1461 src/Content/Conversation.php:615 src/Object/Post.php:227 #: mod/photos.php:1465 src/Content/Conversation.php:615 src/Object/Post.php:227
msgid "Select" msgid "Select"
msgstr "" msgstr ""
#: mod/photos.php:1462 mod/settings.php:573 src/Content/Conversation.php:616 #: mod/photos.php:1466 mod/settings.php:573 src/Content/Conversation.php:616
#: src/Module/Admin/Users/Active.php:139 src/Module/Admin/Users/Blocked.php:140 #: src/Module/Admin/Users/Active.php:139 src/Module/Admin/Users/Blocked.php:140
#: src/Module/Admin/Users/Index.php:153 src/Module/Contact.php:870 #: src/Module/Admin/Users/Index.php:153 src/Module/Contact.php:872
#: src/Module/Contact.php:1163 #: src/Module/Contact.php:1175
msgid "Delete" msgid "Delete"
msgstr "" msgstr ""
#: mod/photos.php:1523 src/Object/Post.php:349 #: mod/photos.php:1527 src/Object/Post.php:349
msgid "Like" msgid "Like"
msgstr "" msgstr ""
#: mod/photos.php:1524 src/Object/Post.php:349 #: mod/photos.php:1528 src/Object/Post.php:349
msgid "I like this (toggle)" msgid "I like this (toggle)"
msgstr "" msgstr ""
#: mod/photos.php:1525 src/Object/Post.php:350 #: mod/photos.php:1529 src/Object/Post.php:350
msgid "Dislike" msgid "Dislike"
msgstr "" msgstr ""
#: mod/photos.php:1527 src/Object/Post.php:350 #: mod/photos.php:1531 src/Object/Post.php:350
msgid "I don't like this (toggle)" msgid "I don't like this (toggle)"
msgstr "" msgstr ""
#: mod/photos.php:1549 #: mod/photos.php:1553
msgid "Map" msgid "Map"
msgstr "" msgstr ""
#: mod/photos.php:1619 #: mod/photos.php:1623
msgid "View Album" msgid "View Album"
msgstr "" msgstr ""
@ -2396,16 +2397,16 @@ msgid "All contacts"
msgstr "" msgstr ""
#: src/BaseModule.php:212 src/Content/Widget.php:238 src/Core/ACL.php:195 #: src/BaseModule.php:212 src/Content/Widget.php:238 src/Core/ACL.php:195
#: src/Module/Contact.php:836 src/Module/PermissionTooltip.php:77 #: src/Module/Contact.php:838 src/Module/PermissionTooltip.php:77
#: src/Module/PermissionTooltip.php:99 #: src/Module/PermissionTooltip.php:99
msgid "Followers" msgid "Followers"
msgstr "" msgstr ""
#: src/BaseModule.php:217 src/Content/Widget.php:239 src/Module/Contact.php:837 #: src/BaseModule.php:217 src/Content/Widget.php:239 src/Module/Contact.php:839
msgid "Following" msgid "Following"
msgstr "" msgstr ""
#: src/BaseModule.php:222 src/Content/Widget.php:240 src/Module/Contact.php:838 #: src/BaseModule.php:222 src/Content/Widget.php:240 src/Module/Contact.php:840
msgid "Mutual friends" msgid "Mutual friends"
msgstr "" msgstr ""
@ -3003,43 +3004,43 @@ msgstr ""
msgid "Follow Thread" msgid "Follow Thread"
msgstr "" msgstr ""
#: src/Content/Item.php:443 src/Model/Contact.php:1051 #: src/Content/Item.php:443 src/Model/Contact.php:1081
msgid "View Status" msgid "View Status"
msgstr "" msgstr ""
#: src/Content/Item.php:444 src/Content/Item.php:466 src/Model/Contact.php:977 #: src/Content/Item.php:444 src/Content/Item.php:466 src/Model/Contact.php:1007
#: src/Model/Contact.php:1043 src/Model/Contact.php:1052 #: src/Model/Contact.php:1073 src/Model/Contact.php:1082
#: 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:1053 #: src/Content/Item.php:445 src/Model/Contact.php:1083
msgid "View Photos" msgid "View Photos"
msgstr "" msgstr ""
#: src/Content/Item.php:446 src/Model/Contact.php:1044 #: src/Content/Item.php:446 src/Model/Contact.php:1074
#: src/Model/Contact.php:1054 #: src/Model/Contact.php:1084
msgid "Network Posts" msgid "Network Posts"
msgstr "" msgstr ""
#: src/Content/Item.php:447 src/Model/Contact.php:1045 #: src/Content/Item.php:447 src/Model/Contact.php:1075
#: src/Model/Contact.php:1055 #: src/Model/Contact.php:1085
msgid "View Contact" msgid "View Contact"
msgstr "" msgstr ""
#: src/Content/Item.php:448 src/Model/Contact.php:1057 #: src/Content/Item.php:448 src/Model/Contact.php:1087
msgid "Send PM" msgid "Send PM"
msgstr "" msgstr ""
#: src/Content/Item.php:449 src/Module/Admin/Blocklist/Contact.php:84 #: src/Content/Item.php:449 src/Module/Admin/Blocklist/Contact.php:84
#: src/Module/Admin/Users/Active.php:140 src/Module/Admin/Users/Index.php:154 #: src/Module/Admin/Users/Active.php:140 src/Module/Admin/Users/Index.php:154
#: src/Module/Contact.php:607 src/Module/Contact.php:868 #: src/Module/Contact.php:609 src/Module/Contact.php:870
#: src/Module/Contact.php:1146 #: src/Module/Contact.php:1148
msgid "Block" msgid "Block"
msgstr "" msgstr ""
#: src/Content/Item.php:450 src/Module/Contact.php:608 #: src/Content/Item.php:450 src/Module/Contact.php:610
#: src/Module/Contact.php:869 src/Module/Contact.php:1154 #: src/Module/Contact.php:871 src/Module/Contact.php:1156
#: src/Module/Notifications/Introductions.php:113 #: src/Module/Notifications/Introductions.php:113
#: src/Module/Notifications/Introductions.php:185 #: src/Module/Notifications/Introductions.php:185
#: src/Module/Notifications/Notification.php:59 #: src/Module/Notifications/Notification.php:59
@ -3050,7 +3051,7 @@ msgstr ""
msgid "Languages" msgid "Languages"
msgstr "" msgstr ""
#: src/Content/Item.php:458 src/Model/Contact.php:1058 #: src/Content/Item.php:458 src/Model/Contact.php:1088
msgid "Poke" msgid "Poke"
msgstr "" msgstr ""
@ -3088,7 +3089,7 @@ msgid "Sign in"
msgstr "" msgstr ""
#: src/Content/Nav.php:190 src/Module/BaseProfile.php:56 #: src/Content/Nav.php:190 src/Module/BaseProfile.php:56
#: src/Module/Contact.php:639 src/Module/Contact.php:904 #: src/Module/Contact.php:641 src/Module/Contact.php:906
#: src/Module/Settings/TwoFactor/Index.php:112 view/theme/frio/theme.php:226 #: src/Module/Settings/TwoFactor/Index.php:112 view/theme/frio/theme.php:226
msgid "Status" msgid "Status"
msgstr "" msgstr ""
@ -3099,8 +3100,8 @@ msgid "Your posts and conversations"
msgstr "" msgstr ""
#: src/Content/Nav.php:191 src/Module/BaseProfile.php:48 #: src/Content/Nav.php:191 src/Module/BaseProfile.php:48
#: src/Module/BaseSettings.php:57 src/Module/Contact.php:641 #: src/Module/BaseSettings.php:57 src/Module/Contact.php:643
#: src/Module/Contact.php:928 src/Module/Profile/Profile.php:241 #: src/Module/Contact.php:930 src/Module/Profile/Profile.php:241
#: src/Module/Welcome.php:57 view/theme/frio/theme.php:227 #: src/Module/Welcome.php:57 view/theme/frio/theme.php:227
msgid "Profile" msgid "Profile"
msgstr "" msgstr ""
@ -3186,8 +3187,8 @@ msgstr ""
#: src/Content/Nav.php:235 src/Content/Nav.php:294 #: src/Content/Nav.php:235 src/Content/Nav.php:294
#: src/Content/Text/HTML.php:902 src/Module/BaseProfile.php:125 #: src/Content/Text/HTML.php:902 src/Module/BaseProfile.php:125
#: src/Module/BaseProfile.php:128 src/Module/Contact.php:839 #: src/Module/BaseProfile.php:128 src/Module/Contact.php:841
#: src/Module/Contact.php:935 view/theme/frio/theme.php:237 #: src/Module/Contact.php:937 view/theme/frio/theme.php:237
msgid "Contacts" msgid "Contacts"
msgstr "" msgstr ""
@ -3417,7 +3418,7 @@ msgstr ""
msgid "Examples: Robert Morgenstein, Fishing" msgid "Examples: Robert Morgenstein, Fishing"
msgstr "" msgstr ""
#: src/Content/Widget.php:78 src/Module/Contact.php:860 #: src/Content/Widget.php:78 src/Module/Contact.php:862
#: src/Module/Directory.php:99 view/theme/vier/theme.php:174 #: src/Module/Directory.php:99 view/theme/vier/theme.php:174
msgid "Find" msgid "Find"
msgstr "" msgstr ""
@ -3444,7 +3445,7 @@ msgid "Local Directory"
msgstr "" msgstr ""
#: src/Content/Widget.php:214 src/Model/Group.php:535 #: src/Content/Widget.php:214 src/Model/Group.php:535
#: src/Module/Contact.php:823 src/Module/Welcome.php:76 #: src/Module/Contact.php:825 src/Module/Welcome.php:76
msgid "Groups" msgid "Groups"
msgstr "" msgstr ""
@ -3456,7 +3457,7 @@ msgstr ""
msgid "Relationships" msgid "Relationships"
msgstr "" msgstr ""
#: src/Content/Widget.php:247 src/Module/Contact.php:775 #: src/Content/Widget.php:247 src/Module/Contact.php:777
#: src/Module/Group.php:292 #: src/Module/Group.php:292
msgid "All Contacts" msgid "All Contacts"
msgstr "" msgstr ""
@ -3500,7 +3501,7 @@ msgstr ""
msgid "Organisations" msgid "Organisations"
msgstr "" msgstr ""
#: src/Content/Widget.php:529 src/Model/Contact.php:1481 #: src/Content/Widget.php:529 src/Model/Contact.php:1509
msgid "News" msgid "News"
msgstr "" msgstr ""
@ -3555,12 +3556,12 @@ msgid "More Trending Tags"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:96 src/Model/Profile.php:372 #: src/Content/Widget/VCard.php:96 src/Model/Profile.php:372
#: src/Module/Contact.php:630 src/Module/Profile/Profile.php:176 #: src/Module/Contact.php:632 src/Module/Profile/Profile.php:176
msgid "XMPP:" msgid "XMPP:"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:97 src/Model/Profile.php:373 #: src/Content/Widget/VCard.php:97 src/Model/Profile.php:373
#: src/Module/Contact.php:632 src/Module/Profile/Profile.php:180 #: src/Module/Contact.php:634 src/Module/Profile/Profile.php:180
msgid "Matrix:" msgid "Matrix:"
msgstr "" msgstr ""
@ -4364,85 +4365,85 @@ msgstr ""
msgid "Legacy module file not found: %s" msgid "Legacy module file not found: %s"
msgstr "" msgstr ""
#: src/Model/Contact.php:1047 src/Model/Contact.php:1060 #: src/Model/Contact.php:1077 src/Model/Contact.php:1090
msgid "UnFollow" msgid "UnFollow"
msgstr "" msgstr ""
#: src/Model/Contact.php:1056 #: src/Model/Contact.php:1086
msgid "Drop Contact" msgid "Drop Contact"
msgstr "" msgstr ""
#: src/Model/Contact.php:1066 src/Module/Admin/Users/Pending.php:107 #: src/Model/Contact.php:1096 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:1477 #: src/Model/Contact.php:1505
msgid "Organisation" msgid "Organisation"
msgstr "" msgstr ""
#: src/Model/Contact.php:1485 #: src/Model/Contact.php:1513
msgid "Forum" msgid "Forum"
msgstr "" msgstr ""
#: src/Model/Contact.php:2341 #: src/Model/Contact.php:2369
msgid "Disallowed profile URL." msgid "Disallowed profile URL."
msgstr "" msgstr ""
#: src/Model/Contact.php:2346 src/Module/Friendica.php:81 #: src/Model/Contact.php:2374 src/Module/Friendica.php:81
msgid "Blocked domain" msgid "Blocked domain"
msgstr "" msgstr ""
#: src/Model/Contact.php:2351 #: src/Model/Contact.php:2379
msgid "Connect URL missing." msgid "Connect URL missing."
msgstr "" msgstr ""
#: src/Model/Contact.php:2360 #: src/Model/Contact.php:2388
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:2397 #: src/Model/Contact.php:2425
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:2399 #: src/Model/Contact.php:2427
msgid "No compatible communication protocols or feeds were discovered." msgid "No compatible communication protocols or feeds were discovered."
msgstr "" msgstr ""
#: src/Model/Contact.php:2402 #: src/Model/Contact.php:2430
msgid "An author or name was not found." msgid "An author or name was not found."
msgstr "" msgstr ""
#: src/Model/Contact.php:2405 #: src/Model/Contact.php:2433
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:2408 #: src/Model/Contact.php:2436
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:2409 #: src/Model/Contact.php:2437
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:2415 #: src/Model/Contact.php:2443
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:2420 #: src/Model/Contact.php:2448
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:2479 #: src/Model/Contact.php:2507
msgid "Unable to retrieve contact information." msgid "Unable to retrieve contact information."
msgstr "" msgstr ""
@ -4712,7 +4713,7 @@ msgstr ""
msgid "Homepage:" msgid "Homepage:"
msgstr "" msgstr ""
#: src/Model/Profile.php:371 src/Module/Contact.php:634 #: src/Model/Profile.php:371 src/Module/Contact.php:636
#: src/Module/Notifications/Introductions.php:168 #: src/Module/Notifications/Introductions.php:168
msgid "About:" msgid "About:"
msgstr "" msgstr ""
@ -5113,8 +5114,8 @@ msgstr ""
msgid "List of active accounts" msgid "List of active accounts"
msgstr "" msgstr ""
#: src/Module/Admin/BaseUsers.php:66 src/Module/Contact.php:783 #: src/Module/Admin/BaseUsers.php:66 src/Module/Contact.php:785
#: src/Module/Contact.php:843 #: src/Module/Contact.php:845
msgid "Pending" msgid "Pending"
msgstr "" msgstr ""
@ -5122,8 +5123,8 @@ msgstr ""
msgid "List of pending registrations" msgid "List of pending registrations"
msgstr "" msgstr ""
#: src/Module/Admin/BaseUsers.php:74 src/Module/Contact.php:791 #: src/Module/Admin/BaseUsers.php:74 src/Module/Contact.php:793
#: src/Module/Contact.php:844 #: src/Module/Contact.php:846
msgid "Blocked" msgid "Blocked"
msgstr "" msgstr ""
@ -5180,8 +5181,8 @@ msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:85 #: src/Module/Admin/Blocklist/Contact.php:85
#: src/Module/Admin/Users/Blocked.php:142 src/Module/Admin/Users/Index.php:156 #: src/Module/Admin/Users/Blocked.php:142 src/Module/Admin/Users/Index.php:156
#: src/Module/Contact.php:607 src/Module/Contact.php:868 #: src/Module/Contact.php:609 src/Module/Contact.php:870
#: src/Module/Contact.php:1146 #: src/Module/Contact.php:1148
msgid "Unblock" msgid "Unblock"
msgstr "" msgstr ""
@ -6527,7 +6528,7 @@ msgid ""
"received." "received."
msgstr "" msgstr ""
#: src/Module/Admin/Site.php:609 src/Module/Contact.php:536 #: src/Module/Admin/Site.php:609 src/Module/Contact.php:538
#: src/Module/Settings/TwoFactor/Index.php:118 #: src/Module/Settings/TwoFactor/Index.php:118
msgid "Disabled" msgid "Disabled"
msgstr "" msgstr ""
@ -7220,12 +7221,12 @@ msgstr ""
msgid "Too Many Requests" msgid "Too Many Requests"
msgstr "" msgstr ""
#: src/Module/BaseProfile.php:51 src/Module/Contact.php:931 #: src/Module/BaseProfile.php:51 src/Module/Contact.php:933
msgid "Profile Details" msgid "Profile Details"
msgstr "" msgstr ""
#: src/Module/BaseProfile.php:72 src/Module/BaseProfile.php:75 #: src/Module/BaseProfile.php:72 src/Module/BaseProfile.php:75
#: src/Module/Contact.php:920 #: src/Module/Contact.php:922
msgid "Media" msgid "Media"
msgstr "" msgstr ""
@ -7331,330 +7332,339 @@ msgstr ""
msgid "Contact has been unignored" msgid "Contact has been unignored"
msgstr "" msgstr ""
#: src/Module/Contact.php:440 #: src/Module/Contact.php:441
msgid "Drop contact" msgid "Drop contact"
msgstr "" msgstr ""
#: src/Module/Contact.php:443 src/Module/Contact.php:864 #: src/Module/Contact.php:442 src/Module/Contact.php:866
msgid "Do you really want to delete this contact?" msgid "Do you really want to delete this contact?"
msgstr "" msgstr ""
#: src/Module/Contact.php:444 src/Module/Notifications/Introductions.php:123 #: src/Module/Contact.php:443 src/Module/Contact/Revoke.php:98
#: src/Module/Notifications/Introductions.php:123
#: src/Module/OAuth/Acknowledge.php:47 src/Module/Register.php:117 #: src/Module/OAuth/Acknowledge.php:47 src/Module/Register.php:117
msgid "Yes" msgid "Yes"
msgstr "" msgstr ""
#: src/Module/Contact.php:457 #: src/Module/Contact.php:459
msgid "Contact has been removed." msgid "Contact has been removed."
msgstr "" msgstr ""
#: src/Module/Contact.php:478 #: src/Module/Contact.php:480
#, php-format #, php-format
msgid "You are mutual friends with %s" msgid "You are mutual friends with %s"
msgstr "" msgstr ""
#: src/Module/Contact.php:482 #: src/Module/Contact.php:484
#, php-format #, php-format
msgid "You are sharing with %s" msgid "You are sharing with %s"
msgstr "" msgstr ""
#: src/Module/Contact.php:486 #: src/Module/Contact.php:488
#, php-format #, php-format
msgid "%s is sharing with you" msgid "%s is sharing with you"
msgstr "" msgstr ""
#: src/Module/Contact.php:510 #: src/Module/Contact.php:512
msgid "Private communications are not available for this contact." msgid "Private communications are not available for this contact."
msgstr "" msgstr ""
#: src/Module/Contact.php:512 #: src/Module/Contact.php:514
msgid "Never" msgid "Never"
msgstr "" msgstr ""
#: src/Module/Contact.php:515 #: src/Module/Contact.php:517
msgid "(Update was not successful)" msgid "(Update was not successful)"
msgstr "" msgstr ""
#: src/Module/Contact.php:515 #: src/Module/Contact.php:517
msgid "(Update was successful)" msgid "(Update was successful)"
msgstr "" msgstr ""
#: src/Module/Contact.php:517 src/Module/Contact.php:1117 #: src/Module/Contact.php:519 src/Module/Contact.php:1119
msgid "Suggest friends" msgid "Suggest friends"
msgstr "" msgstr ""
#: src/Module/Contact.php:521 #: src/Module/Contact.php:523
#, php-format #, php-format
msgid "Network type: %s" msgid "Network type: %s"
msgstr "" msgstr ""
#: src/Module/Contact.php:526 #: src/Module/Contact.php:528
msgid "Communications lost with this contact!" msgid "Communications lost with this contact!"
msgstr "" msgstr ""
#: src/Module/Contact.php:532 #: src/Module/Contact.php:534
msgid "Fetch further information for feeds" msgid "Fetch further information for feeds"
msgstr "" msgstr ""
#: src/Module/Contact.php:534 #: src/Module/Contact.php:536
msgid "" msgid ""
"Fetch information like preview pictures, title and teaser from the feed " "Fetch information like preview pictures, title and teaser from the feed "
"item. You can activate this if the feed doesn't contain much text. Keywords " "item. You can activate this if the feed doesn't contain much text. Keywords "
"are taken from the meta header in the feed item and are posted as hash tags." "are taken from the meta header in the feed item and are posted as hash tags."
msgstr "" msgstr ""
#: src/Module/Contact.php:537 #: src/Module/Contact.php:539
msgid "Fetch information" msgid "Fetch information"
msgstr "" msgstr ""
#: src/Module/Contact.php:538 #: src/Module/Contact.php:540
msgid "Fetch keywords" msgid "Fetch keywords"
msgstr "" msgstr ""
#: src/Module/Contact.php:539 #: src/Module/Contact.php:541
msgid "Fetch information and keywords" msgid "Fetch information and keywords"
msgstr "" msgstr ""
#: src/Module/Contact.php:551 src/Module/Contact.php:555 #: src/Module/Contact.php:553 src/Module/Contact.php:557
#: src/Module/Contact.php:558 src/Module/Contact.php:562 #: src/Module/Contact.php:560 src/Module/Contact.php:564
msgid "No mirroring" msgid "No mirroring"
msgstr "" msgstr ""
#: src/Module/Contact.php:552 #: src/Module/Contact.php:554
msgid "Mirror as forwarded posting" msgid "Mirror as forwarded posting"
msgstr "" msgstr ""
#: src/Module/Contact.php:553 src/Module/Contact.php:559 #: src/Module/Contact.php:555 src/Module/Contact.php:561
#: src/Module/Contact.php:563 #: src/Module/Contact.php:565
msgid "Mirror as my own posting" msgid "Mirror as my own posting"
msgstr "" msgstr ""
#: src/Module/Contact.php:556 src/Module/Contact.php:560 #: src/Module/Contact.php:558 src/Module/Contact.php:562
msgid "Native reshare" msgid "Native reshare"
msgstr "" msgstr ""
#: src/Module/Contact.php:575 #: src/Module/Contact.php:577
msgid "Contact Information / Notes" msgid "Contact Information / Notes"
msgstr "" msgstr ""
#: src/Module/Contact.php:576 #: src/Module/Contact.php:578
msgid "Contact Settings" msgid "Contact Settings"
msgstr "" msgstr ""
#: src/Module/Contact.php:584 #: src/Module/Contact.php:586
msgid "Contact" msgid "Contact"
msgstr "" msgstr ""
#: src/Module/Contact.php:588 #: src/Module/Contact.php:590
msgid "Their personal note" msgid "Their personal note"
msgstr "" msgstr ""
#: src/Module/Contact.php:590 #: src/Module/Contact.php:592
msgid "Edit contact notes" msgid "Edit contact notes"
msgstr "" msgstr ""
#: src/Module/Contact.php:593 src/Module/Contact.php:1083 #: src/Module/Contact.php:595 src/Module/Contact.php:1085
#, php-format #, php-format
msgid "Visit %s's profile [%s]" msgid "Visit %s's profile [%s]"
msgstr "" msgstr ""
#: src/Module/Contact.php:594 #: src/Module/Contact.php:596
msgid "Block/Unblock contact" msgid "Block/Unblock contact"
msgstr "" msgstr ""
#: src/Module/Contact.php:595 #: src/Module/Contact.php:597
msgid "Ignore contact" msgid "Ignore contact"
msgstr "" msgstr ""
#: src/Module/Contact.php:596 #: src/Module/Contact.php:598
msgid "View conversations" msgid "View conversations"
msgstr "" msgstr ""
#: src/Module/Contact.php:601 #: src/Module/Contact.php:603
msgid "Last update:" msgid "Last update:"
msgstr "" msgstr ""
#: src/Module/Contact.php:603 #: src/Module/Contact.php:605
msgid "Update public posts" msgid "Update public posts"
msgstr "" msgstr ""
#: src/Module/Contact.php:605 src/Module/Contact.php:1127 #: src/Module/Contact.php:607 src/Module/Contact.php:1129
msgid "Update now" msgid "Update now"
msgstr "" msgstr ""
#: src/Module/Contact.php:608 src/Module/Contact.php:869 #: src/Module/Contact.php:610 src/Module/Contact.php:871
#: src/Module/Contact.php:1154 #: src/Module/Contact.php:1156
msgid "Unignore" msgid "Unignore"
msgstr "" msgstr ""
#: src/Module/Contact.php:612 #: src/Module/Contact.php:614
msgid "Currently blocked" msgid "Currently blocked"
msgstr "" msgstr ""
#: src/Module/Contact.php:613 #: src/Module/Contact.php:615
msgid "Currently ignored" msgid "Currently ignored"
msgstr "" msgstr ""
#: src/Module/Contact.php:614 #: src/Module/Contact.php:616
msgid "Currently archived" msgid "Currently archived"
msgstr "" msgstr ""
#: src/Module/Contact.php:615 #: src/Module/Contact.php:617
msgid "Awaiting connection acknowledge" msgid "Awaiting connection acknowledge"
msgstr "" msgstr ""
#: src/Module/Contact.php:616 src/Module/Notifications/Introductions.php:171 #: src/Module/Contact.php:618 src/Module/Notifications/Introductions.php:171
msgid "Hide this contact from others" msgid "Hide this contact from others"
msgstr "" msgstr ""
#: src/Module/Contact.php:616 #: src/Module/Contact.php:618
msgid "" msgid ""
"Replies/likes to your public posts <strong>may</strong> still be visible" "Replies/likes to your public posts <strong>may</strong> still be visible"
msgstr "" msgstr ""
#: src/Module/Contact.php:617 #: src/Module/Contact.php:619
msgid "Notification for new posts" msgid "Notification for new posts"
msgstr "" msgstr ""
#: src/Module/Contact.php:617 #: src/Module/Contact.php:619
msgid "Send a notification of every new post of this contact" msgid "Send a notification of every new post of this contact"
msgstr "" msgstr ""
#: src/Module/Contact.php:619 #: src/Module/Contact.php:621
msgid "Keyword Deny List" msgid "Keyword Deny List"
msgstr "" msgstr ""
#: src/Module/Contact.php:619 #: src/Module/Contact.php:621
msgid "" msgid ""
"Comma separated list of keywords that should not be converted to hashtags, " "Comma separated list of keywords that should not be converted to hashtags, "
"when \"Fetch information and keywords\" is selected" "when \"Fetch information and keywords\" is selected"
msgstr "" msgstr ""
#: src/Module/Contact.php:637 src/Module/Settings/TwoFactor/Index.php:132 #: src/Module/Contact.php:639 src/Module/Settings/TwoFactor/Index.php:132
msgid "Actions" msgid "Actions"
msgstr "" msgstr ""
#: src/Module/Contact.php:644 #: src/Module/Contact.php:646
msgid "Mirror postings from this contact" msgid "Mirror postings from this contact"
msgstr "" msgstr ""
#: src/Module/Contact.php:646 #: src/Module/Contact.php:648
msgid "" msgid ""
"Mark this contact as remote_self, this will cause friendica to repost new " "Mark this contact as remote_self, this will cause friendica to repost new "
"entries from this contact." "entries from this contact."
msgstr "" msgstr ""
#: src/Module/Contact.php:778 #: src/Module/Contact.php:780
msgid "Show all contacts" msgid "Show all contacts"
msgstr "" msgstr ""
#: src/Module/Contact.php:786 #: src/Module/Contact.php:788
msgid "Only show pending contacts" msgid "Only show pending contacts"
msgstr "" msgstr ""
#: src/Module/Contact.php:794 #: src/Module/Contact.php:796
msgid "Only show blocked contacts" msgid "Only show blocked contacts"
msgstr "" msgstr ""
#: src/Module/Contact.php:799 src/Module/Contact.php:846 #: src/Module/Contact.php:801 src/Module/Contact.php:848
#: src/Object/Post.php:309 #: src/Object/Post.php:309
msgid "Ignored" msgid "Ignored"
msgstr "" msgstr ""
#: src/Module/Contact.php:802 #: src/Module/Contact.php:804
msgid "Only show ignored contacts" msgid "Only show ignored contacts"
msgstr "" msgstr ""
#: src/Module/Contact.php:807 src/Module/Contact.php:847 #: src/Module/Contact.php:809 src/Module/Contact.php:849
msgid "Archived" msgid "Archived"
msgstr "" msgstr ""
#: src/Module/Contact.php:810 #: src/Module/Contact.php:812
msgid "Only show archived contacts" msgid "Only show archived contacts"
msgstr "" msgstr ""
#: src/Module/Contact.php:815 src/Module/Contact.php:845 #: src/Module/Contact.php:817 src/Module/Contact.php:847
msgid "Hidden" msgid "Hidden"
msgstr "" msgstr ""
#: src/Module/Contact.php:818 #: src/Module/Contact.php:820
msgid "Only show hidden contacts" msgid "Only show hidden contacts"
msgstr "" msgstr ""
#: src/Module/Contact.php:826 #: src/Module/Contact.php:828
msgid "Organize your contact groups" msgid "Organize your contact groups"
msgstr "" msgstr ""
#: src/Module/Contact.php:858 #: src/Module/Contact.php:860
msgid "Search your contacts" msgid "Search your contacts"
msgstr "" msgstr ""
#: src/Module/Contact.php:859 src/Module/Search/Index.php:194 #: src/Module/Contact.php:861 src/Module/Search/Index.php:194
#, php-format #, php-format
msgid "Results for: %s" msgid "Results for: %s"
msgstr "" msgstr ""
#: src/Module/Contact.php:867 #: src/Module/Contact.php:869
msgid "Update" msgid "Update"
msgstr "" msgstr ""
#: src/Module/Contact.php:872 #: src/Module/Contact.php:874
msgid "Batch Actions" msgid "Batch Actions"
msgstr "" msgstr ""
#: src/Module/Contact.php:907 #: src/Module/Contact.php:909
msgid "Conversations started by this contact" msgid "Conversations started by this contact"
msgstr "" msgstr ""
#: src/Module/Contact.php:912 #: src/Module/Contact.php:914
msgid "Posts and Comments" msgid "Posts and Comments"
msgstr "" msgstr ""
#: src/Module/Contact.php:923 #: src/Module/Contact.php:925
msgid "Posts containing media objects" msgid "Posts containing media objects"
msgstr "" msgstr ""
#: src/Module/Contact.php:938 #: src/Module/Contact.php:940
msgid "View all known contacts" msgid "View all known contacts"
msgstr "" msgstr ""
#: src/Module/Contact.php:948 #: src/Module/Contact.php:950
msgid "Advanced Contact Settings" msgid "Advanced Contact Settings"
msgstr "" msgstr ""
#: src/Module/Contact.php:1042 #: src/Module/Contact.php:1044
msgid "Mutual Friendship" msgid "Mutual Friendship"
msgstr "" msgstr ""
#: src/Module/Contact.php:1046 #: src/Module/Contact.php:1048
msgid "is a fan of yours" msgid "is a fan of yours"
msgstr "" msgstr ""
#: src/Module/Contact.php:1050 #: src/Module/Contact.php:1052
msgid "you are a fan of" msgid "you are a fan of"
msgstr "" msgstr ""
#: src/Module/Contact.php:1068 #: src/Module/Contact.php:1070
msgid "Pending outgoing contact request" msgid "Pending outgoing contact request"
msgstr "" msgstr ""
#: src/Module/Contact.php:1070 #: src/Module/Contact.php:1072
msgid "Pending incoming contact request" msgid "Pending incoming contact request"
msgstr "" msgstr ""
#: src/Module/Contact.php:1137 #: src/Module/Contact.php:1139
msgid "Refetch contact data" msgid "Refetch contact data"
msgstr "" msgstr ""
#: src/Module/Contact.php:1148 #: src/Module/Contact.php:1150
msgid "Toggle Blocked status" msgid "Toggle Blocked status"
msgstr "" msgstr ""
#: src/Module/Contact.php:1156 #: src/Module/Contact.php:1158
msgid "Toggle Ignored status" msgid "Toggle Ignored status"
msgstr "" msgstr ""
#: src/Module/Contact.php:1165 #: src/Module/Contact.php:1166 src/Module/Contact/Revoke.php:96
msgid "Revoke Follow"
msgstr ""
#: src/Module/Contact.php:1168
msgid "Revoke the follow from this contact"
msgstr ""
#: src/Module/Contact.php:1177
msgid "Delete contact" msgid "Delete contact"
msgstr "" msgstr ""
@ -7797,6 +7807,39 @@ msgstr ""
msgid "Make this post private" msgid "Make this post private"
msgstr "" msgstr ""
#: src/Module/Contact/Revoke.php:48
msgid "Unknown contact."
msgstr ""
#: src/Module/Contact/Revoke.php:58 src/Module/Group.php:109
msgid "Contact is deleted."
msgstr ""
#: src/Module/Contact/Revoke.php:62
msgid "Contact is being deleted."
msgstr ""
#: src/Module/Contact/Revoke.php:76
msgid "Follow was successfully revoked."
msgstr ""
#: src/Module/Contact/Revoke.php:78
msgid ""
"Follow was successfully revoked, however the remote contact won't be aware "
"of this revokation."
msgstr ""
#: src/Module/Contact/Revoke.php:80
msgid ""
"Unable to revoke follow, please try again later or contact the administrator."
msgstr ""
#: src/Module/Contact/Revoke.php:97
msgid ""
"Do you really want to revoke this contact's follow? This cannot be undone "
"and they will have to manually follow you back again."
msgstr ""
#: src/Module/Conversation/Community.php:68 #: src/Module/Conversation/Community.php:68
msgid "Local Community" msgid "Local Community"
msgstr "" msgstr ""
@ -8277,10 +8320,6 @@ msgstr ""
msgid "Unknown group." msgid "Unknown group."
msgstr "" msgstr ""
#: src/Module/Group.php:109
msgid "Contact is deleted."
msgstr ""
#: src/Module/Group.php:115 #: src/Module/Group.php:115
msgid "Unable to add the contact to the group." msgid "Unable to add the contact to the group."
msgstr "" msgstr ""
@ -10438,7 +10477,7 @@ msgstr ""
msgid "Show fewer" msgid "Show fewer"
msgstr "" msgstr ""
#: src/Protocol/Diaspora.php:3448 #: src/Protocol/Diaspora.php:3417
msgid "Attachments:" msgid "Attachments:"
msgstr "" msgstr ""

View file

@ -2,10 +2,10 @@
<center> <center>
<form action="{{$confirm_url}}" id="confirm-form" method="{{$method}}"> <form action="{{$confirm_url}}" id="confirm-form" method="{{$method}}">
<h3 id="confirm-message">{{$message}}</h3> <h3 id="confirm-message">{{$l10n.message}}</h3>
<button class="confirm-button" id="confirm-submit-button" type="submit" name="{{$confirm_name}}" value="{{$confirm_value}}">{{$confirm}}</button> <button class="confirm-button" id="confirm-submit-button" type="submit" name="{{$confirm_name}}" value="{{$confirm_value}}">{{$l10n.confirm}}</button>
<button class="confirm-button" id="confirm-cancel-button" type="submit" name="canceled" value="{{$cancel}}">{{$cancel}}</button> <button class="confirm-button" id="confirm-cancel-button" type="submit" name="canceled" value="{{$l10n.cancel}}">{{$l10n.cancel}}</button>
</form> </form>
</center> </center>

View file

@ -1,8 +1,8 @@
<h1>{{$header}}</h1> <h1>{{$l10n.header}}</h1>
{{include file="contact_template.tpl" no_contacts_checkbox=True}} {{include file="contact_template.tpl" no_contacts_checkbox=True}}
{{include file="confirm.tpl"}} {{include file="confirm.tpl"}}
<div class="clear"></div> <div class="clear"></div>

View file

@ -15,13 +15,14 @@
<a class="btn" rel="#contact-actions-menu" href="#" id="contact-edit-actions-button">{{$contact_action_button}}</a> <a class="btn" rel="#contact-actions-menu" href="#" id="contact-edit-actions-button">{{$contact_action_button}}</a>
<ul role="menu" aria-haspopup="true" id="contact-actions-menu" class="menu-popup"> <ul role="menu" aria-haspopup="true" id="contact-actions-menu" class="menu-popup">
{{if $lblsuggest}}<li role="menuitem"><a href="#" title="{{$contact_actions.suggest.title}}" onclick="window.location.href='{{$contact_actions.suggest.url}}'; return false;">{{$contact_actions.suggest.label}}</a></li>{{/if}} {{if $lblsuggest}}<li role="menuitem"><a href="#" title="{{$contact_actions.suggest.title}}" onclick="window.location.href='{{$contact_actions.suggest.url}}'; return false;">{{$contact_actions.suggest.label}}</a></li>{{/if}}
{{if $poll_enabled}}<li role="menuitem"><a href="#" title="{{$contact_actions.update.title}}" onclick="window.location.href='{{$contact_actions.update.url}}'; return false;">{{$contact_actions.update.label}}</a></li>{{/if}} {{if $poll_enabled}}<li role="menuitem"><a href="#" title="{{$contact_actions.update.title}}" onclick="window.location.href='{{$contact_actions.update.url}}'; return false;">{{$contact_actions.update.label}}</a></li>{{/if}}
{{if $contact_actions.updateprofile}}<li role="menuitem"><a href="{{$contact_actions.updateprofile.url}}" title="{{$contact_actions.updateprofile.title}}">{{$contact_actions.updateprofile.label}}</a></li>{{/if}} {{if $contact_actions.updateprofile}}<li role="menuitem"><a href="{{$contact_actions.updateprofile.url}}" title="{{$contact_actions.updateprofile.title}}">{{$contact_actions.updateprofile.label}}</a></li>{{/if}}
<li class="divider"></li> <li class="divider"></li>
<li role="menuitem"><a href="#" title="{{$contact_actions.block.title}}" onclick="window.location.href='{{$contact_actions.block.url}}'; return false;">{{$contact_actions.block.label}}</a></li> <li role="menuitem"><a href="#" title="{{$contact_actions.block.title}}" onclick="window.location.href='{{$contact_actions.block.url}}'; return false;">{{$contact_actions.block.label}}</a></li>
<li role="menuitem"><a href="#" title="{{$contact_actions.ignore.title}}" onclick="window.location.href='{{$contact_actions.ignore.url}}'; return false;">{{$contact_actions.ignore.label}}</a></li> <li role="menuitem"><a href="#" title="{{$contact_actions.ignore.title}}" onclick="window.location.href='{{$contact_actions.ignore.url}}'; return false;">{{$contact_actions.ignore.label}}</a></li>
{{if $contact_actions.delete.url}}<li role="menuitem"><a href="{{$contact_actions.delete.url}}" title="{{$contact_actions.delete.title}}" onclick="return confirmDelete();">{{$contact_actions.delete.label}}</a></li> {{/if}} {{if $contact_actions.revoke_follow.url}}<li role="menuitem"><a href="{{$contact_actions.revoke_follow.url}}" title="{{$contact_actions.revoke_follow.title}}">{{$contact_actions.revoke_follow.label}}</a></li>{{/if}}
{{if $contact_actions.delete.url}}<li role="menuitem"><a href="{{$contact_actions.delete.url}}" title="{{$contact_actions.delete.title}}" onclick="return confirmDelete();">{{$contact_actions.delete.label}}</a></li> {{/if}}
</ul> </ul>
</div> </div>

View file

@ -1,9 +1,9 @@
<form action="{{$confirm_url}}" id="confirm-form" method="{{$method}}" class="generic-page-wrapper"> <form action="{{$confirm_url}}" id="confirm-form" method="{{$method}}" class="generic-page-wrapper">
<div id="confirm-message">{{$message}}</div> <div id="confirm-message">{{$l10n.message}}</div>
<div class="form-group pull-right settings-submit-wrapper"> <div class="form-group pull-right settings-submit-wrapper">
<button type="submit" name="{{$confirm_name}}" id="confirm-submit-button" class="btn btn-primary confirm-button" value="{{$confirm_value}}">{{$confirm}}</button> <button type="submit" name="{{$confirm_name}}" id="confirm-submit-button" class="btn btn-primary confirm-button" value="{{$confirm_value}}">{{$l10n.confirm}}</button>
<button type="submit" name="canceled" value="{{$cancel}} id="confirm-cancel-button" class="btn confirm-button" data-dismiss="modal">{{$cancel}}</button> <button type="submit" name="canceled" value="{{$l10n.cancel}}" id="confirm-cancel-button" class="btn confirm-button" data-dismiss="modal">{{$l10n.cancel}}</button>
</div> </div>
</form> </form>

View file

@ -1,9 +1,9 @@
<div id="contact-drop-confirm"> <div id="contact-drop-confirm">
<h2 class="heading">{{$header}}</h2> <h2 class="heading">{{$l10n.header}}</h2>
{{include file="contact_template.tpl" no_contacts_checkbox=True}} {{include file="contact_template.tpl" no_contacts_checkbox=True}}
{{include file="confirm.tpl"}} {{include file="confirm.tpl"}}
<div class="clear"></div> <div class="clear"></div>
</div> </div>

View file

@ -27,6 +27,7 @@
{{/if}} {{/if}}
<li role="presentation"><a role="menuitem" href="{{$contact_actions.block.url}}" title="{{$contact_actions.block.title}}">{{$contact_actions.block.label}}</a></li> <li role="presentation"><a role="menuitem" href="{{$contact_actions.block.url}}" title="{{$contact_actions.block.title}}">{{$contact_actions.block.label}}</a></li>
<li role="presentation"><a role="menuitem" href="{{$contact_actions.ignore.url}}" title="{{$contact_actions.ignore.title}}">{{$contact_actions.ignore.label}}</a></li> <li role="presentation"><a role="menuitem" href="{{$contact_actions.ignore.url}}" title="{{$contact_actions.ignore.title}}">{{$contact_actions.ignore.label}}</a></li>
{{if $contact_actions.revoke_follow.url}}<li role="presentation"><button role="menuitem" type="button" class="btn-link" title="{{$contact_actions.revoke_follow.title}}" onclick="addToModal('{{$contact_actions.revoke_follow.url}}');">{{$contact_actions.revoke_follow.label}}</button></li>{{/if}}
{{if $contact_actions.delete.url}}<li role="presentation"><button role="menuitem" type="button" class="btn-link" title="{{$contact_actions.delete.title}}" onclick="addToModal('{{$contact_actions.delete.url}}&confirm=1');">{{$contact_actions.delete.label}}</button></li>{{/if}} {{if $contact_actions.delete.url}}<li role="presentation"><button role="menuitem" type="button" class="btn-link" title="{{$contact_actions.delete.title}}" onclick="addToModal('{{$contact_actions.delete.url}}&confirm=1');">{{$contact_actions.delete.label}}</button></li>{{/if}}
</ul> </ul>
</li> </li>

View file

@ -16,13 +16,14 @@
<a class="btn" id="contact-edit-actions-button">{{$contact_action_button}}</a> <a class="btn" id="contact-edit-actions-button">{{$contact_action_button}}</a>
<ul role="menu" aria-haspopup="true" id="contact-actions-menu" class="menu-popup"> <ul role="menu" aria-haspopup="true" id="contact-actions-menu" class="menu-popup">
{{if $lblsuggest}}<li role="menuitem"><a href="#" title="{{$contact_actions.suggest.title}}" onclick="window.location.href='{{$contact_actions.suggest.url}}'; return false;">{{$contact_actions.suggest.label}}</a></li>{{/if}} {{if $lblsuggest}}<li role="menuitem"><a href="#" title="{{$contact_actions.suggest.title}}" onclick="window.location.href='{{$contact_actions.suggest.url}}'; return false;">{{$contact_actions.suggest.label}}</a></li>{{/if}}
{{if $poll_enabled}}<li role="menuitem"><a href="#" title="{{$contact_actions.update.title}}" onclick="window.location.href='{{$contact_actions.update.url}}'; return false;">{{$contact_actions.update.label}}</a></li>{{/if}} {{if $poll_enabled}}<li role="menuitem"><a href="#" title="{{$contact_actions.update.title}}" onclick="window.location.href='{{$contact_actions.update.url}}'; return false;">{{$contact_actions.update.label}}</a></li>{{/if}}
{{if $contact_actions.updateprofile}}<li role="menuitem"><a href="{{$contact_actions.updateprofile.url}}" title="{{$contact_actions.updateprofile.title}}">{{$contact_actions.updateprofile.label}}</a></li>{{/if}} {{if $contact_actions.updateprofile}}<li role="menuitem"><a href="{{$contact_actions.updateprofile.url}}" title="{{$contact_actions.updateprofile.title}}">{{$contact_actions.updateprofile.label}}</a></li>{{/if}}
<li class="divider"></li> <li class="divider"></li>
<li role="menuitem"><a href="#" title="{{$contact_actions.block.title}}" onclick="window.location.href='{{$contact_actions.block.url}}'; return false;">{{$contact_actions.block.label}}</a></li> <li role="menuitem"><a href="#" title="{{$contact_actions.block.title}}" onclick="window.location.href='{{$contact_actions.block.url}}'; return false;">{{$contact_actions.block.label}}</a></li>
<li role="menuitem"><a href="#" title="{{$contact_actions.ignore.title}}" onclick="window.location.href='{{$contact_actions.ignore.url}}'; return false;">{{$contact_actions.ignore.label}}</a></li> <li role="menuitem"><a href="#" title="{{$contact_actions.ignore.title}}" onclick="window.location.href='{{$contact_actions.ignore.url}}'; return false;">{{$contact_actions.ignore.label}}</a></li>
{{if $contact_actions.delete.url}}<li role="menuitem"><a href="{{$contact_actions.delete.url}}" title="{{$contact_actions.delete.title}}" onclick="return confirmDelete();">{{$contact_actions.delete.label}}</a></li>{{/if}} {{if $contact_actions.revoke_follow.url}}<li role="menuitem"><a href="{{$contact_actions.revoke_follow.url}}" title="{{$contact_actions.revoke_follow.title}}">{{$contact_actions.revoke_follow.label}}</a></li>{{/if}}
{{if $contact_actions.delete.url}}<li role="menuitem"><a href="{{$contact_actions.delete.url}}" title="{{$contact_actions.delete.title}}" onclick="return confirmDelete();">{{$contact_actions.delete.label}}</a></li>{{/if}}
</ul> </ul>
</div> </div>