]> git.mxchange.org Git - friendica.git/blobdiff - src/Model/Contact.php
Use a constant for the avatar base path
[friendica.git] / src / Model / Contact.php
index 2c88e798dec792550100aab4dbfc0e05a4d0b42d..6a982869944de165d48124dc962040f7131e0291 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Model;
 
-use Friendica\App\BaseURL;
+use Friendica\Contact\Avatar;
 use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException;
 use Friendica\Content\Pager;
 use Friendica\Content\Text\HTML;
@@ -38,6 +38,7 @@ use Friendica\DI;
 use Friendica\Network\HTTPException;
 use Friendica\Network\Probe;
 use Friendica\Protocol\Activity;
+use Friendica\Protocol\ActivityPub;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Images;
 use Friendica\Util\Network;
@@ -796,7 +797,7 @@ class Contact
        public static function remove($id)
        {
                // We want just to make sure that we don't delete our "self" contact
-               $contact = DBA::selectFirst('contact', ['uid'], ['id' => $id, 'self' => false]);
+               $contact = DBA::selectFirst('contact', ['uri-id', 'photo', 'thumb', 'micro'], ['id' => $id, 'self' => false]);
                if (!DBA::isResult($contact)) {
                        return;
                }
@@ -804,6 +805,10 @@ class Contact
                // Archive the contact
                self::update(['archive' => true, 'network' => Protocol::PHANTOM, 'deleted' => true], ['id' => $id]);
 
+               if (!DBA::exists('contact', ['uri-id' => $contact['uri-id'], 'deleted' => false])) {
+                       Avatar::deleteCache($contact);
+               }
+
                // Delete it in the background
                Worker::add(PRIORITY_MEDIUM, 'Contact\Remove', $id);
        }
@@ -826,8 +831,10 @@ class Contact
                }
 
                if (in_array($contact['rel'], [self::SHARING, self::FRIEND])) {
-                       $cdata = Contact::getPublicAndUserContactID($contact['id'], $contact['uid']);
-                       Worker::add(PRIORITY_HIGH, 'Contact\Unfollow', $cdata['public'], $contact['uid']);
+                       $cdata = self::getPublicAndUserContactID($contact['id'], $contact['uid']);
+                       if (!empty($cdata['public'])) {
+                               Worker::add(PRIORITY_HIGH, 'Contact\Unfollow', $cdata['public'], $contact['uid']);
+                       }
                }
 
                self::removeSharer($contact);
@@ -853,8 +860,10 @@ class Contact
                }
 
                if (in_array($contact['rel'], [self::FOLLOWER, self::FRIEND])) {
-                       $cdata = Contact::getPublicAndUserContactID($contact['id'], $contact['uid']);
-                       Worker::add(PRIORITY_HIGH, 'Contact\RevokeFollow', $cdata['public'], $contact['uid']);
+                       $cdata = self::getPublicAndUserContactID($contact['id'], $contact['uid']);
+                       if (!empty($cdata['public'])) {
+                               Worker::add(PRIORITY_HIGH, 'Contact\RevokeFollow', $cdata['public'], $contact['uid']);
+                       }
                }
 
                self::removeFollower($contact);
@@ -877,13 +886,13 @@ class Contact
                        throw new \InvalidArgumentException('Unexpected public contact record');
                }
 
-               $cdata = Contact::getPublicAndUserContactID($contact['id'], $contact['uid']);
+               $cdata = self::getPublicAndUserContactID($contact['id'], $contact['uid']);
 
