From bf2bc053fe026437b347ca38d3f727d8973a2a67 Mon Sep 17 00:00:00 2001 From: "Marcus F." Date: Sun, 22 Feb 2026 21:40:33 +0100 Subject: [PATCH] Show member since in vcard, if enabled --- src/Model/Profile.php | 31 +++--- src/Module/Profile/Profile.php | 24 ++--- view/lang/C/messages.po | 102 ++++++++++---------- view/theme/frio/css/style.css | 3 + view/theme/frio/templates/profile/vcard.tpl | 7 ++ view/theme/vier/templates/profile/vcard.tpl | 7 ++ 6 files changed, 99 insertions(+), 75 deletions(-) diff --git a/src/Model/Profile.php b/src/Model/Profile.php index 897826ad22..edc5e0c3d1 100644 --- a/src/Model/Profile.php +++ b/src/Model/Profile.php @@ -9,6 +9,7 @@ namespace Friendica\Model; use Friendica\App\Mode; use Friendica\AppHelper; +use Friendica\Content\Feature; use Friendica\Content\Text\BBCode; use Friendica\Content\Widget\ContactBlock; use Friendica\Core\Cache\Enum\Duration; @@ -309,7 +310,7 @@ class Profile } $local_user_is_self = DI::userSession()->getMyUrl() && ($profile['url'] == DI::userSession()->getMyUrl()); - $visitor_is_authenticated = (bool)DI::userSession()->getMyUrl(); + $visitor_is_authenticated = (bool) DI::userSession()->getMyUrl(); $visitor_is_following = in_array($visitor_contact['rel'] ?? 0, [Contact::FOLLOWER, Contact::FRIEND]) || in_array($profile_contact['rel'] ?? 0, [Contact::SHARING, Contact::FRIEND]); $visitor_is_followed = in_array($visitor_contact['rel'] ?? 0, [Contact::SHARING, Contact::FRIEND]) @@ -319,7 +320,7 @@ class Profile if (!$local_user_is_self) { if (!$visitor_is_authenticated) { // Remote follow is only available for local profiles - if (!empty($profile['nickname']) && strpos($profile_url, (string)DI::baseUrl()) === 0) { + if (!empty($profile['nickname']) && strpos($profile_url, (string) DI::baseUrl()) === 0) { $follow_link = 'profile/' . $profile['nickname'] . '/remote_follow'; } } else { @@ -444,12 +445,18 @@ class Profile } $network_url = 'contact/' . $cid . '/conversations'; + $member_since = null; + if (Feature::isEnabled($p['uid'], Feature::MEMBER_SINCE)) { + $member_since = [ DI::l10n()->t('Joined:'), DateTimeFormat::local($p['register_date']) ]; + } + $tpl = Renderer::getMarkupTemplate('profile/vcard.tpl'); $o .= Renderer::replaceMacros($tpl, [ '$profile' => $p, '$picture_dest_url' => $picture_dest_url, '$change_profile_picture_text' => $change_profile_picture_text, '$xmpp' => $xmpp, + '$member_since' => $member_since, '$matrix' => $matrix, '$follow' => DI::l10n()->t('Follow'), '$follow_link' => $follow_link, @@ -542,7 +549,7 @@ class Profile Contact::FRIEND, $uid, DateTimeFormat::utc('now + 6 days'), - DateTimeFormat::utcNow() + DateTimeFormat::utcNow(), ); if (DBA::isResult($result)) { $events = DBA::toArray($result); @@ -585,7 +592,7 @@ class Profile 'id' => $event['id'], 'link' => Contact::magicLinkById($event['cid']), 'title' => $event['name'], - 'date' => DI::l10n()->getDay(DateTimeFormat::local($event['start'], $bd_short)) . (($today) ? ' ' . DI::l10n()->t('[today]') : '') + 'date' => DI::l10n()->getDay(DateTimeFormat::local($event['start'], $bd_short)) . (($today) ? ' ' . DI::l10n()->t('[today]') : ''), ]; } } @@ -598,7 +605,7 @@ class Profile '$event_title' => DI::l10n()->t('Birthdays this week:'), '$events' => $tpl_events, '$lbr' => '{', // raw brackets mess up if/endif macro processing - '$rbr' => '}' + '$rbr' => '}', ]); } @@ -616,7 +623,7 @@ class Profile $condition = [ "`uid` = ? AND `type` != 'birthday' AND `start` < ? AND `start` >= ?", - $uid, DateTimeFormat::utc('now + 7 days'), DateTimeFormat::utc('now - 1 days') + $uid, DateTimeFormat::utc('now + 7 days'), DateTimeFormat::utc('now - 1 days'), ]; $s = DBA::select('event', [], $condition, ['order' => ['start']]); @@ -630,7 +637,7 @@ class Profile $condition = [ 'parent-uri' => $rr['uri'], 'uid' => $rr['uid'], 'author-id' => $pcid, 'vid' => [Verb::getID(Activity::ATTEND), Verb::getID(Activity::ATTENDMAYBE)], - 'visible' => true, 'deleted' => false + 'visible' => true, 'deleted' => false, ]; if (!Post::exists($condition)) { continue; @@ -730,7 +737,7 @@ class Profile (`pub_keywords` LIKE ?) OR (`prv_keywords` LIKE ?))", $searchTerm, $searchTerm, $searchTerm, $searchTerm, - $searchTerm, $searchTerm, $searchTerm, $searchTerm + $searchTerm, $searchTerm, $searchTerm, $searchTerm, ]; } else { $condition = ['verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false]; @@ -772,7 +779,7 @@ class Profile if (!$profile['is-default']) { $contacts = Contact::selectToArray(['id'], [ 'uid' => $profile['uid'], - 'profile-id' => $profile['id'] + 'profile-id' => $profile['id'], ]); if (!count($contacts)) { // No contact visibility selected defaults to user-only permission @@ -783,8 +790,8 @@ class Profile $permissionSet = DI::permissionSet()->selectOrCreate( new PermissionSet( $profile['uid'], - array_column($contacts, 'id') ?? [] - ) + array_column($contacts, 'id') ?? [], + ), ); $order = 1; @@ -819,7 +826,7 @@ class Profile $order, trim($label, ':'), $profile[$field], - $permissionSet + $permissionSet, )); } diff --git a/src/Module/Profile/Profile.php b/src/Module/Profile/Profile.php index 1b562cb888..6aa61a144e 100644 --- a/src/Module/Profile/Profile.php +++ b/src/Module/Profile/Profile.php @@ -146,7 +146,7 @@ class Profile extends BaseProfile $view_as_contact_alert = $this->t( 'You\'re currently viewing your profile as %s Cancel', htmlentities($view_as_contacts[$key]['name'], ENT_COMPAT, 'UTF-8'), - 'profile/' . $this->parameters['nickname'] . '/profile' + 'profile/' . $this->parameters['nickname'] . '/profile', ); } } @@ -183,8 +183,8 @@ class Profile extends BaseProfile if (Feature::isEnabled($profile['uid'], Feature::MEMBER_SINCE)) { $basic_fields += self::buildField( 'membersince', - $this->t('Member since:'), - DateTimeFormat::local($profile['register_date']) + $this->t('Joined:'), + DateTimeFormat::local($profile['register_date']), ); } @@ -193,9 +193,9 @@ class Profile extends BaseProfile $short_bd_format = $this->t('j F'); $dob = $this->l10n->getDay( - intval($profile['dob']) ? - DateTimeFormat::utc($profile['dob'] . ' 00:00 +00:00', $year_bd_format) - : DateTimeFormat::utc('2001-' . substr($profile['dob'], 5) . ' 00:00 +00:00', $short_bd_format) + intval($profile['dob']) + ? DateTimeFormat::utc($profile['dob'] . ' 00:00 +00:00', $year_bd_format) + : DateTimeFormat::utc('2001-' . substr($profile['dob'], 5) . ' 00:00 +00:00', $short_bd_format), ); $basic_fields += self::buildField('dob', $this->t('Birthday:'), $dob); @@ -221,7 +221,7 @@ class Profile extends BaseProfile $basic_fields += self::buildField( 'homepage', $this->t('Homepage:'), - $this->tryRelMe($profile['homepage']) ?: $this->cleanInput($profile['uri-id'], $profile['homepage']) + $this->tryRelMe($profile['homepage']) ?: $this->cleanInput($profile['uri-id'], $profile['homepage']), ); } @@ -264,7 +264,7 @@ class Profile extends BaseProfile 'custom_' . $profile_field->order, $profile_field->label, $this->tryRelMe($profile_field->value) ?: BBCode::convertForUriId($profile['uri-id'], $profile_field->value), - 'aprofile custom' + 'aprofile custom', ); } @@ -273,7 +273,7 @@ class Profile extends BaseProfile $custom_fields += self::buildField( 'group_list', $this->t('Groups:'), - GroupManager::profileAdvanced($profile['uid']) + GroupManager::profileAdvanced($profile['uid']), ); } @@ -296,11 +296,11 @@ class Profile extends BaseProfile '$homepage_verified' => $this->l10n->t('This website has been verified to belong to the same person.'), '$edit_link' => [ 'url' => 'settings/profile', $this->t('Edit profile'), - 'label' => $this->t('Edit profile') + 'label' => $this->t('Edit profile'), ], '$viewas_link' => [ 'url' => $this->args->getQueryString() . '#viewas', - 'label' => $this->t('View as') + 'label' => $this->t('View as'), ], ]); @@ -389,7 +389,7 @@ class Profile extends BaseProfile $input = trim($input); if (Network::isValidHttpUrl($input)) { try { - $input = (string)Uri::fromParts(parse_url($input)); + $input = (string) Uri::fromParts(parse_url($input)); return '' . $input . ''; } catch (\Throwable $th) { return ''; diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index 377a657654..29265ccee6 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2026.04-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-22 12:50+0100\n" +"POT-Creation-Date: 2026-02-22 21:48+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -358,7 +358,7 @@ msgid "Save" msgstr "" #: mod/photos.php:42 mod/photos.php:99 mod/photos.php:328 -#: src/Model/Event.php:503 src/Model/Profile.php:211 +#: src/Model/Event.php:503 src/Model/Profile.php:212 #: src/Module/Calendar/Export.php:60 src/Module/Calendar/Show.php:63 #: src/Module/Feed.php:52 src/Module/HCard.php:37 #: src/Module/Profile/Common.php:50 src/Module/Profile/Common.php:59 @@ -1316,7 +1316,7 @@ msgstr "" #: src/Content/Conversation.php:426 src/Content/Item.php:442 #: src/Content/Widget/VCard.php:120 src/Model/Contact.php:1307 -#: src/Model/Profile.php:460 src/Module/Admin/Logs/View.php:79 +#: src/Model/Profile.php:467 src/Module/Admin/Logs/View.php:79 #: src/Module/Post/Edit.php:179 msgid "Message" msgstr "" @@ -1838,7 +1838,7 @@ msgid "View Photos" msgstr "" #: src/Content/Item.php:440 src/Model/Contact.php:1271 -#: src/Model/Profile.php:443 +#: src/Model/Profile.php:444 msgid "Network Posts" msgstr "" @@ -2437,51 +2437,51 @@ msgid "Show Less" msgstr "" #: src/Content/Widget/VCard.php:94 src/Model/Contact.php:1265 -#: src/Model/Profile.php:437 +#: src/Model/Profile.php:438 msgid "Post to group" msgstr "" #: src/Content/Widget/VCard.php:99 src/Model/Contact.php:1269 -#: src/Model/Profile.php:441 src/Module/Moderation/Item/Source.php:81 +#: src/Model/Profile.php:442 src/Module/Moderation/Item/Source.php:81 msgid "Mention" msgstr "" -#: src/Content/Widget/VCard.php:109 src/Model/Profile.php:356 +#: src/Content/Widget/VCard.php:109 src/Model/Profile.php:357 #: src/Module/Contact/Profile.php:460 src/Module/Profile/Profile.php:213 msgid "XMPP:" msgstr "" -#: src/Content/Widget/VCard.php:110 src/Model/Profile.php:357 +#: src/Content/Widget/VCard.php:110 src/Model/Profile.php:358 #: src/Module/Contact/Profile.php:462 src/Module/Profile/Profile.php:217 msgid "Matrix:" msgstr "" #: src/Content/Widget/VCard.php:111 src/Model/Event.php:68 #: src/Model/Event.php:95 src/Model/Event.php:462 src/Model/Event.php:953 -#: src/Model/Profile.php:351 src/Module/Contact/Profile.php:458 +#: src/Model/Profile.php:352 src/Module/Contact/Profile.php:458 #: src/Module/Directory.php:133 src/Module/Notifications/Introductions.php:187 #: src/Module/Profile/Profile.php:235 msgid "Location:" msgstr "" -#: src/Content/Widget/VCard.php:114 src/Model/Profile.php:467 +#: src/Content/Widget/VCard.php:114 src/Model/Profile.php:474 #: src/Module/Notifications/Introductions.php:201 msgid "Network:" msgstr "" -#: src/Content/Widget/VCard.php:116 src/Model/Profile.php:454 +#: src/Content/Widget/VCard.php:116 src/Model/Profile.php:461 #: src/Module/Contact/Profile.php:529 msgid "Follow" msgstr "" #: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1297 -#: src/Model/Contact.php:1309 src/Model/Profile.php:456 +#: src/Model/Contact.php:1309 src/Model/Profile.php:463 #: src/Module/Contact/Profile.php:521 msgid "Unfollow" msgstr "" #: src/Content/Widget/VCard.php:124 src/Model/Contact.php:1267 -#: src/Model/Profile.php:439 +#: src/Model/Profile.php:440 msgid "View group" msgstr "" @@ -3454,143 +3454,147 @@ msgstr "" msgid "Wall Photos" msgstr "" -#: src/Model/Profile.php:341 src/Module/Settings/Profile/Index.php:273 +#: src/Model/Profile.php:342 src/Module/Settings/Profile/Index.php:273 msgid "Change profile picture" msgstr "" -#: src/Model/Profile.php:354 src/Module/Directory.php:138 +#: src/Model/Profile.php:355 src/Module/Directory.php:138 #: src/Module/Profile/Profile.php:223 msgid "Homepage:" msgstr "" -#: src/Model/Profile.php:355 src/Module/Contact/Profile.php:464 +#: src/Model/Profile.php:356 src/Module/Contact/Profile.php:464 #: src/Module/Notifications/Introductions.php:189 msgid "About:" msgstr "" -#: src/Model/Profile.php:458 +#: src/Model/Profile.php:450 src/Module/Profile/Profile.php:186 +msgid "Joined:" +msgstr "" + +#: src/Model/Profile.php:465 msgid "Atom feed" msgstr "" -#: src/Model/Profile.php:465 src/Module/Profile/Profile.php:296 +#: src/Model/Profile.php:472 src/Module/Profile/Profile.php:296 msgid "This website has been verified to belong to the same person." msgstr "" -#: src/Model/Profile.php:524 +#: src/Model/Profile.php:531 msgid "F d" msgstr "" -#: src/Model/Profile.php:588 src/Model/Profile.php:669 +#: src/Model/Profile.php:595 src/Model/Profile.php:676 msgid "[today]" msgstr "" -#: src/Model/Profile.php:597 +#: src/Model/Profile.php:604 msgid "Birthday Reminders" msgstr "" -#: src/Model/Profile.php:598 +#: src/Model/Profile.php:605 msgid "Birthdays this week:" msgstr "" -#: src/Model/Profile.php:614 +#: src/Model/Profile.php:621 msgid "g A l F d" msgstr "" -#: src/Model/Profile.php:656 +#: src/Model/Profile.php:663 msgid "[No description]" msgstr "" -#: src/Model/Profile.php:682 +#: src/Model/Profile.php:689 msgid "Event Reminders" msgstr "" -#: src/Model/Profile.php:683 +#: src/Model/Profile.php:690 msgid "Upcoming events the next 7 days:" msgstr "" -#: src/Model/Profile.php:793 +#: src/Model/Profile.php:800 msgid "Hometown:" msgstr "" -#: src/Model/Profile.php:794 +#: src/Model/Profile.php:801 msgid "Marital Status:" msgstr "" -#: src/Model/Profile.php:795 +#: src/Model/Profile.php:802 msgid "With:" msgstr "" -#: src/Model/Profile.php:796 +#: src/Model/Profile.php:803 msgid "Since:" msgstr "" -#: src/Model/Profile.php:797 +#: src/Model/Profile.php:804 msgid "Sexual Preference:" msgstr "" -#: src/Model/Profile.php:798 +#: src/Model/Profile.php:805 msgid "Political Views:" msgstr "" -#: src/Model/Profile.php:799 +#: src/Model/Profile.php:806 msgid "Religious Views:" msgstr "" -#: src/Model/Profile.php:800 +#: src/Model/Profile.php:807 msgid "Likes:" msgstr "" -#: src/Model/Profile.php:801 +#: src/Model/Profile.php:808 msgid "Dislikes:" msgstr "" -#: src/Model/Profile.php:802 +#: src/Model/Profile.php:809 msgid "Title/Description:" msgstr "" -#: src/Model/Profile.php:803 src/Module/Admin/Summary.php:208 +#: src/Model/Profile.php:810 src/Module/Admin/Summary.php:208 #: src/Module/Moderation/Report/Create.php:282 #: src/Module/Moderation/Summary.php:65 msgid "Summary" msgstr "" -#: src/Model/Profile.php:804 +#: src/Model/Profile.php:811 msgid "Musical interests" msgstr "" -#: src/Model/Profile.php:805 +#: src/Model/Profile.php:812 msgid "Books, literature" msgstr "" -#: src/Model/Profile.php:806 +#: src/Model/Profile.php:813 msgid "Television" msgstr "" -#: src/Model/Profile.php:807 +#: src/Model/Profile.php:814 msgid "Film/dance/culture/entertainment" msgstr "" -#: src/Model/Profile.php:808 +#: src/Model/Profile.php:815 msgid "Hobbies/Interests" msgstr "" -#: src/Model/Profile.php:809 +#: src/Model/Profile.php:816 msgid "Love/romance" msgstr "" -#: src/Model/Profile.php:810 +#: src/Model/Profile.php:817 msgid "Work/employment" msgstr "" -#: src/Model/Profile.php:811 +#: src/Model/Profile.php:818 msgid "School/education" msgstr "" -#: src/Model/Profile.php:812 +#: src/Model/Profile.php:819 msgid "Contact information and Social Networks" msgstr "" -#: src/Model/Profile.php:860 +#: src/Model/Profile.php:867 #, php-format msgid "Responsible account: %s" msgstr "" @@ -8633,10 +8637,6 @@ msgstr "" msgid "Display name:" msgstr "" -#: src/Module/Profile/Profile.php:186 -msgid "Member since:" -msgstr "" - #: src/Module/Profile/Profile.php:192 msgid "j F, Y" msgstr "" diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index 5fa2c87bbe..8f13cf87c3 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -1306,6 +1306,9 @@ aside .vcard .detail { aside .xmpp, aside .matrix { display: table; } +aside .member-since { + padding-top: 5px; +} aside .vcard .icon { display: table-cell; padding-right: 10px; diff --git a/view/theme/frio/templates/profile/vcard.tpl b/view/theme/frio/templates/profile/vcard.tpl index 865f9a3675..5ebba33d2b 100644 --- a/view/theme/frio/templates/profile/vcard.tpl +++ b/view/theme/frio/templates/profile/vcard.tpl @@ -133,6 +133,13 @@ {{/if}} + {{if $member_since}} +

+ {{$member_since.0}} + {{$member_since.1}} +

+ {{/if}} + {{if $about}} {{/if}} + {{if $member_since}} +

+ {{$member_since.0}} + {{$member_since.1}} +

+ {{/if}} + {{if $profile.xmpp}}
{{$xmpp}}