use Friendica\Network\Probe;
use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub;
-use Friendica\Protocol\Diaspora;
-use Friendica\Protocol\OStatus;
-use Friendica\Protocol\Salmon;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images;
use Friendica\Util\Network;
/**
* 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
+ * The local relationship is updated immediately, the eventual remote server is messaged in the background.
+ *
+ * @param array $contact User-specific contact array (uid != 0) to revoke the follow from
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
- public static function revokeFollow(array $contact): ?bool
+ public static function revokeFollow(array $contact): void
{
if (empty($contact['network'])) {
throw new \InvalidArgumentException('Empty network in contact array');
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) {
- if ($contact['rel'] == self::FRIEND) {
- self::update(['rel' => self::SHARING], ['id' => $contact['id']]);
- } else {
- self::remove($contact['id']);
- }
+ 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']);
}
- return $result;
+ self::removeFollower($contact);
}
/**
}
if ($thread_mode) {
- $items = Post::toArray(Post::selectForUser(local_user(), ['uri-id', 'gravity', 'parent-uri-id', 'thr-parent-id', 'author-id'], $condition, $params));
+ $items = Post::toArray(Post::selectForUser(local_user(), ['uri-id'], $condition, $params));
+
+ if ($pager->getStart() == 0) {
+ $cdata = Contact::getPublicAndUserContactID($cid, local_user());
+ if (!empty($cdata['public'])) {
+ $pinned = Post\Collection::selectToArrayForContact($cdata['public'], Post\Collection::FEATURED, ['uri-id']);
+ $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 = Contact::getPublicAndUserContactID($cid, local_user());
+ if (!empty($cdata['public'])) {
+ $condition = ["`uri-id` IN (SELECT `uri-id` FROM `collection-view` WHERE `cid` = ?)", $cdata['public']];
+ $pinned = Post::toArray(Post::selectForUser(local_user(), $fields, $condition, $params));
+ $items = array_merge($pinned, $items);
+ }
+ }
$o .= DI::conversation()->create($items, 'contact-posts', $update);
}
$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)]);
}
return false;
}
- $fields = ['url', 'name', 'nick', 'avatar', 'photo', 'network', 'blocked'];
+ $fields = ['id', 'url', 'name', 'nick', 'avatar', 'photo', 'network', 'blocked'];
$pub_contact = DBA::selectFirst('contact', $fields, ['id' => $datarray['author-id']]);
if (!DBA::isResult($pub_contact)) {
// Should never happen
// Ensure to always have the correct network type, independent from the connection request method
self::updateFromProbe($contact['id']);
- Post\UserNotification::insertNotification($contact['id'], Activity::FOLLOW, $importer['uid']);
+ Post\UserNotification::insertNotification($pub_contact['id'], Activity::FOLLOW, $importer['uid']);
return true;
} else {
self::updateAvatar($contact_id, $photo, true);
- Post\UserNotification::insertNotification($contact_id, Activity::FOLLOW, $importer['uid']);
+ Post\UserNotification::insertNotification($pub_contact['id'], Activity::FOLLOW, $importer['uid']);
$contact_record = DBA::selectFirst('contact', ['id', 'network', 'name', 'url', 'photo'], ['id' => $contact_id]);
Group::addMember(User::getDefaultGroup($importer['uid']), $contact_record['id']);
- if (($user['notify-flags'] & Notification\Type::INTRO) &&
- in_array($user['page-flags'], [User::PAGE_FLAGS_NORMAL])) {
-
+ if (($user['notify-flags'] & Notification\Type::INTRO) && $user['page-flags'] == User::PAGE_FLAGS_NORMAL) {
DI::notify()->createFromArray([
'type' => Notification\Type::INTRO,
'otype' => Notification\ObjectType::INTRO,
return null;
}
+ /**
+ * Update the local relationship when a local user loses a follower
+ *
+ * @param array $contact User-specific contact (uid != 0) array
+ * @throws HTTPException\InternalServerErrorException
+ * @throws \ImagickException
+ */
public static function removeFollower(array $contact)
{
if (in_array($contact['rel'] ?? [], [self::FRIEND, self::SHARING])) {
} else {
DI::logger()->info('Couldn\'t remove follower because of invalid contact array', ['contact' => $contact, 'callstack' => System::callstack()]);
}
+
+ $cdata = Contact::getPublicAndUserContactID($contact['id'], $contact['uid']);
+
+ DI::notification()->deleteForUserByVerb($contact['uid'], Activity::FOLLOW, ['actor-id' => $cdata['public']]);
}
/**