Show member since in vcard, if enabled

This commit is contained in:
Marcus F. 2026-02-22 21:40:33 +01:00
commit bf2bc053fe
6 changed files with 99 additions and 75 deletions

View file

@ -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,
));
}

View file

@ -146,7 +146,7 @@ class Profile extends BaseProfile
$view_as_contact_alert = $this->t(
'You\'re currently viewing your profile as <b>%s</b> <a href="%s" class="btn btn-sm pull-right">Cancel</a>',
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 '<a href="' . $input . '" target="_blank" rel="noopener noreferrer me">' . $input . '</a>';
} catch (\Throwable $th) {
return '';

View file

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 ""

View file

@ -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;

View file

@ -133,6 +133,13 @@
</div>
{{/if}}
{{if $member_since}}
<p class="member-since">
<strong>{{$member_since.0}}</strong>
<span>{{$member_since.1}}</span>
</p>
{{/if}}
{{if $about}}<dl class="about" style="display:none;">
<dt class="about-label">{{$about}}</dt>
<dd class="x-network">{{$profile.about nofilter}}</dd>

View file

@ -33,6 +33,13 @@
</dl>
{{/if}}
{{if $member_since}}
<p class="member-since">
<strong>{{$member_since.0}}</strong>
<span>{{$member_since.1}}</span>
</p>
{{/if}}
{{if $profile.xmpp}}
<dl class="xmpp">
<dt class="xmpp-label">{{$xmpp}}</dt>