Merge branch 'friendica:2022.12-rc' into new_image_presentation
This commit is contained in:
commit
c7811576cc
24 changed files with 167 additions and 72 deletions
|
@ -631,10 +631,10 @@ class App
|
||||||
|
|
||||||
// ZRL
|
// ZRL
|
||||||
if (!empty($_GET['zrl']) && $this->mode->isNormal() && !$this->mode->isBackend() && !$this->session->getLocalUserId()) {
|
if (!empty($_GET['zrl']) && $this->mode->isNormal() && !$this->mode->isBackend() && !$this->session->getLocalUserId()) {
|
||||||
// Only continue when the given profile link seems valid
|
// Only continue when the given profile link seems valid.
|
||||||
// Valid profile links contain a path with "/profile/" and no query parameters
|
// Valid profile links contain a path with "/profile/" and no query parameters
|
||||||
if ((parse_url($_GET['zrl'], PHP_URL_QUERY) == '') &&
|
if ((parse_url($_GET['zrl'], PHP_URL_QUERY) == '') &&
|
||||||
strstr(parse_url($_GET['zrl'], PHP_URL_PATH), '/profile/')) {
|
strpos(parse_url($_GET['zrl'], PHP_URL_PATH) ?? '', '/profile/') !== false) {
|
||||||
if ($this->session->get('visitor_home') != $_GET['zrl']) {
|
if ($this->session->get('visitor_home') != $_GET['zrl']) {
|
||||||
$this->session->set('my_url', $_GET['zrl']);
|
$this->session->set('my_url', $_GET['zrl']);
|
||||||
$this->session->set('authenticated', 0);
|
$this->session->set('authenticated', 0);
|
||||||
|
|
|
@ -125,7 +125,7 @@ class Avatar
|
||||||
|
|
||||||
private static function getFilename(string $url): string
|
private static function getFilename(string $url): string
|
||||||
{
|
{
|
||||||
$guid = Item::guidFromUri($url, parse_url($url, PHP_URL_HOST));
|
$guid = Item::guidFromUri($url);
|
||||||
|
|
||||||
return substr($guid, 0, 2) . '/' . substr($guid, 3, 2) . '/' . substr($guid, 5, 3) . '/' .
|
return substr($guid, 0, 2) . '/' . substr($guid, 3, 2) . '/' . substr($guid, 5, 3) . '/' .
|
||||||
substr($guid, 9, 2) .'/' . substr($guid, 11, 2) . '/' . substr($guid, 13, 4). '/' . substr($guid, 18) . '-';
|
substr($guid, 9, 2) .'/' . substr($guid, 11, 2) . '/' . substr($guid, 13, 4). '/' . substr($guid, 18) . '-';
|
||||||
|
|
|
@ -273,8 +273,8 @@ class BBCode
|
||||||
// Get all linked images with alternative image description
|
// Get all linked images with alternative image description
|
||||||
if (preg_match_all("/\[img=(http[^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
|
if (preg_match_all("/\[img=(http[^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
|
||||||
foreach ($pictures as $picture) {
|
foreach ($pictures as $picture) {
|
||||||
if (Photo::isLocal($picture[1])) {
|
if ($id = Photo::getIdForName($picture[1])) {
|
||||||
$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => $picture[2]];
|
$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => $picture[2], 'id' => $id];
|
||||||
} else {
|
} else {
|
||||||
$post['remote_images'][] = ['url' => $picture[1], 'description' => $picture[2]];
|
$post['remote_images'][] = ['url' => $picture[1], 'description' => $picture[2]];
|
||||||
}
|
}
|
||||||
|
@ -286,8 +286,8 @@ class BBCode
|
||||||
|
|
||||||
if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
|
if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
|
||||||
foreach ($pictures as $picture) {
|
foreach ($pictures as $picture) {
|
||||||
if (Photo::isLocal($picture[1])) {
|
if ($id = Photo::getIdForName($picture[1])) {
|
||||||
$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => ''];
|
$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => '', 'id' => $id];
|
||||||
} else {
|
} else {
|
||||||
$post['remote_images'][] = ['url' => $picture[1], 'description' => ''];
|
$post['remote_images'][] = ['url' => $picture[1], 'description' => ''];
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,14 +291,11 @@ class APContact
|
||||||
return $fetched_contact;
|
return $fetched_contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
$parts = parse_url($apcontact['url']);
|
|
||||||
unset($parts['scheme']);
|
|
||||||
unset($parts['path']);
|
|
||||||
|
|
||||||
if (empty($apcontact['addr'])) {
|
if (empty($apcontact['addr'])) {
|
||||||
if (!empty($apcontact['nick']) && is_array($parts)) {
|
try {
|
||||||
$apcontact['addr'] = $apcontact['nick'] . '@' . str_replace('//', '', Network::unparseURL($parts));
|
$apcontact['addr'] = $apcontact['nick'] . '@' . (new Uri($apcontact['url']))->getAuthority();
|
||||||
} else {
|
} catch (\Throwable $e) {
|
||||||
|
Logger::warning('Unable to coerce APContact URL into a UriInterface object', ['url' => $apcontact['url'], 'error' => $e->getMessage()]);
|
||||||
$apcontact['addr'] = '';
|
$apcontact['addr'] = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1395,7 +1395,17 @@ class Contact
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($data['network'] == Protocol::DIASPORA) {
|
if ($data['network'] == Protocol::DIASPORA) {
|
||||||
|
try {
|
||||||
DI::dsprContact()->updateFromProbeArray($data);
|
DI::dsprContact()->updateFromProbeArray($data);
|
||||||
|
} catch (\InvalidArgumentException $e) {
|
||||||
|
Logger::error($e->getMessage(), ['url' => $url, 'data' => $data]);
|
||||||
|
}
|
||||||
|
} elseif (!empty($data['networks'][Protocol::DIASPORA])) {
|
||||||
|
try {
|
||||||
|
DI::dsprContact()->updateFromProbeArray($data['networks'][Protocol::DIASPORA]);
|
||||||
|
} catch (\InvalidArgumentException $e) {
|
||||||
|
Logger::error($e->getMessage(), ['url' => $url, 'data' => $data['networks'][Protocol::DIASPORA]]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self::updateFromProbeArray($contact_id, $data);
|
self::updateFromProbeArray($contact_id, $data);
|
||||||
|
@ -2483,13 +2493,23 @@ class Contact
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ret = Probe::uri($contact['url'], $network, $contact['uid']);
|
$data = Probe::uri($contact['url'], $network, $contact['uid']);
|
||||||
|
|
||||||
if ($ret['network'] == Protocol::DIASPORA) {
|
if ($data['network'] == Protocol::DIASPORA) {
|
||||||
DI::dsprContact()->updateFromProbeArray($ret);
|
try {
|
||||||
|
DI::dsprContact()->updateFromProbeArray($data);
|
||||||
|
} catch (\InvalidArgumentException $e) {
|
||||||
|
Logger::error($e->getMessage(), ['id' => $id, 'network' => $network, 'contact' => $contact, 'data' => $data]);
|
||||||
|
}
|
||||||
|
} elseif (!empty($data['networks'][Protocol::DIASPORA])) {
|
||||||
|
try {
|
||||||
|
DI::dsprContact()->updateFromProbeArray($data['networks'][Protocol::DIASPORA]);
|
||||||
|
} catch (\InvalidArgumentException $e) {
|
||||||
|
Logger::error($e->getMessage(), ['id' => $id, 'network' => $network, 'contact' => $contact, 'data' => $data]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::updateFromProbeArray($id, $ret);
|
return self::updateFromProbeArray($id, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2671,7 +2691,7 @@ class Contact
|
||||||
}
|
}
|
||||||
|
|
||||||
$update = false;
|
$update = false;
|
||||||
$guid = ($ret['guid'] ?? '') ?: Item::guidFromUri($ret['url'], parse_url($ret['url'], PHP_URL_HOST));
|
$guid = ($ret['guid'] ?? '') ?: Item::guidFromUri($ret['url']);
|
||||||
|
|
||||||
// make sure to not overwrite existing values with blank entries except some technical fields
|
// make sure to not overwrite existing values with blank entries except some technical fields
|
||||||
$keep = ['batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'baseurl'];
|
$keep = ['batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'baseurl'];
|
||||||
|
@ -3189,9 +3209,10 @@ class Contact
|
||||||
self::clearFollowerFollowingEndpointCache($contact['uid']);
|
self::clearFollowerFollowingEndpointCache($contact['uid']);
|
||||||
|
|
||||||
$cdata = self::getPublicAndUserContactID($contact['id'], $contact['uid']);
|
$cdata = self::getPublicAndUserContactID($contact['id'], $contact['uid']);
|
||||||
|
if (!empty($cdata['public'])) {
|
||||||
DI::notification()->deleteForUserByVerb($contact['uid'], Activity::FOLLOW, ['actor-id' => $cdata['public']]);
|
DI::notification()->deleteForUserByVerb($contact['uid'], Activity::FOLLOW, ['actor-id' => $cdata['public']]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the local relationship when a local user unfollow a contact.
|
* Update the local relationship when a local user unfollow a contact.
|
||||||
|
|
|
@ -2039,6 +2039,7 @@ class Item
|
||||||
* @param string $uri uri of an item entry
|
* @param string $uri uri of an item entry
|
||||||
* @param string|null $host hostname for the GUID prefix
|
* @param string|null $host hostname for the GUID prefix
|
||||||
* @return string Unique guid
|
* @return string Unique guid
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function guidFromUri(string $uri, string $host = null): string
|
public static function guidFromUri(string $uri, string $host = null): string
|
||||||
{
|
{
|
||||||
|
@ -2049,11 +2050,16 @@ class Item
|
||||||
// Remove the scheme to make sure that "https" and "http" doesn't make a difference
|
// Remove the scheme to make sure that "https" and "http" doesn't make a difference
|
||||||
unset($parsed['scheme']);
|
unset($parsed['scheme']);
|
||||||
|
|
||||||
|
$hostPart = $host ?? $parsed['host'] ?? '';
|
||||||
|
if (!$hostPart) {
|
||||||
|
Logger::warning('Empty host GUID part', ['uri' => $uri, 'host' => $host, 'parsed' => $parsed, 'callstack' => System::callstack(10)]);
|
||||||
|
}
|
||||||
|
|
||||||
// Glue it together to be able to make a hash from it
|
// Glue it together to be able to make a hash from it
|
||||||
$host_id = implode('/', $parsed);
|
$host_id = implode('/', $parsed);
|
||||||
|
|
||||||
// Use a mixture of several hashes to provide some GUID like experience
|
// Use a mixture of several hashes to provide some GUID like experience
|
||||||
return hash('crc32', $host) . '-'. hash('joaat', $host_id) . '-'. hash('fnv164', $host_id);
|
return hash('crc32', $hostPart) . '-' . hash('joaat', $host_id) . '-' . hash('fnv164', $host_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -59,8 +59,7 @@ class Mail
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($msg['guid'])) {
|
if (empty($msg['guid'])) {
|
||||||
$host = parse_url($msg['from-url'], PHP_URL_HOST);
|
$msg['guid'] = Item::guidFromUri($msg['uri'], parse_url($msg['from-url'], PHP_URL_HOST));
|
||||||
$msg['guid'] = Item::guidFromUri($msg['uri'], $host);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$msg['created'] = (!empty($msg['created']) ? DateTimeFormat::utc($msg['created']) : DateTimeFormat::utcNow());
|
$msg['created'] = (!empty($msg['created']) ? DateTimeFormat::utc($msg['created']) : DateTimeFormat::utcNow());
|
||||||
|
|
|
@ -70,18 +70,8 @@ class Notify extends BaseModule
|
||||||
throw new \Friendica\Network\HTTPException\InternalServerErrorException();
|
throw new \Friendica\Network\HTTPException\InternalServerErrorException();
|
||||||
}
|
}
|
||||||
$this->dispatchPrivate($user, $postdata);
|
$this->dispatchPrivate($user, $postdata);
|
||||||
} elseif (!$this->dispatchPublic($postdata)) {
|
} else {
|
||||||
(new Salmon(
|
$this->dispatchPublic($postdata);
|
||||||
$this->database,
|
|
||||||
$this->l10n,
|
|
||||||
$this->baseUrl,
|
|
||||||
$this->args,
|
|
||||||
$this->logger,
|
|
||||||
$this->profiler,
|
|
||||||
$this->response,
|
|
||||||
$this->server,
|
|
||||||
$this->parameters
|
|
||||||
))->rawContent($request);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ class NoScrape extends BaseModule
|
||||||
|
|
||||||
// We display the last activity (post or login), reduced to year and week number
|
// We display the last activity (post or login), reduced to year and week number
|
||||||
$last_active = strtotime($owner['last-item']);
|
$last_active = strtotime($owner['last-item']);
|
||||||
if ($last_active < strtotime($owner['last-activity'])) {
|
if ($owner['last-activity'] && $last_active < strtotime($owner['last-activity'])) {
|
||||||
$last_active = strtotime($owner['last-activity']);
|
$last_active = strtotime($owner['last-activity']);
|
||||||
}
|
}
|
||||||
$json_info['last-activity'] = date('o-W', $last_active);
|
$json_info['last-activity'] = date('o-W', $last_active);
|
||||||
|
|
|
@ -48,6 +48,7 @@ use Friendica\Navigation\Notifications\Factory;
|
||||||
use Friendica\Navigation\Notifications\Repository;
|
use Friendica\Navigation\Notifications\Repository;
|
||||||
use Friendica\Navigation\Notifications\ValueObject;
|
use Friendica\Navigation\Notifications\ValueObject;
|
||||||
use Friendica\Navigation\SystemMessages;
|
use Friendica\Navigation\SystemMessages;
|
||||||
|
use Friendica\Network\HTTPException;
|
||||||
use Friendica\Protocol\Activity;
|
use Friendica\Protocol\Activity;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Friendica\Util\Profiler;
|
use Friendica\Util\Profiler;
|
||||||
|
@ -229,7 +230,11 @@ class Ping extends BaseModule
|
||||||
|
|
||||||
// merge all notification types in one array
|
// merge all notification types in one array
|
||||||
foreach ($intros as $intro) {
|
foreach ($intros as $intro) {
|
||||||
|
try {
|
||||||
$navNotifications[] = $this->formattedNavNotification->createFromIntro($intro);
|
$navNotifications[] = $this->formattedNavNotification->createFromIntro($intro);
|
||||||
|
} catch (HTTPException\NotFoundException $e) {
|
||||||
|
$this->introductionRepo->delete($intro);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($registrations) <= 1 || $this->pconfig->get($this->session->getLocalUserId(), 'system', 'detailed_notif')) {
|
if (count($registrations) <= 1 || $this->pconfig->get($this->session->getLocalUserId(), 'system', 'detailed_notif')) {
|
||||||
|
@ -242,7 +247,7 @@ class Ping extends BaseModule
|
||||||
new Uri($this->baseUrl->get(true) . '/moderation/users/pending')
|
new Uri($this->baseUrl->get(true) . '/moderation/users/pending')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} elseif (count($registrations) > 1) {
|
} else {
|
||||||
$navNotifications[] = $this->formattedNavNotification->createFromParams(
|
$navNotifications[] = $this->formattedNavNotification->createFromParams(
|
||||||
$registrations[0]['name'],
|
$registrations[0]['name'],
|
||||||
$registrations[0]['url'],
|
$registrations[0]['url'],
|
||||||
|
|
|
@ -66,11 +66,12 @@ class Salmon extends \Friendica\BaseModule
|
||||||
{
|
{
|
||||||
$xml = Network::postdata();
|
$xml = Network::postdata();
|
||||||
|
|
||||||
$this->logger->debug('New Salmon', ['nickname' => $this->parameters['nickname'], 'xml' => $xml]);
|
|
||||||
|
|
||||||
// Despite having a route with a mandatory nickname parameter, this method can also be called from
|
|
||||||
// \Friendica\Module\DFRN\Notify->post where the same parameter is optional 🤷
|
|
||||||
$nickname = $this->parameters['nickname'] ?? '';
|
$nickname = $this->parameters['nickname'] ?? '';
|
||||||
|
if (empty($nickname)) {
|
||||||
|
throw new HTTPException\BadRequestException('nickname parameter is mandatory');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->debug('New Salmon', ['nickname' => $nickname, 'xml' => $xml]);
|
||||||
|
|
||||||
$importer = $this->database->selectFirst('user', [], ['nickname' => $nickname, 'account_expired' => false, 'account_removed' => false]);
|
$importer = $this->database->selectFirst('user', [], ['nickname' => $nickname, 'account_expired' => false, 'account_removed' => false]);
|
||||||
if (!$this->database->isResult($importer)) {
|
if (!$this->database->isResult($importer)) {
|
||||||
|
|
|
@ -77,7 +77,7 @@ class Tos extends BaseModule
|
||||||
*/
|
*/
|
||||||
protected function content(array $request = []): string
|
protected function content(array $request = []): string
|
||||||
{
|
{
|
||||||
if (strlen($this->config->get('system', 'singleuser'))) {
|
if ($this->config->get('system', 'singleuser')) {
|
||||||
$this->baseUrl->redirect('profile/' . $this->config->get('system', 'singleuser'));
|
$this->baseUrl->redirect('profile/' . $this->config->get('system', 'singleuser'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ use Friendica\Model\Contact;
|
||||||
use Friendica\Navigation\Notifications\Entity;
|
use Friendica\Navigation\Notifications\Entity;
|
||||||
use Friendica\Navigation\Notifications\Exception\NoMessageException;
|
use Friendica\Navigation\Notifications\Exception\NoMessageException;
|
||||||
use Friendica\Navigation\Notifications\ValueObject;
|
use Friendica\Navigation\Notifications\ValueObject;
|
||||||
use Friendica\Network\HTTPException\ServiceUnavailableException;
|
use Friendica\Network\HTTPException;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Friendica\Util\Proxy;
|
use Friendica\Util\Proxy;
|
||||||
use Friendica\Util\Temporal;
|
use Friendica\Util\Temporal;
|
||||||
|
@ -73,7 +73,7 @@ class FormattedNavNotification extends BaseFactory
|
||||||
* @param Uri $href
|
* @param Uri $href
|
||||||
* @param bool $seen
|
* @param bool $seen
|
||||||
* @return ValueObject\FormattedNavNotification
|
* @return ValueObject\FormattedNavNotification
|
||||||
* @throws ServiceUnavailableException
|
* @throws HTTPException\ServiceUnavailableException
|
||||||
*/
|
*/
|
||||||
public function createFromParams(string $contact_name, string $contact_url, string $message, \DateTime $date, Uri $href, bool $seen = false): ValueObject\FormattedNavNotification
|
public function createFromParams(string $contact_name, string $contact_url, string $message, \DateTime $date, Uri $href, bool $seen = false): ValueObject\FormattedNavNotification
|
||||||
{
|
{
|
||||||
|
@ -115,9 +115,9 @@ class FormattedNavNotification extends BaseFactory
|
||||||
* @param Entity\Notification $notification
|
* @param Entity\Notification $notification
|
||||||
* @return ValueObject\FormattedNavNotification
|
* @return ValueObject\FormattedNavNotification
|
||||||
* @throws NoMessageException
|
* @throws NoMessageException
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws HTTPException\InternalServerErrorException
|
||||||
* @throws \Friendica\Network\HTTPException\NotFoundException
|
* @throws HTTPException\NotFoundException
|
||||||
* @throws \Friendica\Network\HTTPException\ServiceUnavailableException
|
* @throws HTTPException\ServiceUnavailableException
|
||||||
*/
|
*/
|
||||||
public function createFromNotification(Entity\Notification $notification): ValueObject\FormattedNavNotification
|
public function createFromNotification(Entity\Notification $notification): ValueObject\FormattedNavNotification
|
||||||
{
|
{
|
||||||
|
@ -141,10 +141,20 @@ class FormattedNavNotification extends BaseFactory
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Friendica\Contact\Introduction\Entity\Introduction $intro
|
||||||
|
* @return ValueObject\FormattedNavNotification
|
||||||
|
* @throws HTTPException\NotFoundException when the contact record couldn't be located
|
||||||
|
* @throws HTTPException\ServiceUnavailableException
|
||||||
|
*/
|
||||||
public function createFromIntro(\Friendica\Contact\Introduction\Entity\Introduction $intro): ValueObject\FormattedNavNotification
|
public function createFromIntro(\Friendica\Contact\Introduction\Entity\Introduction $intro): ValueObject\FormattedNavNotification
|
||||||
{
|
{
|
||||||
if (!isset(self::$contacts[$intro->cid])) {
|
if (empty(self::$contacts[$intro->cid])) {
|
||||||
self::$contacts[$intro->cid] = Contact::getById($intro->cid, ['name', 'url', 'pending']);
|
if ($contact = Contact::getById($intro->cid, ['name', 'url', 'pending'])) {
|
||||||
|
self::$contacts[$intro->cid] = $contact;
|
||||||
|
} else {
|
||||||
|
throw new HTTPException\NotFoundException('Contact not found with id' . $intro->cid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::$contacts[$intro->cid]['pending']) {
|
if (self::$contacts[$intro->cid]['pending']) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ use Friendica\Network\HTTPClient\Client\HttpClientAccept;
|
||||||
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
|
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
|
||||||
use Friendica\Protocol\ActivityNamespace;
|
use Friendica\Protocol\ActivityNamespace;
|
||||||
use Friendica\Protocol\ActivityPub;
|
use Friendica\Protocol\ActivityPub;
|
||||||
|
use Friendica\Protocol\Diaspora;
|
||||||
use Friendica\Protocol\Email;
|
use Friendica\Protocol\Email;
|
||||||
use Friendica\Protocol\Feed;
|
use Friendica\Protocol\Feed;
|
||||||
use Friendica\Protocol\Salmon;
|
use Friendica\Protocol\Salmon;
|
||||||
|
@ -134,6 +135,17 @@ class Probe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$newdata['networks'] = [];
|
||||||
|
foreach ([Protocol::DIASPORA, Protocol::OSTATUS] as $network) {
|
||||||
|
if (!empty($data['networks'][$network])) {
|
||||||
|
$data['networks'][$network]['subscribe'] = $newdata['subscribe'] ?? '';
|
||||||
|
$data['networks'][$network]['baseurl'] = $newdata['baseurl'] ?? '';
|
||||||
|
$data['networks'][$network]['gsid'] = $newdata['gsid'] ?? 0;
|
||||||
|
$newdata['networks'][$network] = self::rearrangeData($data['networks'][$network]);
|
||||||
|
unset($newdata['networks'][$network]['networks']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We don't use the "priority" field anymore and replace it with a dummy.
|
// We don't use the "priority" field anymore and replace it with a dummy.
|
||||||
$newdata['priority'] = 0;
|
$newdata['priority'] = 0;
|
||||||
|
|
||||||
|
@ -345,7 +357,13 @@ class Probe
|
||||||
$data = [];
|
$data = [];
|
||||||
}
|
}
|
||||||
if (empty($data) || (!empty($ap_profile) && empty($network) && (($data['network'] ?? '') != Protocol::DFRN))) {
|
if (empty($data) || (!empty($ap_profile) && empty($network) && (($data['network'] ?? '') != Protocol::DFRN))) {
|
||||||
|
$networks = $data['networks'] ?? [];
|
||||||
|
unset($data['networks']);
|
||||||
|
if (!empty($data['network'])) {
|
||||||
|
$networks[$data['network']] = $data;
|
||||||
|
}
|
||||||
$data = $ap_profile;
|
$data = $ap_profile;
|
||||||
|
$data['networks'] = $networks;
|
||||||
} elseif (!empty($ap_profile)) {
|
} elseif (!empty($ap_profile)) {
|
||||||
$ap_profile['batch'] = '';
|
$ap_profile['batch'] = '';
|
||||||
$data = array_merge($ap_profile, $data);
|
$data = array_merge($ap_profile, $data);
|
||||||
|
@ -669,7 +687,7 @@ class Probe
|
||||||
}
|
}
|
||||||
|
|
||||||
$parts = parse_url($uri);
|
$parts = parse_url($uri);
|
||||||
if (empty($parts['scheme']) && empty($parts['host']) && !strstr($parts['path'], '@')) {
|
if (empty($parts['scheme']) && empty($parts['host']) && (empty($parts['path']) || strpos($parts['path'], '@') === false)) {
|
||||||
Logger::info('URI was not detectable', ['uri' => $uri]);
|
Logger::info('URI was not detectable', ['uri' => $uri]);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -716,9 +734,13 @@ class Probe
|
||||||
}
|
}
|
||||||
if ((!$result && ($network == '')) || ($network == Protocol::DIASPORA)) {
|
if ((!$result && ($network == '')) || ($network == Protocol::DIASPORA)) {
|
||||||
$result = self::diaspora($webfinger);
|
$result = self::diaspora($webfinger);
|
||||||
|
} else {
|
||||||
|
$result['networks'][Protocol::DIASPORA] = self::diaspora($webfinger);
|
||||||
}
|
}
|
||||||
if ((!$result && ($network == '')) || ($network == Protocol::OSTATUS)) {
|
if ((!$result && ($network == '')) || ($network == Protocol::OSTATUS)) {
|
||||||
$result = self::ostatus($webfinger);
|
$result = self::ostatus($webfinger);
|
||||||
|
} else {
|
||||||
|
$result['networks'][Protocol::OSTATUS] = self::ostatus($webfinger);
|
||||||
}
|
}
|
||||||
if (in_array($network, ['', Protocol::ZOT])) {
|
if (in_array($network, ['', Protocol::ZOT])) {
|
||||||
$result = self::zot($webfinger, $result, $baseurl);
|
$result = self::zot($webfinger, $result, $baseurl);
|
||||||
|
@ -2188,6 +2210,8 @@ class Probe
|
||||||
$owner = User::getOwnerDataById($uid);
|
$owner = User::getOwnerDataById($uid);
|
||||||
$approfile = ActivityPub\Transmitter::getProfile($uid);
|
$approfile = ActivityPub\Transmitter::getProfile($uid);
|
||||||
|
|
||||||
|
$split_name = Diaspora::splitName($owner['name']);
|
||||||
|
|
||||||
if (empty($owner['gsid'])) {
|
if (empty($owner['gsid'])) {
|
||||||
$owner['gsid'] = GServer::getID($approfile['generator']['url']);
|
$owner['gsid'] = GServer::getID($approfile['generator']['url']);
|
||||||
}
|
}
|
||||||
|
@ -2207,7 +2231,28 @@ class Probe
|
||||||
'inbox' => $approfile['inbox'], 'outbox' => $approfile['outbox'],
|
'inbox' => $approfile['inbox'], 'outbox' => $approfile['outbox'],
|
||||||
'sharedinbox' => $approfile['endpoints']['sharedInbox'], 'network' => Protocol::DFRN,
|
'sharedinbox' => $approfile['endpoints']['sharedInbox'], 'network' => Protocol::DFRN,
|
||||||
'pubkey' => $owner['upubkey'], 'baseurl' => $approfile['generator']['url'], 'gsid' => $owner['gsid'],
|
'pubkey' => $owner['upubkey'], 'baseurl' => $approfile['generator']['url'], 'gsid' => $owner['gsid'],
|
||||||
'manually-approve' => in_array($owner['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP])
|
'manually-approve' => in_array($owner['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP]),
|
||||||
|
'networks' => [
|
||||||
|
Protocol::DIASPORA => [
|
||||||
|
'name' => $owner['name'],
|
||||||
|
'given_name' => $split_name['first'],
|
||||||
|
'family_name' => $split_name['last'],
|
||||||
|
'nick' => $owner['nick'],
|
||||||
|
'guid' => $approfile['diaspora:guid'],
|
||||||
|
'url' => $owner['url'],
|
||||||
|
'addr' => $owner['addr'],
|
||||||
|
'alias' => $owner['alias'],
|
||||||
|
'photo' => $owner['photo'],
|
||||||
|
'photo_medium' => $owner['thumb'],
|
||||||
|
'photo_small' => $owner['micro'],
|
||||||
|
'batch' => $approfile['generator']['url'] . '/receive/public',
|
||||||
|
'notify' => $owner['notify'],
|
||||||
|
'poll' => $owner['poll'],
|
||||||
|
'poco' => $owner['poco'],
|
||||||
|
'network' => Protocol::DIASPORA,
|
||||||
|
'pubkey' => $owner['upubkey'],
|
||||||
|
]
|
||||||
|
]
|
||||||
];
|
];
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
// Default values for non existing targets
|
// Default values for non existing targets
|
||||||
|
|
|
@ -804,7 +804,7 @@ class Processor
|
||||||
private static function processContent(array $activity, array $item)
|
private static function processContent(array $activity, array $item)
|
||||||
{
|
{
|
||||||
if (!empty($activity['mediatype']) && ($activity['mediatype'] == 'text/markdown')) {
|
if (!empty($activity['mediatype']) && ($activity['mediatype'] == 'text/markdown')) {
|
||||||
$item['title'] = strip_tags($activity['name']);
|
$item['title'] = strip_tags($activity['name'] ?? '');
|
||||||
$content = Markdown::toBBCode($activity['content']);
|
$content = Markdown::toBBCode($activity['content']);
|
||||||
} elseif (!empty($activity['mediatype']) && ($activity['mediatype'] == 'text/bbcode')) {
|
} elseif (!empty($activity['mediatype']) && ($activity['mediatype'] == 'text/bbcode')) {
|
||||||
$item['title'] = $activity['name'];
|
$item['title'] = $activity['name'];
|
||||||
|
@ -1273,8 +1273,11 @@ class Processor
|
||||||
foreach ($receivers[$element] as $receiver) {
|
foreach ($receivers[$element] as $receiver) {
|
||||||
if ($receiver == ActivityPub::PUBLIC_COLLECTION) {
|
if ($receiver == ActivityPub::PUBLIC_COLLECTION) {
|
||||||
$name = Receiver::PUBLIC_COLLECTION;
|
$name = Receiver::PUBLIC_COLLECTION;
|
||||||
|
} elseif ($path = parse_url($receiver, PHP_URL_PATH)) {
|
||||||
|
$name = trim($path, '/');
|
||||||
} else {
|
} else {
|
||||||
$name = trim(parse_url($receiver, PHP_URL_PATH), '/');
|
Logger::warning('Unable to coerce name from receiver', ['receiver' => $receiver]);
|
||||||
|
$name = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$target = Tag::getTargetType($receiver);
|
$target = Tag::getTargetType($receiver);
|
||||||
|
|
|
@ -1472,7 +1472,7 @@ class Receiver
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$element = ['type' => str_replace('as:', '', JsonLD::fetchElement($tag, '@type')),
|
$element = ['type' => str_replace('as:', '', JsonLD::fetchElement($tag, '@type') ?? ''),
|
||||||
'href' => JsonLD::fetchElement($tag, 'as:href', '@id'),
|
'href' => JsonLD::fetchElement($tag, 'as:href', '@id'),
|
||||||
'name' => JsonLD::fetchElement($tag, 'as:name', '@value')];
|
'name' => JsonLD::fetchElement($tag, 'as:name', '@value')];
|
||||||
|
|
||||||
|
|
|
@ -826,9 +826,15 @@ class Diaspora
|
||||||
*/
|
*/
|
||||||
public static function isSupportedByContactUrl(string $url, ?bool $update = null): bool
|
public static function isSupportedByContactUrl(string $url, ?bool $update = null): bool
|
||||||
{
|
{
|
||||||
$contact = Contact::getByURL($url, $update);
|
$contact = Contact::getByURL($url, $update, ['uri-id', 'network']);
|
||||||
|
|
||||||
return DI::dsprContact()->existsByUriId($contact['uri-id'] ?? 0);
|
$supported = DI::dsprContact()->existsByUriId($contact['uri-id'] ?? 0);
|
||||||
|
|
||||||
|
if (!$supported && is_null($update) && ($contact['network'] == Protocol::DFRN)) {
|
||||||
|
$supported = self::isSupportedByContactUrl($url, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4064,7 +4070,7 @@ class Diaspora
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self::isSupportedByContactUrl($parent_post['author-link'], false)) {
|
if (!self::isSupportedByContactUrl($parent_post['author-link'])) {
|
||||||
Logger::info('Parent author is no Diaspora contact.', ['parent-id' => $parent_id]);
|
Logger::info('Parent author is no Diaspora contact.', ['parent-id' => $parent_id]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ class DiasporaContact extends \Friendica\BaseEntity
|
||||||
protected $notify;
|
protected $notify;
|
||||||
/** @var UriInterface */
|
/** @var UriInterface */
|
||||||
protected $poll;
|
protected $poll;
|
||||||
/** @var UriInterface */
|
/** @var string URL pattern string including a placeholder "{uri}" that mustn't be URL-encoded */
|
||||||
protected $subscribe;
|
protected $subscribe;
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
protected $searchable;
|
protected $searchable;
|
||||||
|
@ -107,7 +107,7 @@ class DiasporaContact extends \Friendica\BaseEntity
|
||||||
UriInterface $url, \DateTime $created, string $guid = null, string $addr = null, UriInterface $alias = null,
|
UriInterface $url, \DateTime $created, string $guid = null, string $addr = null, UriInterface $alias = null,
|
||||||
string $nick = null, string $name = null, string $givenName = null, string $familyName = null,
|
string $nick = null, string $name = null, string $givenName = null, string $familyName = null,
|
||||||
UriInterface $photo = null, UriInterface $photoMedium = null, UriInterface $photoSmall = null,
|
UriInterface $photo = null, UriInterface $photoMedium = null, UriInterface $photoSmall = null,
|
||||||
UriInterface $batch = null, UriInterface $notify = null, UriInterface $poll = null, UriInterface $subscribe = null,
|
UriInterface $batch = null, UriInterface $notify = null, UriInterface $poll = null, string $subscribe = null,
|
||||||
bool $searchable = null, string $pubKey = null, UriInterface $baseurl = null, int $gsid = null,
|
bool $searchable = null, string $pubKey = null, UriInterface $baseurl = null, int $gsid = null,
|
||||||
\DateTime $updated = null, int $interacting_count = 0, int $interacted_count = 0, int $post_count = 0, int $uriId = null
|
\DateTime $updated = null, int $interacting_count = 0, int $interacted_count = 0, int $post_count = 0, int $uriId = null
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -45,7 +45,7 @@ class DiasporaContact extends \Friendica\BaseFactory implements ICanCreateFromTa
|
||||||
$row['batch'] ? new Uri($row['batch']) : null,
|
$row['batch'] ? new Uri($row['batch']) : null,
|
||||||
$row['notify'] ? new Uri($row['notify']) : null,
|
$row['notify'] ? new Uri($row['notify']) : null,
|
||||||
$row['poll'] ? new Uri($row['poll']) : null,
|
$row['poll'] ? new Uri($row['poll']) : null,
|
||||||
$row['subscribe'] ? new Uri($row['subscribe']) : null,
|
$row['subscribe'],
|
||||||
$row['searchable'],
|
$row['searchable'],
|
||||||
$row['pubkey'],
|
$row['pubkey'],
|
||||||
$row['baseurl'] ? new Uri($row['baseurl']) : null,
|
$row['baseurl'] ? new Uri($row['baseurl']) : null,
|
||||||
|
@ -87,7 +87,7 @@ class DiasporaContact extends \Friendica\BaseFactory implements ICanCreateFromTa
|
||||||
$data['batch'] ? new Uri($data['batch']) : null,
|
$data['batch'] ? new Uri($data['batch']) : null,
|
||||||
$data['notify'] ? new Uri($data['notify']) : null,
|
$data['notify'] ? new Uri($data['notify']) : null,
|
||||||
$data['poll'] ? new Uri($data['poll']) : null,
|
$data['poll'] ? new Uri($data['poll']) : null,
|
||||||
$data['subscribe'] ? new Uri($data['subscribe']) : null,
|
$data['subscribe'],
|
||||||
!$data['hide'],
|
!$data['hide'],
|
||||||
$data['pubkey'],
|
$data['pubkey'],
|
||||||
$data['baseurl'] ? new Uri($data['baseurl']) : null,
|
$data['baseurl'] ? new Uri($data['baseurl']) : null,
|
||||||
|
|
|
@ -234,6 +234,18 @@ class DiasporaContact extends BaseRepository
|
||||||
*/
|
*/
|
||||||
public function updateFromProbeArray(array $data): Entity\DiasporaContact
|
public function updateFromProbeArray(array $data): Entity\DiasporaContact
|
||||||
{
|
{
|
||||||
|
if (empty($data['url'])) {
|
||||||
|
throw new \InvalidArgumentException('Missing url key in Diaspora probe data array');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($data['guid'])) {
|
||||||
|
throw new \InvalidArgumentException('Missing guid key in Diaspora probe data array');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($data['pubkey'])) {
|
||||||
|
throw new \InvalidArgumentException('Missing pubkey key in Diaspora probe data array');
|
||||||
|
}
|
||||||
|
|
||||||
$uriId = ItemURI::insert(['uri' => $data['url'], 'guid' => $data['guid']]);
|
$uriId = ItemURI::insert(['uri' => $data['url'], 'guid' => $data['guid']]);
|
||||||
|
|
||||||
$contact = Contact::getByUriId($uriId, ['id', 'created']);
|
$contact = Contact::getByUriId($uriId, ['id', 'created']);
|
||||||
|
|
|
@ -625,8 +625,8 @@ class Feed
|
||||||
|
|
||||||
$notify = Item::isRemoteSelf($contact, $item);
|
$notify = Item::isRemoteSelf($contact, $item);
|
||||||
|
|
||||||
// Distributed items should have a well formatted URI.
|
// Distributed items should have a well-formatted URI.
|
||||||
// Additionally we have to avoid conflicts with identical URI between imported feeds and these items.
|
// Additionally, we have to avoid conflicts with identical URI between imported feeds and these items.
|
||||||
if ($notify) {
|
if ($notify) {
|
||||||
$item['guid'] = Item::guidFromUri($orig_plink, DI::baseUrl()->getHostname());
|
$item['guid'] = Item::guidFromUri($orig_plink, DI::baseUrl()->getHostname());
|
||||||
$item['uri'] = Item::newURI($item['guid']);
|
$item['uri'] = Item::newURI($item['guid']);
|
||||||
|
|
|
@ -277,7 +277,7 @@ class Delivery
|
||||||
private static function deliverDFRN(string $cmd, array $contact, array $owner, array $items, array $target_item, bool $public_message, bool $top_level, bool $followup, int $server_protocol = null)
|
private static function deliverDFRN(string $cmd, array $contact, array $owner, array $items, array $target_item, bool $public_message, bool $top_level, bool $followup, int $server_protocol = null)
|
||||||
{
|
{
|
||||||
// Transmit Diaspora reshares via Diaspora if the Friendica contact support Diaspora
|
// Transmit Diaspora reshares via Diaspora if the Friendica contact support Diaspora
|
||||||
if (Diaspora::getReshareDetails($target_item ?? []) && Diaspora::isSupportedByContactUrl($contact['addr'], false)) {
|
if (Diaspora::getReshareDetails($target_item ?? []) && Diaspora::isSupportedByContactUrl($contact['addr'])) {
|
||||||
Logger::info('Reshare will be transmitted via Diaspora', ['url' => $contact['url'], 'guid' => ($target_item['guid'] ?? '') ?: $target_item['id']]);
|
Logger::info('Reshare will be transmitted via Diaspora', ['url' => $contact['url'], 'guid' => ($target_item['guid'] ?? '') ?: $target_item['id']]);
|
||||||
self::deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup);
|
self::deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -6,7 +6,7 @@ $(function(){
|
||||||
var value = this.dataset.filterValue;
|
var value = this.dataset.filterValue;
|
||||||
var re = RegExp(filter+"=[a-z]*");
|
var re = RegExp(filter+"=[a-z]*");
|
||||||
var newhref = location.href;
|
var newhref = location.href;
|
||||||
if (!location.href.indexOf("?") < 0) {
|
if (location.href.indexOf("?") < 0) {
|
||||||
newhref = location.href + "?" + filter + "=" + value;
|
newhref = location.href + "?" + filter + "=" + value;
|
||||||
} else if (location.href.match(re)) {
|
} else if (location.href.match(re)) {
|
||||||
newhref = location.href.replace(RegExp(filter+"=[a-z]*"), filter+"="+value);
|
newhref = location.href.replace(RegExp(filter+"=[a-z]*"), filter+"="+value);
|
||||||
|
|
Loading…
Reference in a new issue