-               if (in_array($contact['rel'], [self::SHARING, self::FRIEND])) {
+               if (in_array($contact['rel'], [self::SHARING, self::FRIEND]) && !empty($cdata['public'])) {
                        Worker::add(PRIORITY_HIGH, 'Contact\Unfollow', $cdata['public'], $contact['uid']);
                }
 
-               if (in_array($contact['rel'], [self::FOLLOWER, self::FRIEND])) {
+               if (in_array($contact['rel'], [self::FOLLOWER, self::FRIEND]) && !empty($cdata['public'])) {
                        Worker::add(PRIORITY_HIGH, 'Contact\RevokeFollow', $cdata['public'], $contact['uid']);
                }
 
@@ -1455,11 +1464,31 @@ class Contact
                }
 
                if ($thread_mode) {
-                       $items = Post::toArray(Post::selectForUser(local_user(), ['uri-id', 'gravity', 'parent-uri-id', 'thr-parent-id', 'author-id'], $condition, $params));
+                       $fields = ['uri-id', 'thr-parent-id', 'gravity', 'author-id', 'commented'];
+                       $items = Post::toArray(Post::selectForUser(local_user(), $fields, $condition, $params));
+
+                       if ($pager->getStart() == 0) {
+                               $cdata = self::getPublicAndUserContactID($cid, local_user());
+                               if (!empty($cdata['public'])) {
+                                       $pinned = Post\Collection::selectToArrayForContact($cdata['public'], Post\Collection::FEATURED, $fields);
+                                       $items = array_merge($items, $pinned);
+                               }
+                       }
 
-                       $o .= DI::conversation()->create($items, 'contacts', $update, false, 'commented', local_user());
+                       $o .= DI::conversation()->create($items, 'contacts', $update, false, 'pinned_commented', local_user());
                } else {
-                       $items = Post::toArray(Post::selectForUser(local_user(), Item::DISPLAY_FIELDLIST, $condition, $params));
+                       $fields = array_merge(Item::DISPLAY_FIELDLIST, ['featured']);
+                       $items = Post::toArray(Post::selectForUser(local_user(), $fields, $condition, $params));
+
+                       if ($pager->getStart() == 0) {
+                               $cdata = self::getPublicAndUserContactID($cid, local_user());
+                               if (!empty($cdata['public'])) {
+                                       $condition = ["`uri-id` IN (SELECT `uri-id` FROM `collection-view` WHERE `cid` = ? AND `type` = ?)",
+                                               $cdata['public'], Post\Collection::FEATURED];
+                                       $pinned = Post::toArray(Post::selectForUser(local_user(), $fields, $condition, $params));
+                                       $items = array_merge($pinned, $items);
+                               }
+                       }
 
                        $o .= DI::conversation()->create($items, 'contact-posts', $update);
                }
@@ -1552,10 +1581,14 @@ class Contact
                                self::updateAvatar($cid, $contact['avatar'], true);
                                return;
                        }
-               } elseif (!empty($contact['photo']) || !empty($contact['thumb']) || !empty($contact['micro'])) {
-                       Logger::info('Removing avatar cache', ['id' => $cid, 'contact' => $contact]);
+               } elseif (Photo::isPhotoURI($contact['photo']) || Photo::isPhotoURI($contact['thumb']) || Photo::isPhotoURI($contact['micro'])) {
+                       Logger::info('Replacing legacy avatar cache', ['id' => $cid, 'contact' => $contact]);
                        self::updateAvatar($cid, $contact['avatar'], true);
                        return;
+               } elseif (DI::config()->get('system', 'avatar_cache') && (empty($contact['photo']) || empty($contact['thumb']) || empty($contact['micro']))) {
+                       Logger::info('Adding avatar cache file', ['id' => $cid, 'contact' => $contact]);
+                       self::updateAvatar($cid, $contact['avatar'], true);
+               return;
                }
        }
 
@@ -1572,6 +1605,27 @@ class Contact
        private static function getAvatarPath(array $contact, string $size, $no_update = false)
        {
                $contact = self::checkAvatarCacheByArray($contact, $no_update);
+
+               if (DI::config()->get('system', 'avatar_cache')) {
+                       switch ($size) {
+                               case Proxy::SIZE_MICRO:
+                                       if (!empty($contact['micro']) && !Photo::isPhotoURI($contact['micro'])) {
+                                               return $contact['micro'];
+                                       }
+                                       break;
+                               case Proxy::SIZE_THUMB:
+                                       if (!empty($contact['thumb']) && !Photo::isPhotoURI($contact['thumb'])) {
+                                               return $contact['thumb'];
+                                       }
+                                       break;
+                               case Proxy::SIZE_SMALL:
+                                       if (!empty($contact['photo']) && !Photo::isPhotoURI($contact['photo'])) {
+                                               return $contact['photo'];
+                                       }
+                                       break;
+                       }
+               }
+
                return self::getAvatarUrlForId($contact['id'], $size, $contact['updated'] ?? '');
        }
 
