diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 2bb563e74..6d41cd85c 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -997,7 +997,7 @@ class BBCode $attributes[$field] = html_entity_decode($matches[2] ?? '', ENT_QUOTES, 'UTF-8'); } - $author_contact = Contact::getByURL($attributes['profile'], false, ['url', 'addr', 'name', 'micro']); + $author_contact = Contact::getByURL($attributes['profile'], false, ['id', 'url', 'addr', 'name', 'micro']); $author_contact['url'] = ($author_contact['url'] ?? $attributes['profile']); $author_contact['addr'] = ($author_contact['addr'] ?? '') ?: Protocol::getAddrFromProfileUrl($attributes['profile']); @@ -1005,7 +1005,9 @@ class BBCode $attributes['avatar'] = ($author_contact['micro'] ?? '') ?: $attributes['avatar']; $attributes['profile'] = ($author_contact['url'] ?? '') ?: $attributes['profile']; - if ($attributes['avatar']) { + if (!empty($author_contact['id'])) { + $attributes['avatar'] = Contact::getAvatarUrlForId($author_contact['id'], ProxyUtils::SIZE_THUMB); + } elseif ($attributes['avatar']) { $attributes['avatar'] = ProxyUtils::proxifyUrl($attributes['avatar'], false, ProxyUtils::SIZE_THUMB); } diff --git a/src/Factory/Api/Mastodon/Attachment.php b/src/Factory/Api/Mastodon/Attachment.php index a447e6b8f..f073ac157 100644 --- a/src/Factory/Api/Mastodon/Attachment.php +++ b/src/Factory/Api/Mastodon/Attachment.php @@ -67,17 +67,16 @@ class Attachment extends BaseFactory $remote = $attachment['url']; if ($type == 'image') { - if (Proxy::isLocalImage($attachment['url'])) { - $url = $attachment['url']; - $preview = $attachment['preview'] ?? $url; - $remote = ''; - } else { - $url = Proxy::proxifyUrl($attachment['url']); - $preview = Proxy::proxifyUrl($attachment['url'], false, Proxy::SIZE_SMALL); - } + $url = Post\Media::getPreviewUrlForId($attachment['id']); + $preview = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_SMALL); } else { - $url = Proxy::proxifyUrl($attachment['url']); - $preview = Proxy::proxifyUrl($attachment['preview'] ?? ''); + $url = $attachment['url']; + + if (!empty($attachment['preview'])) { + $preview = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_SMALL); + } else { + $preview = ''; + } } $object = new \Friendica\Object\Api\Mastodon\Attachment($attachment, $type, $url, $preview, $remote); diff --git a/src/Factory/Notification/Introduction.php b/src/Factory/Notification/Introduction.php index aacb0b778..ff9c028af 100644 --- a/src/Factory/Notification/Introduction.php +++ b/src/Factory/Notification/Introduction.php @@ -139,7 +139,7 @@ class Introduction extends BaseFactory 'madeby_zrl' => Contact::magicLink($notification['url']), 'madeby_addr' => $notification['addr'], 'contact_id' => $notification['contact-id'], - 'photo' => (!empty($notification['fphoto']) ? Proxy::proxifyUrl($notification['fphoto'], false, Proxy::SIZE_SMALL) : Contact::DEFAULT_AVATAR_PHOTO), + 'photo' => Contact::getAvatarUrlForUrl($notification['furl'], 0, Proxy::SIZE_SMALL), 'name' => $notification['fname'], 'url' => $notification['furl'], 'zrl' => Contact::magicLink($notification['furl']), diff --git a/src/Factory/Notification/Notification.php b/src/Factory/Notification/Notification.php index 1167c5a75..e69b2131e 100644 --- a/src/Factory/Notification/Notification.php +++ b/src/Factory/Notification/Notification.php @@ -32,6 +32,7 @@ use Friendica\Core\PConfig\IPConfig; use Friendica\Core\Protocol; use Friendica\Core\Session\ISession; use Friendica\Database\Database; +use Friendica\Model\Contact; use Friendica\Model\Post; use Friendica\Module\BaseNotifications; use Friendica\Network\HTTPException\InternalServerErrorException; @@ -239,7 +240,7 @@ class Notification extends BaseFactory $formattedNotifications[] = new \Friendica\Object\Notification\Notification([ 'label' => 'notification', 'link' => $this->baseUrl->get(true) . '/notification/' . $notification->id, - 'image' => Proxy::proxifyUrl($notification->photo, false, Proxy::SIZE_MICRO), + 'image' => Contact::getAvatarUrlForUrl($notification->url, $notification->uid, Proxy::SIZE_MICRO), 'url' => $notification->url, 'text' => strip_tags(BBCode::convert($notification->msg)), 'when' => DateTimeFormat::local($notification->date, 'r'), diff --git a/src/Model/Contact.php b/src/Model/Contact.php index dc7848278..86f848da3 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1510,14 +1510,10 @@ class Contact $avatar = $contact['avatar']; } - if (empty($avatar)) { - $avatar = self::getDefaultAvatar([], $size); - } - - if (Proxy::isLocalImage($avatar)) { + if (!empty($avatar) && Proxy::isLocalImage($avatar)) { return $avatar; } else { - return Proxy::proxifyUrl($avatar, false, $size); + return self::getAvatarUrlForId($contact['id'], $size); } } @@ -1665,12 +1661,47 @@ class Contact /** * Get avatar link for given contact id * - * @param integer $cid contact id + * @param integer $cid contact id + * @param string $size One of the ProxyUtils::SIZE_* constants * @return string avatar link */ - public static function getAvatarUrlForId(int $cid):string + public static function getAvatarUrlForId(int $cid, string $size = ''):string { - return DI::baseUrl() . '/photo/contact/' . $cid; + $url = DI::baseUrl() . '/photo/contact/'; + switch ($size) { + case Proxy::SIZE_MICRO: + $url .= Proxy::PIXEL_MICRO . '/'; + break; + case Proxy::SIZE_THUMB: + $url .= Proxy::PIXEL_THUMB . '/'; + break; + case Proxy::SIZE_SMALL: + $url .= Proxy::PIXEL_SMALL . '/'; + break; + case Proxy::SIZE_MEDIUM: + $url .= Proxy::PIXEL_MEDIUM . '/'; + break; + case Proxy::SIZE_LARGE: + $url .= Proxy::PIXEL_LARGE . '/'; + break; + } + return $url . $cid; + } + + /** + * Get avatar link for given contact URL + * + * @param string $url contact url + * @param integer $uid user id + * @param string $size One of the ProxyUtils::SIZE_* constants + * @return string avatar link + */ + public static function getAvatarUrlForUrl(string $url, int $uid, string $size = ''):string + { + $condition = ["`nurl` = ? AND ((`uid` = ? AND `network` IN (?, ?)) OR `uid` = ?)", + Strings::normaliseLink($url), $uid, Protocol::FEED, Protocol::MAIL, 0]; + $contact = self::selectFirst(['id'], $condition); + return self::getAvatarUrlForId($contact['id'] ?? 0, $size); } /** diff --git a/src/Model/Item.php b/src/Model/Item.php index 871ff9ad8..78e0321b4 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -2863,12 +2863,8 @@ class Item continue; } - $author = ['uid' => 0, 'id' => $item['author-id'], - 'network' => $item['author-network'], 'url' => $item['author-link']]; - $the_url = Contact::magicLinkByContact($author, $attachment['url']); - if (!empty($attachment['preview'])) { - $preview_url = Proxy::proxifyUrl(Contact::magicLinkByContact($author, $attachment['preview'])); + $preview_url = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_LARGE); } else { $preview_url = ''; } @@ -2878,7 +2874,7 @@ class Item $media = Renderer::replaceMacros(Renderer::getMarkupTemplate('video_top.tpl'), [ '$video' => [ 'id' => $attachment['id'], - 'src' => $the_url, + 'src' => $attachment['url'], 'name' => $attachment['name'] ?: $attachment['url'], 'preview' => $preview_url, 'mime' => $attachment['mimetype'], @@ -2893,8 +2889,8 @@ class Item $media = Renderer::replaceMacros(Renderer::getMarkupTemplate('content/audio.tpl'), [ '$audio' => [ 'id' => $attachment['id'], - 'src' => $the_url, - 'name' => $attachment['name'] ?: $attachment['url'], + 'src' => $attachment['url'], + 'name' => $attachment['name'] ?: $attachment['url'], 'mime' => $attachment['mimetype'], ], ]); @@ -2904,14 +2900,11 @@ class Item $trailing .= $media; } } elseif ($attachment['filetype'] == 'image') { - if (empty($preview_url) && (max($attachment['width'], $attachment['height']) > 600)) { - $preview_url = Proxy::proxifyUrl($the_url, false, ($attachment['width'] > $attachment['height']) ? Proxy::SIZE_MEDIUM : Proxy::SIZE_LARGE); - } $media = Renderer::replaceMacros(Renderer::getMarkupTemplate('content/image.tpl'), [ - '$image' => [ - 'src' => Proxy::proxifyUrl($the_url), - 'preview' => $preview_url, - 'attachment' => $attachment, + '$image' => [ + 'src' => Post\Media::getUrlForId($attachment['id']), + 'preview' => Post\Media::getPreviewUrlForId($attachment['id'], ($attachment['width'] > $attachment['height']) ? Proxy::SIZE_MEDIUM : Proxy::SIZE_LARGE), + 'attachment' => $attachment, ], ]); // On Diaspora posts the attached pictures are leading @@ -2989,11 +2982,11 @@ class Item 'type' => 'link', 'url' => $attachment['url']]; - if ($preview) { + if ($preview && !empty($attachment['preview'])) { if ($attachment['preview-width'] >= 500) { - $data['image'] = $attachment['preview'] ?? ''; + $data['image'] = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_MEDIUM); } else { - $data['preview'] = $attachment['preview'] ?? ''; + $data['preview'] = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_MEDIUM); } } diff --git a/src/Model/Post/Media.php b/src/Model/Post/Media.php index 81c41755f..63bfe0034 100644 --- a/src/Model/Post/Media.php +++ b/src/Model/Post/Media.php @@ -31,6 +31,7 @@ use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Util\Images; use Friendica\Util\ParseUrl; +use Friendica\Util\Proxy; use Friendica\Util\Strings; /** @@ -494,10 +495,10 @@ class Media /** * Split the attachment media in the three segments "visual", "link" and "additional" - * - * @param int $uri_id + * + * @param int $uri_id * @param string $guid - * @param array $links ist of links that shouldn't be added + * @param array $links ist of links that shouldn't be added * @return array attachments */ public static function splitAttachments(int $uri_id, string $guid = '', array $links = []) @@ -526,7 +527,7 @@ class Media continue 2; } } - + if (!empty($medium['preview'])) { $previews[] = $medium['preview']; } @@ -631,4 +632,64 @@ class Media return $body; } + + /** + * Get preview link for given media id + * + * @param integer $id media id + * @param string $size One of the ProxyUtils::SIZE_* constants + * @return string preview link + */ + public static function getPreviewUrlForId(int $id, string $size = ''):string + { + $url = DI::baseUrl() . '/photo/preview/'; + switch ($size) { + case Proxy::SIZE_MICRO: + $url .= Proxy::PIXEL_MICRO . '/'; + break; + case Proxy::SIZE_THUMB: + $url .= Proxy::PIXEL_THUMB . '/'; + break; + case Proxy::SIZE_SMALL: + $url .= Proxy::PIXEL_SMALL . '/'; + break; + case Proxy::SIZE_MEDIUM: + $url .= Proxy::PIXEL_MEDIUM . '/'; + break; + case Proxy::SIZE_LARGE: + $url .= Proxy::PIXEL_LARGE . '/'; + break; + } + return $url . $id; + } + + /** + * Get media link for given media id + * + * @param integer $id media id + * @param string $size One of the ProxyUtils::SIZE_* constants + * @return string media link + */ + public static function getUrlForId(int $id, string $size = ''):string + { + $url = DI::baseUrl() . '/photo/media/'; + switch ($size) { + case Proxy::SIZE_MICRO: + $url .= Proxy::PIXEL_MICRO . '/'; + break; + case Proxy::SIZE_THUMB: + $url .= Proxy::PIXEL_THUMB . '/'; + break; + case Proxy::SIZE_SMALL: + $url .= Proxy::PIXEL_SMALL . '/'; + break; + case Proxy::SIZE_MEDIUM: + $url .= Proxy::PIXEL_MEDIUM . '/'; + break; + case Proxy::SIZE_LARGE: + $url .= Proxy::PIXEL_LARGE . '/'; + break; + } + return $url . $id; + } } diff --git a/src/Model/Profile.php b/src/Model/Profile.php index b32c58fc9..b8a5bc822 100644 --- a/src/Model/Profile.php +++ b/src/Model/Profile.php @@ -329,9 +329,9 @@ class Profile // correct contact table entry for the logged-in user. $profile_contact = []; - if (!empty($profile['nurl'] ?? '')) { - if (local_user() && ($profile['uid'] ?? '') != local_user()) { - $profile_contact = Contact::getById(Contact::getIdForURL($profile['nurl'], local_user())); + if (!empty($profile['nurl'])) { + if (local_user() && ($profile['uid'] ?? 0) != local_user()) { + $profile_contact = Contact::getByURL($profile['nurl'], null, ['rel'], local_user()); } if (!empty($profile['cid']) && self::getMyURL()) { $profile_contact = Contact::selectFirst(['rel'], ['id' => $profile['cid']]); @@ -359,6 +359,12 @@ class Profile $profile_url = DI::baseUrl()->get() . '/profile/' . $profile['nickname']; } + if (!empty($profile['id'])) { + $cid = $profile['id']; + } else { + $cid = Contact::getIdForURL($profile_url, false); + } + $follow_link = null; $unfollow_link = null; $subscribe_feed_link = null; @@ -501,11 +507,9 @@ class Profile $p['address'] = BBCode::convert($p['address']); } - if (isset($p['photo'])) { - $p['photo'] = ProxyUtils::proxifyUrl($p['photo'], false, ProxyUtils::SIZE_SMALL); - } + $p['photo'] = Contact::getAvatarUrlForId($cid); - $p['url'] = Contact::magicLink(($p['url'] ?? '') ?: $profile_url); + $p['url'] = Contact::magicLink($profile_url); $tpl = Renderer::getMarkupTemplate('profile/vcard.tpl'); $o .= Renderer::replaceMacros($tpl, [ diff --git a/src/Module/Photo.php b/src/Module/Photo.php index d430fa9b0..9fdda1a8d 100644 --- a/src/Module/Photo.php +++ b/src/Module/Photo.php @@ -27,6 +27,7 @@ use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\Photo as MPhoto; +use Friendica\Model\Post; use Friendica\Util\Proxy; use Friendica\Object\Image; @@ -68,10 +69,10 @@ class Photo extends BaseModule if (!empty($parameters['customsize'])) { $customsize = intval($parameters['customsize']); $uid = MPhoto::stripExtension($parameters['name']); - $photo = self::getAvatar($uid, $parameters['type']); + $photo = self::getAvatar($uid, $parameters['type'], $customsize); } elseif (!empty($parameters['type'])) { $uid = MPhoto::stripExtension($parameters['name']); - $photo = self::getAvatar($uid, $parameters['type']); + $photo = self::getAvatar($uid, $parameters['type'], Proxy::PIXEL_SMALL); } elseif (!empty($parameters['name'])) { $photoid = MPhoto::stripExtension($parameters['name']); $scale = 0; @@ -149,23 +150,56 @@ class Photo extends BaseModule exit(); } - private static function getAvatar($uid, $type="avatar") + private static function getAvatar($uid, $type="avatar", $customsize) { switch($type) { + case "preview": + $media = DBA::selectFirst('post-media', ['preview', 'url', 'type', 'uri-id'], ['id' => $uid]); + if (empty($media)) { + return false; + } + $url = $media['preview']; + + if (empty($url) && ($media['type'] == Post\Media::IMAGE)) { + $url = $media['url']; + } + + if (empty($url)) { + return false; + } + + $author = Contact::selectFirst([], ["`id` IN (SELECT `author-id` FROM `post` WHERE `uri-id` = ?)", $media['uri-id']]); + $url = Contact::magicLinkByContact($author, $url); + + return MPhoto::createPhotoForExternalResource($url); + case "media": + $media = DBA::selectFirst('post-media', ['url'], ['id' => $uid, 'type' => Post\Media::IMAGE]); + if (empty($media['url'])) { + return false; + } + + $author = Contact::selectFirst([], ["`id` IN (SELECT `author-id` FROM `post` WHERE `uri-id` = ?)", $media['uri-id']]); + $url = Contact::magicLinkByContact($author, $media['url']); + + return MPhoto::createPhotoForExternalResource($url); case "contact": - $contact = Contact::getById($uid, ['uid', 'url', 'avatar', 'photo']); + $contact = Contact::getById($uid, ['uid', 'url', 'avatar', 'photo', 'xmpp', 'addr']); if (empty($contact)) { return false; } If (($contact['uid'] != 0) && empty($contact['photo']) && empty($contact['avatar'])) { - $contact = Contact::getByURL($contact['url'], false, ['avatar', 'photo']); + $contact = Contact::getByURL($contact['url'], false, ['avatar', 'photo', 'xmpp', 'addr']); } if (!empty($contact['photo'])) { $url = $contact['photo']; } elseif (!empty($contact['avatar'])) { $url = $contact['avatar']; + } elseif ($customsize <= Proxy::PIXEL_MICRO) { + $url = Contact::getDefaultAvatar($contact, Proxy::SIZE_MICRO); + } elseif ($customsize <= Proxy::PIXEL_THUMB) { + $url = Contact::getDefaultAvatar($contact, Proxy::SIZE_THUMB); } else { - $url = DI::baseUrl() . Contact::DEFAULT_AVATAR_PHOTO; + $url = Contact::getDefaultAvatar($contact, Proxy::SIZE_SMALL); } return MPhoto::createPhotoForExternalResource($url); case "header": @@ -210,7 +244,7 @@ class Photo extends BaseModule default: $default = Contact::getDefaultAvatar($contact, Proxy::SIZE_THUMB); } - + $parts = parse_url($default); if (!empty($parts['scheme']) || !empty($parts['host'])) { $photo = MPhoto::createPhotoForExternalResource($default); diff --git a/src/Module/Proxy.php b/src/Module/Proxy.php index e43852bab..f929d4f73 100644 --- a/src/Module/Proxy.php +++ b/src/Module/Proxy.php @@ -181,7 +181,7 @@ class Proxy extends BaseModule private static function getRequestInfo() { $a = DI::app(); - $size = 1024; + $size = ProxyUtils::PIXEL_LARGE; $sizetype = ''; // Look for filename in the arguments @@ -203,23 +203,23 @@ class Proxy extends BaseModule // thumb, small, medium and large. if (substr($url, -6) == ':micro') { - $size = 48; + $size = ProxyUtils::PIXEL_MICRO; $sizetype = ':micro'; $url = substr($url, 0, -6); } elseif (substr($url, -6) == ':thumb') { - $size = 80; + $size = ProxyUtils::PIXEL_THUMB; $sizetype = ':thumb'; $url = substr($url, 0, -6); } elseif (substr($url, -6) == ':small') { - $size = 300; + $size = ProxyUtils::PIXEL_SMALL; $url = substr($url, 0, -6); $sizetype = ':small'; } elseif (substr($url, -7) == ':medium') { - $size = 600; + $size = ProxyUtils::PIXEL_MEDIUM; $url = substr($url, 0, -7); $sizetype = ':medium'; } elseif (substr($url, -6) == ':large') { - $size = 1024; + $size = ProxyUtils::PIXEL_LARGE; $url = substr($url, 0, -6); $sizetype = ':large'; } diff --git a/src/Util/Proxy.php b/src/Util/Proxy.php index 82e7db4f5..437b52e1e 100644 --- a/src/Util/Proxy.php +++ b/src/Util/Proxy.php @@ -37,11 +37,20 @@ class Proxy /** * Sizes constants */ - const SIZE_MICRO = 'micro'; - const SIZE_THUMB = 'thumb'; - const SIZE_SMALL = 'small'; - const SIZE_MEDIUM = 'medium'; - const SIZE_LARGE = 'large'; + const SIZE_MICRO = 'micro'; // 48 + const SIZE_THUMB = 'thumb'; // 80 + const SIZE_SMALL = 'small'; // 300 + const SIZE_MEDIUM = 'medium'; // 600 + const SIZE_LARGE = 'large'; // 1024 + + /** + * Pixel Sizes + */ + const PIXEL_MICRO = 48; + const PIXEL_THUMB = 80; + const PIXEL_SMALL = 300; + const PIXEL_MEDIUM = 600; + const PIXEL_LARGE = 1024; /** * Accepted extensions