X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModel%2FContact.php;h=4898ec56783e57368fab52a946457eeacb5f9d1b;hb=2e05dac7dae0a3d028b442a2d5afbd4176a32e99;hp=2e7d4b68b586332b0a31e1a29f1278aa5b3a36c0;hpb=606b0257ffee320419266ecf7a58e3bc1e8a7e62;p=friendica.git diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 2e7d4b68b5..4898ec5678 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -22,6 +22,7 @@ namespace Friendica\Model; use Friendica\App\BaseURL; +use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException; use Friendica\Content\Pager; use Friendica\Content\Text\HTML; use Friendica\Core\Hook; @@ -56,36 +57,6 @@ class Contact const DEFAULT_AVATAR_THUMB = '/images/person-80.jpg'; const DEFAULT_AVATAR_MICRO = '/images/person-48.jpg'; - /** - * @deprecated since version 2019.03 - * @see User::PAGE_FLAGS_NORMAL - */ - const PAGE_NORMAL = User::PAGE_FLAGS_NORMAL; - /** - * @deprecated since version 2019.03 - * @see User::PAGE_FLAGS_SOAPBOX - */ - const PAGE_SOAPBOX = User::PAGE_FLAGS_SOAPBOX; - /** - * @deprecated since version 2019.03 - * @see User::PAGE_FLAGS_COMMUNITY - */ - const PAGE_COMMUNITY = User::PAGE_FLAGS_COMMUNITY; - /** - * @deprecated since version 2019.03 - * @see User::PAGE_FLAGS_FREELOVE - */ - const PAGE_FREELOVE = User::PAGE_FLAGS_FREELOVE; - /** - * @deprecated since version 2019.03 - * @see User::PAGE_FLAGS_BLOG - */ - const PAGE_BLOG = User::PAGE_FLAGS_BLOG; - /** - * @deprecated since version 2019.03 - * @see User::PAGE_FLAGS_PRVGROUP - */ - const PAGE_PRVGROUP = User::PAGE_FLAGS_PRVGROUP; /** * @} */ @@ -653,9 +624,9 @@ class Contact 'nick' => $user['nickname'], 'pubkey' => $user['pubkey'], 'prvkey' => $user['prvkey'], - 'photo' => User::getAvatarUrlForId($user['uid']), - 'thumb' => User::getAvatarUrlForId($user['uid'], Proxy::SIZE_THUMB), - 'micro' => User::getAvatarUrlForId($user['uid'], Proxy::SIZE_MICRO), + 'photo' => User::getAvatarUrl($user), + 'thumb' => User::getAvatarUrl($user, Proxy::SIZE_THUMB), + 'micro' => User::getAvatarUrl($user, Proxy::SIZE_MICRO), 'blocked' => 0, 'pending' => 0, 'url' => DI::baseUrl() . '/profile/' . $user['nickname'], @@ -709,7 +680,7 @@ class Contact return false; } - $fields = ['nickname', 'page-flags', 'account-type', 'prvkey', 'pubkey']; + $fields = ['uid', 'nickname', 'page-flags', 'account-type', 'prvkey', 'pubkey']; $user = DBA::selectFirst('user', $fields, ['uid' => $uid, 'account_expired' => false]); if (!DBA::isResult($user)) { return false; @@ -768,7 +739,7 @@ class Contact $fields['micro'] = self::getDefaultAvatar($fields, Proxy::SIZE_MICRO); } - $fields['avatar'] = User::getAvatarUrlForId($uid); + $fields['avatar'] = User::getAvatarUrl($user); $fields['forum'] = $user['page-flags'] == User::PAGE_FLAGS_COMMUNITY; $fields['prv'] = $user['page-flags'] == User::PAGE_FLAGS_PRVGROUP; $fields['unsearchable'] = !$profile['net-publish']; @@ -795,8 +766,8 @@ class Contact // Update the profile $fields = [ - 'photo' => User::getAvatarUrlForId($uid), - 'thumb' => User::getAvatarUrlForId($uid, Proxy::SIZE_THUMB) + 'photo' => User::getAvatarUrl($user), + 'thumb' => User::getAvatarUrl($user, Proxy::SIZE_THUMB) ]; DBA::update('profile', $fields, ['uid' => $uid]); @@ -823,24 +794,24 @@ class Contact self::update(['archive' => true, 'network' => Protocol::PHANTOM, 'deleted' => true], ['id' => $id]); // Delete it in the background - Worker::add(PRIORITY_MEDIUM, 'RemoveContact', $id); + Worker::add(PRIORITY_MEDIUM, 'Contact\Remove', $id); } /** * Sends an unfriend message. Removes the contact for two-way unfriending or sharing only protocols (feed an mail) * * @param array $user User unfriending - * @param array $contact Contact unfriended + * @param array $contact Contact (uid != 0) unfriended * @param boolean $two_way Revoke eventual inbound follow as well - * @return bool|null true if successful, false if not, null if no action was performed + * @return bool|null true if successful, false if not, null if no remote action was performed * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function terminateFriendship(array $user, array $contact, bool $two_way = false): bool + public static function terminateFriendship(array $user, array $contact): ?bool { - $result = Protocol::terminateFriendship($user, $contact, $two_way); + $result = Protocol::terminateFriendship($user, $contact); - if ($two_way || in_array($contact['network'], [Protocol::FEED, Protocol::MAIL])) { + if ($contact['rel'] == Contact::SHARING || in_array($contact['network'], [Protocol::FEED, Protocol::MAIL])) { self::remove($contact['id']); } else { self::update(['rel' => Contact::FOLLOWER], ['id' => $contact['id']]); @@ -857,7 +828,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function revokeFollow(array $contact): bool + public static function revokeFollow(array $contact): ?bool { if (empty($contact['network'])) { throw new \InvalidArgumentException('Empty network in contact array'); @@ -872,7 +843,11 @@ class 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) { - DBA::update('contact', ['rel' => $contact['rel'] == self::FRIEND ? self::SHARING : self::NOTHING], ['id' => $contact['id']]); + if ($contact['rel'] == self::FRIEND) { + self::update(['rel' => self::SHARING], ['id' => $contact['id']]); + } else { + self::remove($contact['id']); + } } return $result; @@ -994,7 +969,6 @@ class Contact $pm_url = ''; $status_link = ''; $photos_link = ''; - $contact_drop_link = ''; $poke_link = ''; if ($uid == 0) { @@ -1046,10 +1020,6 @@ class Contact $posts_link = DI::baseUrl() . '/contact/' . $contact['id'] . '/conversations'; - if (!$contact['self']) { - $contact_drop_link = DI::baseUrl() . '/contact/' . $contact['id'] . '/drop?confirm=1'; - } - $follow_link = ''; $unfollow_link = ''; if (!$contact['self'] && Protocol::supportsFollow($contact['network'])) { @@ -1060,10 +1030,6 @@ class Contact } } - if (!empty($follow_link) || !empty($unfollow_link)) { - $contact_drop_link = ''; - } - /** * Menu array: * "name" => [ "Label", "link", (bool)Should the link opened in a new tab? ] @@ -1083,7 +1049,6 @@ class Contact 'photos' => [DI::l10n()->t('View Photos') , $photos_link , true], 'network' => [DI::l10n()->t('Network Posts') , $posts_link , false], 'edit' => [DI::l10n()->t('View Contact') , $contact_url , false], - 'drop' => [DI::l10n()->t('Drop Contact') , $contact_drop_link, false], 'pm' => [DI::l10n()->t('Send PM') , $pm_url , false], 'poke' => [DI::l10n()->t('Poke') , $poke_link , false], 'follow' => [DI::l10n()->t('Connect/Follow'), $follow_link , true], @@ -1091,9 +1056,11 @@ class Contact ]; if (!empty($contact['pending'])) { - $intro = DBA::selectFirst('intro', ['id'], ['contact-id' => $contact['id']]); - if (DBA::isResult($intro)) { - $menu['follow'] = [DI::l10n()->t('Approve'), 'notifications/intros/' . $intro['id'], true]; + try { + $intro = DI::intro()->selectForContact($contact['id']); + $menu['follow'] = [DI::l10n()->t('Approve'), 'notifications/intros/' . $intro->id, true]; + } catch (IntroductionNotFoundException $exception) { + DI::logger()->error('Pending contact doesn\'t have an introduction.', ['exception' => $exception]); } } } @@ -1370,12 +1337,13 @@ class Contact * @param bool $thread_mode * @param int $update Update mode * @param int $parent Item parent ID for the update mode + * @param bool $only_media Only display media content * @return string posts in HTML * @throws \Exception */ - public static function getPostsFromUrl($contact_url, $thread_mode = false, $update = 0, $parent = 0) + public static function getPostsFromUrl($contact_url, $thread_mode = false, $update = 0, $parent = 0, bool $only_media = false) { - return self::getPostsFromId(self::getIdForURL($contact_url), $thread_mode, $update, $parent); + return self::getPostsFromId(self::getIdForURL($contact_url), $thread_mode, $update, $parent, $only_media); } /** @@ -1384,14 +1352,13 @@ class Contact * @param int $cid Contact ID * @param bool $thread_mode * @param int $update Update mode - * @param int $parent Item parent ID for the update mode + * @param int $parent Item parent ID for the update mode + * @param bool $only_media Only display media content * @return string posts in HTML * @throws \Exception */ - public static function getPostsFromId($cid, $thread_mode = false, $update = 0, $parent = 0) + public static function getPostsFromId($cid, $thread_mode = false, $update = 0, $parent = 0, bool $only_media = false) { - $a = DI::app(); - $contact = DBA::selectFirst('contact', ['contact-type', 'network'], ['id' => $cid]); if (!DBA::isResult($contact)) { return ''; @@ -1422,6 +1389,11 @@ class Contact } } + if ($only_media) { + $condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))", + Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]); + } + if (DI::mode()->isMobile()) { $itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network', DI::config()->get('system', 'itemspage_network_mobile')); @@ -1551,18 +1523,22 @@ class Contact */ public static function checkAvatarCache(int $cid) { - $contact = DBA::selectFirst('contact', ['url', 'avatar', 'photo', 'thumb', 'micro'], ['id' => $cid, 'uid' => 0, 'self' => false]); + $contact = DBA::selectFirst('contact', ['url', 'network', 'avatar', 'photo', 'thumb', 'micro'], ['id' => $cid, 'uid' => 0, 'self' => false]); if (!DBA::isResult($contact)) { return; } - if (empty($contact['avatar']) || (!empty($contact['photo']) && !empty($contact['thumb']) && !empty($contact['micro']))) { + if (in_array($contact['network'], [Protocol::FEED, Protocol::MAIL]) || DI::config()->get('system', 'cache_contact_avatar')) { + if (!empty($contact['avatar']) && (empty($contact['photo']) || empty($contact['thumb']) || empty($contact['micro']))) { + Logger::info('Adding avatar cache', ['id' => $cid, 'contact' => $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]); + self::updateAvatar($cid, $contact['avatar'], true); return; } - - Logger::info('Adding avatar cache', ['id' => $cid, 'contact' => $contact]); - - self::updateAvatar($cid, $contact['avatar'], true); } /** @@ -1723,19 +1699,22 @@ class Contact * Get avatar link for given contact id * * @param integer $cid contact id - * @param string $size One of the ProxyUtils::SIZE_* constants + * @param string $size One of the Proxy::SIZE_* constants * @param string $updated Contact update date * @return string avatar link */ - public static function getAvatarUrlForId(int $cid, string $size = '', string $updated = ''):string + public static function getAvatarUrlForId(int $cid, string $size = '', string $updated = '', string $guid = ''):string { // We have to fetch the "updated" variable when it wasn't provided // The parameter can be provided to improve performance - if (empty($updated)) { - $contact = self::getById($cid, ['updated']); - $updated = $contact['updated'] ?? ''; + if (empty($updated) || empty($guid)) { + $account = DBA::selectFirst('account-user-view', ['updated', 'guid'], ['id' => $cid]); + $updated = $account['updated'] ?? ''; + $guid = $account['guid'] ?? ''; } + $guid = urlencode($guid); + $url = DI::baseUrl() . '/photo/contact/'; switch ($size) { case Proxy::SIZE_MICRO: @@ -1754,7 +1733,7 @@ class Contact $url .= Proxy::PIXEL_LARGE . '/'; break; } - return $url . $cid . ($updated ? '?ts=' . strtotime($updated) : ''); + return $url . ($guid ?: $cid) . ($updated ? '?ts=' . strtotime($updated) : ''); } /** @@ -1762,7 +1741,7 @@ class Contact * * @param string $url contact url * @param integer $uid user id - * @param string $size One of the ProxyUtils::SIZE_* constants + * @param string $size One of the Proxy::SIZE_* constants * @return string avatar link */ public static function getAvatarUrlForUrl(string $url, int $uid, string $size = ''):string @@ -1777,19 +1756,22 @@ class Contact * Get header link for given contact id * * @param integer $cid contact id - * @param string $size One of the ProxyUtils::SIZE_* constants + * @param string $size One of the Proxy::SIZE_* constants * @param string $updated Contact update date * @return string header link */ - public static function getHeaderUrlForId(int $cid, string $size = '', string $updated = ''):string + public static function getHeaderUrlForId(int $cid, string $size = '', string $updated = '', string $guid = ''):string { // We have to fetch the "updated" variable when it wasn't provided // The parameter can be provided to improve performance - if (empty($updated)) { - $contact = self::getById($cid, ['updated']); - $updated = $contact['updated'] ?? ''; + if (empty($updated) || empty($guid)) { + $account = DBA::selectFirst('account-user-view', ['updated', 'guid'], ['id' => $cid]); + $updated = $account['updated'] ?? ''; + $guid = $account['guid'] ?? ''; } + $guid = urlencode($guid); + $url = DI::baseUrl() . '/photo/header/'; switch ($size) { case Proxy::SIZE_MICRO: @@ -1809,7 +1791,7 @@ class Contact break; } - return $url . $cid . ($updated ? '?ts=' . strtotime($updated) : ''); + return $url . ($guid ?: $cid) . ($updated ? '?ts=' . strtotime($updated) : ''); } /** @@ -1860,54 +1842,61 @@ class Contact $avatar = self::getDefaultAvatar($contact, Proxy::SIZE_SMALL); } - if ($default_avatar && Proxy::isLocalImage($avatar)) { - $fields = ['avatar' => $avatar, 'avatar-date' => DateTimeFormat::utcNow(), - 'photo' => $avatar, - 'thumb' => self::getDefaultAvatar($contact, Proxy::SIZE_THUMB), - 'micro' => self::getDefaultAvatar($contact, Proxy::SIZE_MICRO)]; - Logger::debug('Use default avatar', ['id' => $cid, 'uid' => $uid]); - } + if (in_array($contact['network'], [Protocol::FEED, Protocol::MAIL]) || DI::config()->get('system', 'cache_contact_avatar')) { + if ($default_avatar && Proxy::isLocalImage($avatar)) { + $fields = ['avatar' => $avatar, 'avatar-date' => DateTimeFormat::utcNow(), + 'photo' => $avatar, + 'thumb' => self::getDefaultAvatar($contact, Proxy::SIZE_THUMB), + 'micro' => self::getDefaultAvatar($contact, Proxy::SIZE_MICRO)]; + Logger::debug('Use default avatar', ['id' => $cid, 'uid' => $uid]); + } - // Use the data from the self account - if (empty($fields)) { - $local_uid = User::getIdForURL($contact['url']); - if (!empty($local_uid)) { - $fields = self::selectFirst(['avatar', 'avatar-date', 'photo', 'thumb', 'micro'], ['self' => true, 'uid' => $local_uid]); - Logger::debug('Use owner data', ['id' => $cid, 'uid' => $uid, 'owner-uid' => $local_uid]); + // Use the data from the self account + if (empty($fields)) { + $local_uid = User::getIdForURL($contact['url']); + if (!empty($local_uid)) { + $fields = self::selectFirst(['avatar', 'avatar-date', 'photo', 'thumb', 'micro'], ['self' => true, 'uid' => $local_uid]); + Logger::debug('Use owner data', ['id' => $cid, 'uid' => $uid, 'owner-uid' => $local_uid]); + } } - } - if (empty($fields)) { - $update = ($contact['avatar'] != $avatar) || $force; - - if (!$update) { - $data = [ - $contact['photo'] ?? '', - $contact['thumb'] ?? '', - $contact['micro'] ?? '', - ]; - - foreach ($data as $image_uri) { - $image_rid = Photo::ridFromURI($image_uri); - if ($image_rid && !Photo::exists(['resource-id' => $image_rid, 'uid' => $uid])) { - Logger::debug('Regenerating avatar', ['contact uid' => $uid, 'cid' => $cid, 'missing photo' => $image_rid, 'avatar' => $contact['avatar']]); - $update = true; + if (empty($fields)) { + $update = ($contact['avatar'] != $avatar) || $force; + + if (!$update) { + $data = [ + $contact['photo'] ?? '', + $contact['thumb'] ?? '', + $contact['micro'] ?? '', + ]; + + foreach ($data as $image_uri) { + $image_rid = Photo::ridFromURI($image_uri); + if ($image_rid && !Photo::exists(['resource-id' => $image_rid, 'uid' => $uid])) { + Logger::debug('Regenerating avatar', ['contact uid' => $uid, 'cid' => $cid, 'missing photo' => $image_rid, 'avatar' => $contact['avatar']]); + $update = true; + } } } - } - if ($update) { - $photos = Photo::importProfilePhoto($avatar, $uid, $cid, true); - if ($photos) { - $fields = ['avatar' => $avatar, 'photo' => $photos[0], 'thumb' => $photos[1], 'micro' => $photos[2], 'avatar-date' => DateTimeFormat::utcNow()]; - $update = !empty($fields); - Logger::debug('Created new cached avatars', ['id' => $cid, 'uid' => $uid, 'owner-uid' => $local_uid]); - } else { - $update = false; + if ($update) { + $photos = Photo::importProfilePhoto($avatar, $uid, $cid, true); + if ($photos) { + $fields = ['avatar' => $avatar, 'photo' => $photos[0], 'thumb' => $photos[1], 'micro' => $photos[2], 'avatar-date' => DateTimeFormat::utcNow()]; + $update = !empty($fields); + Logger::debug('Created new cached avatars', ['id' => $cid, 'uid' => $uid, 'owner-uid' => $local_uid]); + } else { + $update = false; + } } + } else { + $update = ($fields['photo'] . $fields['thumb'] . $fields['micro'] != $contact['photo'] . $contact['thumb'] . $contact['micro']) || $force; } } else { - $update = ($fields['photo'] . $fields['thumb'] . $fields['micro'] != $contact['photo'] . $contact['thumb'] . $contact['micro']) || $force; + 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; } if (!$update) { @@ -1928,7 +1917,7 @@ class Contact if (!empty($cids)) { // Delete possibly existing cached user contact avatars - Photo::delete(['uid' => $uids, 'contact-id' => $cids, 'album' => Photo::CONTACT_PHOTOS]); + Photo::delete(['uid' => $uids, 'contact-id' => $cids, 'photo-type' => Photo::CONTACT_AVATAR]); } } @@ -2185,7 +2174,7 @@ class Contact } $update = false; - $guid = $ret['guid'] ?? ''; + $guid = ($ret['guid'] ?? '') ?: Item::guidFromUri($ret['url'], parse_url($ret['url'], PHP_URL_HOST)); // make sure to not overwrite existing values with blank entries except some technical fields $keep = ['batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'baseurl']; @@ -2213,6 +2202,8 @@ class Contact self::updateAvatar($id, $ret['photo'], $update); } + $uriid = ItemURI::insert(['uri' => $ret['url'], 'guid' => $guid]); + if (!$update) { self::updateContact($id, $uid, $contact['url'], $ret['url'], ['failed' => false, 'last-update' => $updated, 'success_update' => $updated]); @@ -2231,12 +2222,7 @@ class Contact return true; } - if (empty($guid)) { - $ret['uri-id'] = ItemURI::getIdByURI($ret['url']); - } else { - $ret['uri-id'] = ItemURI::insert(['uri' => $ret['url'], 'guid' => $guid]); - } - + $ret['uri-id'] = $uriid; $ret['nurl'] = Strings::normaliseLink($ret['url']); $ret['updated'] = $updated; $ret['failed'] = false; @@ -2393,7 +2379,7 @@ class Contact } if (($network != '') && ($ret['network'] != $network)) { - Logger::log('Expected network ' . $network . ' does not match actual network ' . $ret['network']); + Logger::notice('Expected network ' . $network . ' does not match actual network ' . $ret['network']); return $result; } @@ -2460,7 +2446,7 @@ class Contact if (DBA::isResult($contact)) { // update contact - $new_relation = (($contact['rel'] == self::FOLLOWER) ? self::FRIEND : self::SHARING); + $new_relation = (in_array($contact['rel'], [self::FOLLOWER, self::FRIEND]) ? self::FRIEND : self::SHARING); $fields = ['rel' => $new_relation, 'subhub' => $subhub, 'readonly' => false]; self::update($fields, ['id' => $contact['id']]); @@ -2506,7 +2492,7 @@ class Contact $contact_id = $contact['id']; $result['cid'] = $contact_id; - Group::addMember(User::getDefaultGroup($uid, $contact["network"]), $contact_id); + Group::addMember(User::getDefaultGroup($uid), $contact_id); // Update the avatar self::updateAvatar($contact_id, $ret['photo']); @@ -2522,103 +2508,11 @@ class Contact Worker::add(PRIORITY_HIGH, 'UpdateContact', $contact_id); } - $owner = User::getOwnerDataById($uid); - - if (DBA::isResult($owner)) { - if (in_array($protocol, [Protocol::OSTATUS, Protocol::DFRN])) { - // create a follow slap - $item = []; - $item['verb'] = Activity::FOLLOW; - $item['gravity'] = GRAVITY_ACTIVITY; - $item['follow'] = $contact["url"]; - $item['body'] = ''; - $item['title'] = ''; - $item['guid'] = ''; - $item['uri-id'] = 0; - - $slap = OStatus::salmon($item, $owner); + $result['success'] = Protocol::follow($uid, $contact, $protocol); - if (!empty($contact['notify'])) { - Salmon::slapper($owner, $contact['notify'], $slap); - } - } elseif ($protocol == Protocol::DIASPORA) { - $ret = Diaspora::sendShare($owner, $contact); - Logger::log('share returns: ' . $ret); - } elseif ($protocol == Protocol::ACTIVITYPUB) { - $activity_id = ActivityPub\Transmitter::activityIDFromContact($contact_id); - if (empty($activity_id)) { - // This really should never happen - return false; - } - - $ret = ActivityPub\Transmitter::sendActivity('Follow', $contact['url'], $uid, $activity_id); - Logger::log('Follow returns: ' . $ret); - } - } - - $result['success'] = true; return $result; } - /** - * Updated contact's SSL policy - * - * @param array $contact Contact array - * @param string $new_policy New policy, valid: self,full - * - * @return array Contact array with updated values - * @throws \Exception - */ - public static function updateSslPolicy(array $contact, $new_policy) - { - $ssl_changed = false; - if ((intval($new_policy) == BaseURL::SSL_POLICY_SELFSIGN || $new_policy === 'self') && strstr($contact['url'], 'https:')) { - $ssl_changed = true; - $contact['url'] = str_replace('https:', 'http:', $contact['url']); - $contact['request'] = str_replace('https:', 'http:', $contact['request']); - $contact['notify'] = str_replace('https:', 'http:', $contact['notify']); - $contact['poll'] = str_replace('https:', 'http:', $contact['poll']); - $contact['confirm'] = str_replace('https:', 'http:', $contact['confirm']); - $contact['poco'] = str_replace('https:', 'http:', $contact['poco']); - } - - if ((intval($new_policy) == BaseURL::SSL_POLICY_FULL || $new_policy === 'full') && strstr($contact['url'], 'http:')) { - $ssl_changed = true; - $contact['url'] = str_replace('http:', 'https:', $contact['url']); - $contact['request'] = str_replace('http:', 'https:', $contact['request']); - $contact['notify'] = str_replace('http:', 'https:', $contact['notify']); - $contact['poll'] = str_replace('http:', 'https:', $contact['poll']); - $contact['confirm'] = str_replace('http:', 'https:', $contact['confirm']); - $contact['poco'] = str_replace('http:', 'https:', $contact['poco']); - } - - if ($ssl_changed) { - $fields = ['url' => $contact['url'], 'request' => $contact['request'], - 'notify' => $contact['notify'], 'poll' => $contact['poll'], - 'confirm' => $contact['confirm'], 'poco' => $contact['poco']]; - self::update($fields, ['id' => $contact['id']]); - } - - return $contact; - } - - /** - * Follow a contact - * - * @param int $cid Public contact id - * @param int $uid User ID - * - * @return bool "true" if following had been successful - */ - public static function follow(int $cid, int $uid) - { - $contact = self::getById($cid, ['url']); - - $result = self::createFromProbeForUser($uid, $contact['url']); - - return $result['cid']; - } - /** * Unfollow a contact * @@ -2706,13 +2600,13 @@ class Contact // Ensure to always have the correct network type, independent from the connection request method self::updateFromProbe($contact['id']); - Post\UserNotification::insertNotication($contact['id'], Verb::getID(Activity::FOLLOW), $importer['uid']); + Post\UserNotification::insertNotification($contact['id'], Activity::FOLLOW, $importer['uid']); return true; } else { // send email notification to owner? if (DBA::exists('contact', ['nurl' => Strings::normaliseLink($url), 'uid' => $importer['uid'], 'pending' => true])) { - Logger::log('ignoring duplicated connection request from pending contact ' . $url); + Logger::notice('ignoring duplicated connection request from pending contact ' . $url); return null; } @@ -2737,7 +2631,7 @@ class Contact self::updateAvatar($contact_id, $photo, true); - Post\UserNotification::insertNotication($contact_id, Verb::getID(Activity::FOLLOW), $importer['uid']); + Post\UserNotification::insertNotification($contact_id, Activity::FOLLOW, $importer['uid']); $contact_record = DBA::selectFirst('contact', ['id', 'network', 'name', 'url', 'photo'], ['id' => $contact_id]); @@ -2746,20 +2640,21 @@ class Contact $user = DBA::selectFirst('user', $fields, ['uid' => $importer['uid']]); if (DBA::isResult($user) && !in_array($user['page-flags'], [User::PAGE_FLAGS_SOAPBOX, User::PAGE_FLAGS_FREELOVE, User::PAGE_FLAGS_COMMUNITY])) { // create notification - $hash = Strings::getRandomHex(); - if (is_array($contact_record)) { - DBA::insert('intro', ['uid' => $importer['uid'], 'contact-id' => $contact_record['id'], - 'blocked' => false, 'knowyou' => false, 'note' => $note, - 'hash' => $hash, 'datetime' => DateTimeFormat::utcNow()]); + $intro = DI::introFactory()->createNew( + $importer['uid'], + $contact_record['id'], + $note + ); + DI::intro()->save($intro); } - Group::addMember(User::getDefaultGroup($importer['uid'], $contact_record["network"]), $contact_record['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])) { - notification([ + DI::notify()->createFromArray([ 'type' => Notification\Type::INTRO, 'otype' => Notification\ObjectType::INTRO, 'verb' => ($sharing ? Activity::FRIEND : Activity::FOLLOW), @@ -2831,7 +2726,7 @@ class Contact $contacts = DBA::select('contact', ['id', 'uid', 'name', 'url', 'bd'], $condition); while ($contact = DBA::fetch($contacts)) { - Logger::log('update_contact_birthday: ' . $contact['bd']); + Logger::notice('update_contact_birthday: ' . $contact['bd']); $nextbd = DateTimeFormat::utcNow('Y') . substr($contact['bd'], 4); @@ -3011,37 +2906,33 @@ class Contact } // check supported networks + $networks = [Protocol::DFRN, Protocol::ACTIVITYPUB]; if (DI::config()->get('system', 'diaspora_enabled')) { - $diaspora = Protocol::DIASPORA; - } else { - $diaspora = Protocol::DFRN; + $networks[] = Protocol::DIASPORA; } if (!DI::config()->get('system', 'ostatus_disabled')) { - $ostatus = Protocol::OSTATUS; - } else { - $ostatus = Protocol::DFRN; + $networks[] = Protocol::OSTATUS; + } + + $condition = ['network' => $networks, 'failed' => false, 'deleted' => false, 'uid' => $uid]; + + if ($uid == 0) { + $condition['blocked'] = false; } // check if we search only communities or every contact if ($mode === 'community') { - $extra_sql = sprintf(' AND `contact-type` = %d', self::TYPE_COMMUNITY); - } else { - $extra_sql = ''; + $condition['contact-type'] = self::TYPE_COMMUNITY; } $search .= '%'; - $results = DBA::p("SELECT * FROM `contact` - WHERE (NOT `unsearchable` OR `nurl` IN (SELECT `nurl` FROM `owner-view` where `publish` OR `net-publish`)) - AND `network` IN (?, ?, ?, ?) AND - NOT `failed` AND `uid` = ? AND - (`addr` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?) $extra_sql - ORDER BY `nurl` DESC LIMIT 1000", - Protocol::DFRN, Protocol::ACTIVITYPUB, $ostatus, $diaspora, $uid, $search, $search, $search - ); + $condition = DBA::mergeConditions($condition, + ["(NOT `unsearchable` OR `nurl` IN (SELECT `nurl` FROM `owner-view` WHERE `publish` OR `net-publish`)) + AND (`addr` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?)", $search, $search, $search]); - $contacts = DBA::toArray($results); + $contacts = self::selectToArray([], $condition); return $contacts; }