@@ -1778,7 +1832,7 @@ class Contact
        {
                // We have to fetch the "updated" variable when it wasn't provided
                // The parameter can be provided to improve performance
-               if (empty($updated) || empty($guid)) {
+               if (empty($updated)) {
                        $account = DBA::selectFirst('account-user-view', ['updated', 'guid'], ['id' => $cid]);
                        $updated = $account['updated'] ?? '';
                        $guid = $account['guid'] ?? '';
@@ -1880,7 +1934,7 @@ class Contact
         */
        public static function updateAvatar(int $cid, string $avatar, bool $force = false, bool $create_cache = false)
        {
-               $contact = DBA::selectFirst('contact', ['uid', 'avatar', 'photo', 'thumb', 'micro', 'xmpp', 'addr', 'nurl', 'url', 'network'],
+               $contact = DBA::selectFirst('contact', ['uid', 'avatar', 'photo', 'thumb', 'micro', 'xmpp', 'addr', 'nurl', 'url', 'network', 'uri-id'],
                        ['id' => $cid, 'self' => false]);
                if (!DBA::isResult($contact)) {
                        return;
@@ -1921,6 +1975,8 @@ class Contact
                }
 
                if (in_array($contact['network'], [Protocol::FEED, Protocol::MAIL]) || $cache_avatar) {
+                       Avatar::deleteCache($contact);
+
                        if ($default_avatar && Proxy::isLocalImage($avatar)) {
                                $fields = ['avatar' => $avatar, 'avatar-date' => DateTimeFormat::utcNow(),
                                        'photo' => $avatar,
@@ -1972,9 +2028,8 @@ class Contact
                        }
                } else {
                        Photo::delete(['uid' => $uid, 'contact-id' => $cid, 'photo-type' => Photo::CONTACT_AVATAR]);
-                       $fields = ['avatar' => $avatar, 'avatar-date' => DateTimeFormat::utcNow(),
-                               'photo' => '', 'thumb' => '', 'micro' => ''];
-                       $update = ($avatar != $contact['avatar'] . $contact['photo'] . $contact['thumb'] . $contact['micro']) || $force;
+                       $fields = Avatar::fetchAvatarContact($contact, $avatar);
+                       $update = ($avatar . $fields['photo'] . $fields['thumb'] . $fields['micro'] != $contact['avatar'] . $contact['photo'] . $contact['thumb'] . $contact['micro']) || $force;
                }
 
                if (!$update) {
@@ -2252,6 +2307,10 @@ class Contact
                $new_pubkey = $ret['pubkey'] ?? '';
 
                if ($uid == 0) {
+                       if ($ret['network'] == Protocol::ACTIVITYPUB) {
+                               ActivityPub\Processor::fetchFeaturedPosts($ret['url']);
+                       }
+       
                        $ret['last-item'] = Probe::getLastUpdate($ret);
                        Logger::info('Fetched last item', ['id' => $id, 'probed_url' => $ret['url'], 'last-item' => $ret['last-item'], 'callstack' => System::callstack(20)]);
                }
@@ -2757,9 +2816,10 @@ class Contact
                        self::remove($contact['id']);
                } else {
                        DI::logger()->info('Couldn\'t remove follower because of invalid contact array', ['contact' => $contact, 'callstack' => System::callstack()]);
+                       return;
                }
 
-               $cdata = Contact::getPublicAndUserContactID($contact['id'], $contact['uid']);
+               $cdata = self::getPublicAndUserContactID($contact['id'], $contact['uid']);
 
                DI::notification()->deleteForUserByVerb($contact['uid'], Activity::FOLLOW, ['actor-id' => $cdata['public']]);
        }