mirror of
https://github.com/friendica/friendica
synced 2025-04-27 07:10:12 +00:00
Merge branch 'develop' into refactoring-of-app-class
This commit is contained in:
commit
a24a65de2f
561 changed files with 64963 additions and 61342 deletions
|
@ -1082,17 +1082,17 @@ class Contact
|
|||
*/
|
||||
public static function markForArchival(array $contact)
|
||||
{
|
||||
if (!isset($contact['url']) && !empty($contact['id'])) {
|
||||
$fields = ['id', 'url', 'archive', 'self', 'term-date'];
|
||||
if ((!isset($contact['uri-id']) || !isset($contact['url']) || !isset($contact['archive']) || !isset($contact['self']) || !isset($contact['term-date'])) && !empty($contact['id'])) {
|
||||
$fields = ['id', 'uri-id', 'url', 'archive', 'self', 'term-date'];
|
||||
$contact = DBA::selectFirst('contact', $fields, ['id' => $contact['id']]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
return;
|
||||
}
|
||||
} elseif (!isset($contact['url'])) {
|
||||
} elseif (!isset($contact['url']) || !isset($contact['uri-id'])) {
|
||||
Logger::info('Empty contact', ['contact' => $contact]);
|
||||
}
|
||||
|
||||
Logger::info('Contact is marked for archival', ['id' => $contact['id'], 'term-date' => $contact['term-date']]);
|
||||
Logger::info('Contact is marked for archival', ['id' => $contact['id'], 'archive' => $contact['archive'], 'term-date' => $contact['term-date'], 'url' => $contact['url']]);
|
||||
|
||||
// Contact already archived or "self" contact? => nothing to do
|
||||
if ($contact['archive'] || $contact['self']) {
|
||||
|
@ -1100,8 +1100,7 @@ class Contact
|
|||
}
|
||||
|
||||
if ($contact['term-date'] <= DBA::NULL_DATETIME) {
|
||||
self::update(['term-date' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
|
||||
self::update(['term-date' => DateTimeFormat::utcNow()], ['`nurl` = ? AND `term-date` <= ? AND NOT `self`', Strings::normaliseLink($contact['url']), DBA::NULL_DATETIME]);
|
||||
self::update(['term-date' => DateTimeFormat::utcNow()], ['uri-id' => $contact['uri-id'], 'self' => false]);
|
||||
} else {
|
||||
/* @todo
|
||||
* We really should send a notification to the owner after 2-3 weeks
|
||||
|
@ -1118,8 +1117,7 @@ class Contact
|
|||
* delete, though if the owner tries to unarchive them we'll start
|
||||
* the whole process over again.
|
||||
*/
|
||||
self::update(['archive' => true], ['id' => $contact['id']]);
|
||||
self::update(['archive' => true], ['nurl' => Strings::normaliseLink($contact['url']), 'self' => false]);
|
||||
self::update(['archive' => true], ['uri-id' => $contact['uri-id'], 'self' => false]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1144,28 +1142,25 @@ class Contact
|
|||
}
|
||||
}
|
||||
|
||||
$condition = ['`id` = ? AND (`term-date` > ? OR `archive`)', $contact['id'], DBA::NULL_DATETIME];
|
||||
$exists = DBA::exists('contact', $condition);
|
||||
|
||||
// We don't need to update, we never marked this contact for archival
|
||||
if (!$exists) {
|
||||
$condition = ['`id` = ? AND (`term-date` > ? OR `archive`)', $contact['id'], DBA::NULL_DATETIME];
|
||||
if (!DBA::exists('contact', $condition)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logger::info('Contact is marked as vital again', ['id' => $contact['id'], 'term-date' => $contact['term-date']]);
|
||||
|
||||
if (!isset($contact['url']) && !empty($contact['id'])) {
|
||||
$fields = ['id', 'url', 'batch'];
|
||||
if ((!isset($contact['url']) || !isset($contact['uri-id'])) && !empty($contact['id'])) {
|
||||
$fields = ['id', 'uri-id', 'url', 'batch', 'term-date'];
|
||||
$contact = DBA::selectFirst('contact', $fields, ['id' => $contact['id']]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Logger::info('Contact is marked as vital again', ['id' => $contact['id'], 'term-date' => $contact['term-date'], 'url' => $contact['url']]);
|
||||
|
||||
// It's a miracle. Our dead contact has inexplicably come back to life.
|
||||
$fields = ['failed' => false, 'term-date' => DBA::NULL_DATETIME, 'archive' => false];
|
||||
self::update($fields, ['id' => $contact['id']]);
|
||||
self::update($fields, ['nurl' => Strings::normaliseLink($contact['url']), 'self' => false]);
|
||||
self::update($fields, ['uri-id' => $contact['uri-id'], 'self' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1225,7 +1220,7 @@ class Contact
|
|||
if ($contact['uid'] && in_array($contact['rel'], [self::SHARING, self::FRIEND])) {
|
||||
$unfollow_link = 'contact/unfollow?url=' . urlencode($contact['url']) . '&auto=1';
|
||||
} elseif (!$contact['pending']) {
|
||||
$follow_link = 'contact/follow?url=' . urlencode($contact['url']) . '&auto=1';
|
||||
$follow_link = 'contact/follow?binurl=' . bin2hex($contact['url']) . '&auto=1';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1372,7 +1367,7 @@ class Contact
|
|||
$personal_contact = DBA::selectFirst('contact', $fields, ["`nurl` = ? AND `uid` != 0", Strings::normaliseLink($url)]);
|
||||
}
|
||||
|
||||
if (DBA::isResult($personal_contact)) {
|
||||
if (DBA::isResult($personal_contact) && !Probe::isProbable($personal_contact['network'])) {
|
||||
Logger::info('Take contact data from personal contact', ['url' => $url, 'update' => $update, 'contact' => $personal_contact]);
|
||||
$data = $personal_contact;
|
||||
$data['photo'] = $personal_contact['avatar'];
|
||||
|
@ -1590,11 +1585,15 @@ class Contact
|
|||
*/
|
||||
public static function getPostsFromId(int $cid, int $uid, bool $only_media = false, string $last_created = null): string
|
||||
{
|
||||
$contact = DBA::selectFirst('contact', ['contact-type', 'network'], ['id' => $cid]);
|
||||
$contact = DBA::selectFirst('contact', ['contact-type', 'network', 'name', 'nick'], ['id' => $cid]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (Contact\User::isIsBlocked($cid, $uid)) {
|
||||
return DI::l10n()->t('%s has blocked you', $contact['name'] ?: $contact['nick']);
|
||||
}
|
||||
|
||||
if (empty($contact["network"]) || in_array($contact["network"], Protocol::FEDERATED)) {
|
||||
$condition = ["(`uid` = 0 OR (`uid` = ? AND NOT `global`))", $uid];
|
||||
} else {
|
||||
|
@ -1658,11 +1657,15 @@ class Contact
|
|||
*/
|
||||
public static function getThreadsFromId(int $cid, int $uid, int $update = 0, int $parent = 0, string $last_created = ''): string
|
||||
{
|
||||
$contact = DBA::selectFirst('contact', ['contact-type', 'network'], ['id' => $cid]);
|
||||
$contact = DBA::selectFirst('contact', ['contact-type', 'network', 'name', 'nick'], ['id' => $cid]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (Contact\User::isIsBlocked($cid, $uid)) {
|
||||
return DI::l10n()->t('%s has blocked you', $contact['name'] ?: $contact['nick']);
|
||||
}
|
||||
|
||||
if (empty($contact["network"]) || in_array($contact["network"], Protocol::FEDERATED)) {
|
||||
$condition = ["(`uid` = 0 OR (`uid` = ? AND NOT `global`))", $uid];
|
||||
} else {
|
||||
|
@ -2298,7 +2301,7 @@ class Contact
|
|||
return;
|
||||
}
|
||||
|
||||
if (!Network::isValidHttpUrl($avatar)) {
|
||||
if (!empty($avatar) && !Network::isValidHttpUrl($avatar)) {
|
||||
Logger::warning('Invalid avatar', ['cid' => $cid, 'avatar' => $avatar]);
|
||||
$avatar = '';
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Friendica\Model\Contact;
|
|||
|
||||
use Exception;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
|
@ -140,13 +140,21 @@ class User
|
|||
|
||||
$contact = Contact::getById($cdata['public']);
|
||||
if ($blocked) {
|
||||
Protocol::block($contact, $uid);
|
||||
Worker::add(Worker::PRIORITY_HIGH, 'Contact\Block', $cid, $uid);
|
||||
} else {
|
||||
Protocol::unblock($contact, $uid);
|
||||
Worker::add(Worker::PRIORITY_HIGH, 'Contact\Unblock', $cid, $uid);
|
||||
}
|
||||
|
||||
if ($cdata['user'] != 0) {
|
||||
DBA::update('contact', ['blocked' => $blocked], ['id' => $cdata['user'], 'pending' => false]);
|
||||
|
||||
if ($blocked) {
|
||||
$contact = Contact::getById($cdata['user']);
|
||||
if (!empty($contact)) {
|
||||
// Mastodon-expected behavior: relationship is severed on block
|
||||
Contact::terminateFriendship($contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DBA::update('user-contact', ['blocked' => $blocked], ['cid' => $cdata['public'], 'uid' => $uid], true);
|
||||
|
|
|
@ -30,6 +30,7 @@ class Conversation
|
|||
const PARCEL_ATOM03 = 15;
|
||||
const PARCEL_OPML = 16;
|
||||
const PARCEL_TWITTER = 67;
|
||||
const PARCEL_CONNECTOR = 68;
|
||||
const PARCEL_UNKNOWN = 255;
|
||||
|
||||
/**
|
||||
|
|
|
@ -753,6 +753,10 @@ class GServer
|
|||
$serverdata = self::detectNetworkViaContacts($url, $serverdata);
|
||||
}
|
||||
|
||||
if ($serverdata['platform'] == 'mastodon') {
|
||||
$serverdata = self::detectMastodonForks($serverdata);
|
||||
}
|
||||
|
||||
if (($serverdata['network'] == Protocol::PHANTOM) && in_array($serverdata['detection-method'], [self::DETECT_MANUAL, self::DETECT_BODY])) {
|
||||
self::setFailureByUrl($url);
|
||||
return false;
|
||||
|
@ -1792,6 +1796,23 @@ class GServer
|
|||
return $serverdata;
|
||||
}
|
||||
|
||||
private static function detectMastodonForks(array $serverdata): array
|
||||
{
|
||||
if (strpos($serverdata['version'], 'glitch') !== false) {
|
||||
$serverdata['platform'] = 'glitchsoc';
|
||||
}
|
||||
|
||||
if (strpos($serverdata['version'], 'chuckya') !== false) {
|
||||
$serverdata['platform'] = 'chuckya';
|
||||
}
|
||||
|
||||
if (strpos($serverdata['version'], 'sakura') !== false) {
|
||||
$serverdata['platform'] = 'sakura';
|
||||
}
|
||||
|
||||
return $serverdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given server does have a '/poco' endpoint.
|
||||
* This is used for the 'PortableContact' functionality,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Friendica\Model;
|
||||
|
||||
use Friendica\Contact\LocalRelationship\Entity\LocalRelationship;
|
||||
use Friendica\Content\ContactSelector;
|
||||
use Friendica\Content\Image;
|
||||
use Friendica\Content\Post\Collection\PostMedias;
|
||||
use Friendica\Content\Post\Entity\PostMedia;
|
||||
|
@ -3375,7 +3376,7 @@ class Item
|
|||
$item['body'] = preg_replace("#\s*\[attachment .*?].*?\[/attachment]\s*#ism", "\n", $item['body']);
|
||||
}
|
||||
|
||||
$fields = ['uri-id', 'uri', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink', 'network', 'has-media', 'quote-uri-id', 'post-type'];
|
||||
$fields = ['uri-id', 'uri', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'author-gsid', 'guid', 'created', 'plink', 'network', 'has-media', 'quote-uri-id', 'post-type'];
|
||||
|
||||
$shared_uri_id = 0;
|
||||
$shared_links = [];
|
||||
|
@ -3383,7 +3384,7 @@ class Item
|
|||
|
||||
$shared = DI::contentItem()->getSharedPost($item, $fields);
|
||||
if (!empty($shared['post'])) {
|
||||
$shared_item = $shared['post'];
|
||||
$shared_item = $shared['post'];
|
||||
$shared_item['body'] = Post\Media::removeFromEndOfBody($shared_item['body']);
|
||||
$shared_item['body'] = Post\Media::replaceImage($shared_item['body']);
|
||||
$quote_uri_id = $shared['post']['uri-id'];
|
||||
|
@ -3470,6 +3471,10 @@ class Item
|
|||
unset($hook_data);
|
||||
}
|
||||
|
||||
if (!empty($shared_item['uri-id'])) {
|
||||
$s = self::replacePlatformIcon($s, $shared_item, $uid);
|
||||
}
|
||||
|
||||
$hook_data = [
|
||||
'item' => $item,
|
||||
'html' => $s,
|
||||
|
@ -3533,6 +3538,39 @@ class Item
|
|||
return $hook_data['html'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the platform icon with the icon in the style selected by the user
|
||||
*
|
||||
* @param string $html
|
||||
* @param array $item
|
||||
* @param integer $uid
|
||||
* @return string
|
||||
*/
|
||||
private static function replacePlatformIcon(string $html, array $item, int $uid): string
|
||||
{
|
||||
$dom = new \DOMDocument();
|
||||
if (!@$dom->loadHTML($html)) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$svg = ContactSelector::networkToSVG($item['network'], $item['author-gsid'], '', $uid);
|
||||
if (empty($svg)) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$xpath = new \DOMXPath($dom);
|
||||
/** @var DOMElement $element */
|
||||
foreach ($xpath->query("//img[@class='network-svg']") as $element) {
|
||||
$src = $element->getAttributeNode('src')->nodeValue;
|
||||
if ($src == $svg) {
|
||||
continue;
|
||||
}
|
||||
$element_html = $element->ownerDocument->saveHTML($element);
|
||||
$html = str_replace($element_html, str_replace($src, $svg, $element_html), $html);
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify links to pictures to links for the "Fancybox" gallery
|
||||
*
|
||||
|
@ -3733,6 +3771,9 @@ class Item
|
|||
continue;
|
||||
}
|
||||
|
||||
if (empty($PostMedia->description) && DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'accessibility', 'hide_empty_descriptions')) {
|
||||
continue;
|
||||
}
|
||||
$images[] = $PostMedia->withUrl(new Uri($src_url))->withPreview(new Uri($preview_url), $preview_size);
|
||||
}
|
||||
}
|
||||
|
@ -4152,6 +4193,10 @@ class Item
|
|||
|
||||
try {
|
||||
$curlResult = DI::httpClient()->head($uri, [HttpClientOptions::ACCEPT_CONTENT => HttpClientAccept::JSON_AS, HttpClientOptions::REQUEST => HttpClientRequest::ACTIVITYPUB]);
|
||||
if (!HTTPSignature::isValidContentType($curlResult->getContentType(), $uri) && (current(explode(';', $curlResult->getContentType())) == 'application/json')) {
|
||||
// Issue 14126: Workaround for Mastodon servers that return "application/json" on a "head" request.
|
||||
$curlResult = HTTPSignature::fetchRaw($uri, $uid);
|
||||
}
|
||||
if (HTTPSignature::isValidContentType($curlResult->getContentType(), $uri)) {
|
||||
$fetched_uri = ActivityPub\Processor::fetchMissingActivity($uri, [], '', $completion, $uid);
|
||||
}
|
||||
|
|
|
@ -465,7 +465,7 @@ class Post
|
|||
AND ((NOT `contact-readonly` AND NOT `contact-pending` AND (`contact-rel` IN (?, ?)))
|
||||
OR `self` OR `contact-uid` = ?)
|
||||
AND NOT EXISTS(SELECT `uri-id` FROM `post-user` WHERE `uid` = ? AND `uri-id` = " . DBA::quoteIdentifier($view) . ".`uri-id` AND `hidden`)
|
||||
AND NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` IN (`author-id`, `owner-id`) AND (`blocked` OR `ignored`))
|
||||
AND NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` IN (`author-id`, `owner-id`) AND (`blocked` OR `ignored` OR `is-blocked`))
|
||||
AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = ? AND `gsid` IN (`author-gsid`, `owner-gsid`, `causer-gsid`) AND `ignored`)",
|
||||
0, Contact::SHARING, Contact::FRIEND, 0, $uid, $uid, $uid]);
|
||||
|
||||
|
|
|
@ -324,7 +324,7 @@ class Profile
|
|||
if ($visitor_is_following) {
|
||||
$unfollow_link = $visitor_base_path . '/contact/unfollow?url=' . urlencode($profile_url) . '&auto=1';
|
||||
} else {
|
||||
$follow_link = $visitor_base_path . '/contact/follow?url=' . urlencode($profile_url) . '&auto=1';
|
||||
$follow_link = $visitor_base_path . '/contact/follow?binurl=' . bin2hex($profile_url) . '&auto=1';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue