From 4c3f2441f7966fad09663090141b7ee4b17d7b91 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 18 Jun 2023 16:49:38 +0000 Subject: [PATCH] Display the contact alias if the URL is no HTTP link --- mod/photos.php | 100 +++++----- src/Content/Conversation.php | 60 ++++-- src/Content/GroupManager.php | 3 +- src/Content/Item.php | 21 +- src/Content/Text/HTML.php | 15 +- src/Content/Widget.php | 15 +- src/Content/Widget/ContactBlock.php | 2 +- src/Content/Widget/VCard.php | 17 +- src/Model/Contact.php | 181 ++++++++++------- src/Model/Event.php | 25 ++- src/Model/Item.php | 289 +++++++++++++++++----------- src/Module/Contact.php | 52 +++-- src/Module/Contact/Unfollow.php | 2 +- src/Object/Post.php | 39 ++-- static/dbstructure.config.php | 2 +- static/dbview.config.php | 8 + 16 files changed, 528 insertions(+), 303 deletions(-) diff --git a/mod/photos.php b/mod/photos.php index 233d28a5e7..1b9120576d 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -117,7 +117,7 @@ function photos_init(App $a) $tpl = Renderer::getMarkupTemplate("photos_head.tpl"); - DI::page()['htmlhead'] .= Renderer::replaceMacros($tpl,[ + DI::page()['htmlhead'] .= Renderer::replaceMacros($tpl, [ '$ispublic' => DI::l10n()->t('everybody') ]); } @@ -214,13 +214,15 @@ function photos_post(App $a) // get the list of photos we are about to delete if ($visitor) { - $r = DBA::toArray(DBA::p("SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `contact-id` = ? AND `uid` = ? AND `album` = ?", + $r = DBA::toArray(DBA::p( + "SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `contact-id` = ? AND `uid` = ? AND `album` = ?", $visitor, $page_owner_uid, $album )); } else { - $r = DBA::toArray(DBA::p("SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `uid` = ? AND `album` = ?", + $r = DBA::toArray(DBA::p( + "SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `uid` = ? AND `album` = ?", DI::userSession()->getLocalUserId(), $album )); @@ -258,7 +260,6 @@ function photos_post(App $a) // same as above but remove single photo if ($visitor) { $condition = ['contact-id' => $visitor, 'uid' => $page_owner_uid, 'resource-id' => DI::args()->getArgv()[3]]; - } else { $condition = ['uid' => DI::userSession()->getLocalUserId(), 'resource-id' => DI::args()->getArgv()[3]]; } @@ -405,7 +406,7 @@ function photos_post(App $a) if (strpos($tag, '@') === 0) { $profile = ''; $contact = null; - $name = substr($tag,1); + $name = substr($tag, 1); if ((strpos($name, '@')) || (strpos($name, 'http://'))) { $newname = $name; @@ -441,13 +442,15 @@ function photos_post(App $a) if ($tagcid) { $contact = DBA::selectFirst('contact', [], ['id' => $tagcid, 'uid' => $page_owner_uid]); } else { - $newname = str_replace('_',' ',$name); + $newname = str_replace('_', ' ', $name); //select someone from this user's contacts by name $contact = DBA::selectFirst('contact', [], ['name' => $newname, 'uid' => $page_owner_uid]); if (!DBA::isResult($contact)) { //select someone by attag or nick and the name passed in - $contact = DBA::selectFirst('contact', [], + $contact = DBA::selectFirst( + 'contact', + [], ['(`attag` = ? OR `nick` = ?) AND `uid` = ?', $name, $name, $page_owner_uid], ['order' => ['attag' => true]] ); @@ -689,11 +692,13 @@ function photos_content(App $a) $uploader = ''; - $ret = ['post_url' => 'profile/' . $user['nickname'] . '/photos', - 'addon_text' => $uploader, - 'default_upload' => true]; + $ret = [ + 'post_url' => 'profile/' . $user['nickname'] . '/photos', + 'addon_text' => $uploader, + 'default_upload' => true + ]; - Hook::callAll('photo_upload_form',$ret); + Hook::callAll('photo_upload_form', $ret); $default_upload_box = Renderer::replaceMacros(Renderer::getMarkupTemplate('photos_default_uploader_box.tpl'), []); $default_upload_submit = Renderer::replaceMacros(Renderer::getMarkupTemplate('photos_default_uploader_submit.tpl'), [ @@ -705,7 +710,7 @@ function photos_content(App $a) $umf_bytes = Strings::getBytesFromShorthand(ini_get('upload_max_filesize')); // Per Friendica definition a value of '0' means unlimited: - If ($mis_bytes == 0) { + if ($mis_bytes == 0) { $mis_bytes = INF; } @@ -719,7 +724,7 @@ function photos_content(App $a) $aclselect_e = ($visitor ? '' : ACL::getFullSelectorHTML(DI::page(), $a->getLoggedInUserId())); - $o .= Renderer::replaceMacros($tpl,[ + $o .= Renderer::replaceMacros($tpl, [ '$pagename' => DI::l10n()->t('Upload Photos'), '$sessid' => session_id(), '$usage' => $usage_message, @@ -747,7 +752,7 @@ function photos_content(App $a) if ($datatype === 'album') { // if $datum is not a valid hex, redirect to the default page if (is_null($datum) || !Strings::isHex($datum)) { - DI::baseUrl()->redirect('photos/' . $user['nickname']. '/album'); + DI::baseUrl()->redirect('photos/' . $user['nickname'] . '/album'); } $album = hex2bin($datum); @@ -756,7 +761,8 @@ function photos_content(App $a) } $total = 0; - $r = DBA::toArray(DBA::p("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = ? AND `album` = ? + $r = DBA::toArray(DBA::p( + "SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = ? AND `album` = ? AND `scale` <= 4 $sql_extra GROUP BY `resource-id`", $owner_uid, $album @@ -775,7 +781,8 @@ function photos_content(App $a) $order = 'DESC'; } - $r = DBA::toArray(DBA::p("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, + $r = DBA::toArray(DBA::p( + "SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`type`) AS `type`, max(`scale`) AS `scale`, ANY_VALUE(`desc`) as `desc`, ANY_VALUE(`created`) as `created` FROM `photo` WHERE `uid` = ? AND `album` = ? @@ -809,7 +816,7 @@ function photos_content(App $a) $album_e = $album; - $o .= Renderer::replaceMacros($edit_tpl,[ + $o .= Renderer::replaceMacros($edit_tpl, [ '$nametext' => DI::l10n()->t('New album name: '), '$nickname' => $user['nickname'], '$album' => $album_e, @@ -843,16 +850,16 @@ function photos_content(App $a) $desc_e = $rr['desc']; $photos[] = [ - 'id' => $rr['id'], - 'twist' => ' ' . ($twist ? 'rotleft' : 'rotright') . rand(2,4), - 'link' => 'photos/' . $user['nickname'] . '/image/' . $rr['resource-id'] + 'id' => $rr['id'], + 'twist' => ' ' . ($twist ? 'rotleft' : 'rotright') . rand(2, 4), + 'link' => 'photos/' . $user['nickname'] . '/image/' . $rr['resource-id'] . ($order_field === 'created' ? '?order=created' : ''), 'title' => DI::l10n()->t('View Photo'), - 'src' => 'photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.' .$ext, - 'alt' => $imgalt_e, - 'desc'=> $desc_e, - 'ext' => $ext, - 'hash'=> $rr['resource-id'], + 'src' => 'photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.' . $ext, + 'alt' => $imgalt_e, + 'desc' => $desc_e, + 'ext' => $ext, + 'hash' => $rr['resource-id'], ]; } } @@ -870,7 +877,6 @@ function photos_content(App $a) ]); return $o; - } // Display one photo @@ -955,7 +961,7 @@ function photos_content(App $a) } $tpl = Renderer::getMarkupTemplate('photo_edit_head.tpl'); - DI::page()['htmlhead'] .= Renderer::replaceMacros($tpl,[ + DI::page()['htmlhead'] .= Renderer::replaceMacros($tpl, [ '$prevlink' => $prevlink, '$nextlink' => $nextlink ]); @@ -967,7 +973,7 @@ function photos_content(App $a) if ($nextlink) { $nextlink = [$nextlink, '']; } - } + } } if (count($ph) == 1) { @@ -1007,12 +1013,12 @@ function photos_content(App $a) } $photo = [ - 'href' => 'photo/' . $hires['resource-id'] . '-' . $hires['scale'] . '.' . $phototypes[$hires['type']], - 'title'=> DI::l10n()->t('View Full Size'), - 'src' => 'photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.' . $phototypes[$lores['type']] . '?_u=' . DateTimeFormat::utcNow('ymdhis'), - 'height' => $hires['height'], - 'width' => $hires['width'], - 'album' => $hires['album'], + 'href' => 'photo/' . $hires['resource-id'] . '-' . $hires['scale'] . '.' . $phototypes[$hires['type']], + 'title' => DI::l10n()->t('View Full Size'), + 'src' => 'photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.' . $phototypes[$lores['type']] . '?_u=' . DateTimeFormat::utcNow('ymdhis'), + 'height' => $hires['height'], + 'width' => $hires['width'], + 'album' => $hires['album'], 'filename' => $hires['filename'], ]; @@ -1079,12 +1085,12 @@ function photos_content(App $a) $edit = Renderer::replaceMacros($edit_tpl, [ '$id' => $ph[0]['id'], - '$album' => ['albname', DI::l10n()->t('New album name'), $album_e,''], + '$album' => ['albname', DI::l10n()->t('New album name'), $album_e, ''], '$caption' => ['desc', DI::l10n()->t('Caption'), $caption_e, ''], '$tags' => ['newtag', DI::l10n()->t('Add a Tag'), "", DI::l10n()->t('Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping')], - '$rotate_none' => ['rotate', DI::l10n()->t('Do not rotate'),0,'', true], - '$rotate_cw' => ['rotate', DI::l10n()->t("Rotate CW \x28right\x29"),1,''], - '$rotate_ccw' => ['rotate', DI::l10n()->t("Rotate CCW \x28left\x29"),2,''], + '$rotate_none' => ['rotate', DI::l10n()->t('Do not rotate'), 0, '', true], + '$rotate_cw' => ['rotate', DI::l10n()->t("Rotate CW \x28right\x29"), 1, ''], + '$rotate_ccw' => ['rotate', DI::l10n()->t("Rotate CCW \x28left\x29"), 2, ''], '$nickname' => $user['nickname'], '$resource_id' => $ph[0]['resource-id'], @@ -1179,7 +1185,7 @@ function photos_content(App $a) $qcomment = $words ? explode("\n", $words) : []; } - $comments .= Renderer::replaceMacros($cmnt_tpl,[ + $comments .= Renderer::replaceMacros($cmnt_tpl, [ '$return_path' => '', '$jsreload' => $return_path, '$id' => $link_item['id'], @@ -1203,13 +1209,19 @@ function photos_content(App $a) $activity = DI::activity(); if (($activity->match($item['verb'], Activity::LIKE) || - $activity->match($item['verb'], Activity::DISLIKE)) && - ($item['gravity'] != Item::GRAVITY_PARENT)) { + $activity->match($item['verb'], Activity::DISLIKE)) && + ($item['gravity'] != Item::GRAVITY_PARENT) + ) { continue; } - $author = ['uid' => 0, 'id' => $item['author-id'], - 'network' => $item['author-network'], 'url' => $item['author-link']]; + $author = [ + 'uid' => 0, + 'id' => $item['author-id'], + 'network' => $item['author-network'], + 'url' => $item['author-link'], + 'alias' => $item['author-alias'] + ]; $profile_url = Contact::magicLinkByContact($author); if (strpos($profile_url, 'contact/redir/') === 0) { $sparkle = ' sparkle'; @@ -1228,7 +1240,7 @@ function photos_content(App $a) $title_e = $item['title']; $body_e = BBCode::convertForUriId($item['uri-id'], $item['body']); - $comments .= Renderer::replaceMacros($template,[ + $comments .= Renderer::replaceMacros($template, [ '$id' => $item['id'], '$profile_url' => $profile_url, '$name' => $item['author-name'], diff --git a/src/Content/Conversation.php b/src/Content/Conversation.php index e0205d3d09..be984d555b 100644 --- a/src/Content/Conversation.php +++ b/src/Content/Conversation.php @@ -154,7 +154,8 @@ class Conversation 'uid' => 0, 'id' => $activity['author-id'], 'network' => $activity['author-network'], - 'url' => $activity['author-link'] + 'url' => $activity['author-link'], + 'alias' => $activity['author-alias'], ]; $url = Contact::magicLinkByContact($author); if (strpos($url, 'contact/redir/') === 0) { @@ -272,7 +273,7 @@ class Conversation $phrase = $this->l10n->tt(' attends', ' attend', $total, $spanatts); break; case 'attendno': - $phrase = $this->l10n->tt(' doesn\'t attend',' don\'t attend', $total, $spanatts); + $phrase = $this->l10n->tt(' doesn\'t attend', ' don\'t attend', $total, $spanatts); break; case 'attendmaybe': $phrase = $this->l10n->tt(' attends maybe', ' attend maybe', $total, $spanatts); @@ -537,7 +538,7 @@ class Conversation if (!$update) { $live_update_div = '
' . "\r\n" . "\r\n"; + . "?f='; \r\n"; } } elseif ($mode === self::MODE_SEARCH) { $live_update_div = '' . "\r\n"; @@ -625,7 +626,13 @@ class Conversation $tags = Tag::populateFromItem($item); - $author = ['uid' => 0, 'id' => $item['author-id'], 'network' => $item['author-network'], 'url' => $item['author-link']]; + $author = [ + 'uid' => 0, + 'id' => $item['author-id'], + 'network' => $item['author-network'], + 'url' => $item['author-link'], + 'alias' => $item['author-alias'], + ]; $profile_link = Contact::magicLinkByContact($author); $sparkle = ''; @@ -856,7 +863,8 @@ class Conversation $row['causer-avatar'] = $contact['thumb']; $row['causer-name'] = $contact['name']; } elseif (($row['gravity'] == ItemModel::GRAVITY_ACTIVITY) && ($row['verb'] == Activity::ANNOUNCE) && - ($row['author-id'] == $activity['causer-id'])) { + ($row['author-id'] == $activity['causer-id']) + ) { return $row; } } @@ -892,9 +900,15 @@ class Conversation } if (in_array($row['gravity'], [ItemModel::GRAVITY_PARENT, ItemModel::GRAVITY_COMMENT]) && !empty($row['causer-id'])) { - $causer = ['uid' => 0, 'id' => $row['causer-id'], 'network' => $row['causer-network'], 'url' => $row['causer-link']]; + $causer = [ + 'uid' => 0, + 'id' => $row['causer-id'], + 'network' => $row['causer-network'], + 'url' => $row['causer-link'], + 'alias' => $row['causer-alias'], + ]; - $row['reshared'] = $this->l10n->t('%s reshared this.', '' . htmlentities($row['causer-name']) . ''); + $row['reshared'] = $this->l10n->t('%s reshared this.', '' . htmlentities($row['causer-name']) . ''); } $row['direction'] = ['direction' => 3, 'title' => (empty($row['causer-id']) ? $this->l10n->t('Reshared') : $this->l10n->t('Reshared by %s <%s>', $row['causer-name'], $row['causer-link']))]; break; @@ -994,15 +1008,21 @@ class Conversation $condition = DBA::mergeConditions($condition, ["(`gravity` != ? OR `origin`)", ItemModel::GRAVITY_ACTIVITY]); } - $condition = DBA::mergeConditions($condition, - ["`uid` IN (0, ?) AND (NOT `vid` IN (?, ?, ?) OR `vid` IS NULL)", $uid, Verb::getID(Activity::FOLLOW), Verb::getID(Activity::VIEW), Verb::getID(Activity::READ)]); + $condition = DBA::mergeConditions( + $condition, + ["`uid` IN (0, ?) AND (NOT `vid` IN (?, ?, ?) OR `vid` IS NULL)", $uid, Verb::getID(Activity::FOLLOW), Verb::getID(Activity::VIEW), Verb::getID(Activity::READ)] + ); $condition = DBA::mergeConditions($condition, ["(`uid` != ? OR `private` != ?)", 0, ItemModel::PRIVATE]); - $condition = DBA::mergeConditions($condition, - ["`visible` AND NOT `deleted` AND NOT `author-blocked` AND NOT `owner-blocked` + $condition = DBA::mergeConditions( + $condition, + [ + "`visible` AND NOT `deleted` AND NOT `author-blocked` AND NOT `owner-blocked` AND ((NOT `contact-pending` AND (`contact-rel` IN (?, ?))) OR `self` OR `contact-uid` = ?)", - Contact::SHARING, Contact::FRIEND, 0]); + Contact::SHARING, Contact::FRIEND, 0 + ] + ); $thread_parents = Post::select(['uri-id', 'causer-id'], $condition, ['order' => ['uri-id' => false, 'uid']]); @@ -1109,8 +1129,10 @@ class Conversation $items[$key]['user-collapsed-author'] = !$always_display && in_array($row['author-id'], $collapses); $items[$key]['user-collapsed-owner'] = !$always_display && in_array($row['owner-id'], $collapses); - if (in_array($mode, [self::MODE_COMMUNITY, self::MODE_NETWORK]) && - (in_array($row['author-id'], $blocks) || in_array($row['owner-id'], $blocks) || in_array($row['author-id'], $ignores) || in_array($row['owner-id'], $ignores))) { + if ( + in_array($mode, [self::MODE_COMMUNITY, self::MODE_NETWORK]) && + (in_array($row['author-id'], $blocks) || in_array($row['owner-id'], $blocks) || in_array($row['author-id'], $ignores) || in_array($row['owner-id'], $ignores)) + ) { unset($items[$key]); } } @@ -1145,7 +1167,7 @@ class Conversation $condition = DBA::mergeConditions(['parent-uri-id' => $uriids, 'gravity' => ItemModel::GRAVITY_ACTIVITY, 'verb' => $verbs], ["NOT `deleted`"]); $separator = chr(255) . chr(255) . chr(255); - $sql = "SELECT `thr-parent-id`, `body`, `verb`, COUNT(*) AS `total`, GROUP_CONCAT(REPLACE(`author-name`, '" . $separator . "', ' ') SEPARATOR '". $separator ."' LIMIT 50) AS `title` FROM `post-view` WHERE " . array_shift($condition) . " GROUP BY `thr-parent-id`, `verb`, `body`"; + $sql = "SELECT `thr-parent-id`, `body`, `verb`, COUNT(*) AS `total`, GROUP_CONCAT(REPLACE(`author-name`, '" . $separator . "', ' ') SEPARATOR '" . $separator . "' LIMIT 50) AS `title` FROM `post-view` WHERE " . array_shift($condition) . " GROUP BY `thr-parent-id`, `verb`, `body`"; $emojis = []; @@ -1286,7 +1308,7 @@ class Conversation // Searches the post item in the children $j = 0; while ($child['children'][$j]['verb'] !== Activity::POST && $j < count($child['children'])) { - $j ++; + $j++; } $moved_item = $child['children'][$j]; @@ -1360,8 +1382,10 @@ class Conversation * items and add them as children of their top-level post. */ foreach ($parents as $i => $parent) { - $parents[$i]['children'] = array_merge($this->getItemChildren($item_array, $parent, true), - $this->getItemChildren($item_array, $parent, false)); + $parents[$i]['children'] = array_merge( + $this->getItemChildren($item_array, $parent, true), + $this->getItemChildren($item_array, $parent, false) + ); } foreach ($parents as $i => $parent) { diff --git a/src/Content/GroupManager.php b/src/Content/GroupManager.php index d7848b41bf..fc43080d90 100644 --- a/src/Content/GroupManager.php +++ b/src/Content/GroupManager.php @@ -78,7 +78,7 @@ class GroupManager $groupList = []; - $fields = ['id', 'url', 'name', 'micro', 'thumb', 'avatar', 'network', 'uid']; + $fields = ['id', 'url', 'alias', 'name', 'micro', 'thumb', 'avatar', 'network', 'uid']; $contacts = DBA::select('account-user-view', $fields, $condition, $params); if (!$contacts) { return $groupList; @@ -87,6 +87,7 @@ class GroupManager while ($contact = DBA::fetch($contacts)) { $groupList[] = [ 'url' => $contact['url'], + 'alias' => $contact['alias'], 'name' => $contact['name'], 'id' => $contact['id'], 'micro' => $contact['micro'], diff --git a/src/Content/Item.php b/src/Content/Item.php index 3981978f4e..49193627f6 100644 --- a/src/Content/Item.php +++ b/src/Content/Item.php @@ -305,18 +305,20 @@ class Item } $author_arr = [ - 'uid' => 0, - 'id' => $item['author-id'], + 'uid' => 0, + 'id' => $item['author-id'], 'network' => $item['author-network'], - 'url' => $item['author-link'], + 'url' => $item['author-link'], + 'alias' => $item['author-lias'], ]; $author = '[url=' . Contact::magicLinkByContact($author_arr) . ']' . $item['author-name'] . '[/url]'; $author_arr = [ - 'uid' => 0, - 'id' => $obj['author-id'], + 'uid' => 0, + 'id' => $obj['author-id'], 'network' => $obj['author-network'], - 'url' => $obj['author-link'], + 'url' => $obj['author-link'], + 'alias' => $obj['author-alias'], ]; $objauthor = '[url=' . Contact::magicLinkByContact($author_arr) . ']' . $obj['author-name'] . '[/url]'; @@ -372,10 +374,11 @@ class Item } $author = [ - 'uid' => 0, - 'id' => $item['author-id'], + 'uid' => 0, + 'id' => $item['author-id'], 'network' => $item['author-network'], - 'url' => $item['author-link'], + 'url' => $item['author-link'], + 'alias' => $item['author-alias'], ]; $profile_link = Contact::magicLinkByContact($author, $item['author-link']); if (strpos($profile_link, 'contact/redir/') === 0) { diff --git a/src/Content/Text/HTML.php b/src/Content/Text/HTML.php index 01151a6a52..d30e7ead03 100644 --- a/src/Content/Text/HTML.php +++ b/src/Content/Text/HTML.php @@ -422,7 +422,8 @@ class HTML { $URLSearchString = "^\[\]"; - $matches = ["/\[url\=([$URLSearchString]*)\].*?\[\/url\]/ism", + $matches = [ + "/\[url\=([$URLSearchString]*)\].*?\[\/url\]/ism", "/\[url\]([$URLSearchString]*)\[\/url\]/ism", "/\[img\=[0-9]*x[0-9]*\](.*?)\[\/img\]/ism", "/\[img\](.*?)\[\/img\]/ism", @@ -531,8 +532,10 @@ class HTML $ignore = false; // A list of some links that should be ignored - $list = ["/user/", "/tag/", "/group/", "/circle/", "/profile/", "/search?search=", "/search?tag=", "mailto:", "/u/", "/node/", - "//plus.google.com/", "//twitter.com/"]; + $list = [ + "/user/", "/tag/", "/group/", "/circle/", "/profile/", "/search?search=", "/search?tag=", "mailto:", "/u/", "/node/", + "//plus.google.com/", "//twitter.com/" + ]; foreach ($list as $listitem) { if (strpos($treffer[1], $listitem) !== false) { $ignore = true; @@ -941,7 +944,8 @@ class HTML $domain = '(?:(?!-)[A-Za-z0-9-]{1,63}(?set('URI.SafeIframeRegexp', + $config->set( + 'URI.SafeIframeRegexp', '%^https://(?: ' . implode('|', $allowedIframeDomains) . ' ) @@ -1050,7 +1054,8 @@ class HTML if (isset($mediaType->parameters['charset'])) { return strtolower($mediaType->parameters['charset']); } - } catch(\InvalidArgumentException $e) {} + } catch (\InvalidArgumentException $e) { + } return null; } diff --git a/src/Content/Widget.php b/src/Content/Widget.php index 6b44a62eb7..f0236c00c1 100644 --- a/src/Content/Widget.php +++ b/src/Content/Widget.php @@ -474,7 +474,6 @@ class Widget $thisday = substr($dnow, 4); $dnow = substr($dnow, 0, 8) . '01'; $dthen = substr($dthen, 0, 8) . '01'; - /* * Starting with the current month, get the first and last days of every @@ -494,7 +493,6 @@ class Widget $ret[$dyear][] = [$str, $end_month, $start_month]; $dnow = DateTimeFormat::utc($dnow . ' -1 month', 'Y-m-d'); - } } @@ -506,7 +504,7 @@ class Widget $cutoff_year = intval(DateTimeFormat::localNow('Y')) - $visible_years; $cutoff = array_key_exists($cutoff_year, $ret); - $o = Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/posted_date.tpl'),[ + $o = Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/posted_date.tpl'), [ '$title' => DI::l10n()->t('Archives'), '$size' => $visible_years, '$cutoff_year' => $cutoff_year, @@ -540,7 +538,14 @@ class Widget ['ref' => 'community', 'name' => DI::l10n()->t('Groups')], ]; - return self::filter('accounttype', DI::l10n()->t('Account Types'), '', - DI::l10n()->t('All'), $base, $accounts, $accounttype); + return self::filter( + 'accounttype', + DI::l10n()->t('Account Types'), + '', + DI::l10n()->t('All'), + $base, + $accounts, + $accounttype + ); } } diff --git a/src/Content/Widget/ContactBlock.php b/src/Content/Widget/ContactBlock.php index e206dbcb4e..fbc492eaad 100644 --- a/src/Content/Widget/ContactBlock.php +++ b/src/Content/Widget/ContactBlock.php @@ -104,7 +104,7 @@ class ContactBlock $contact_uriids = array_column($personal_contacts, 'uri-id'); if (!empty($contact_uriids)) { - $contacts_stmt = DBA::select('contact', ['id', 'uid', 'addr', 'url', 'name', 'thumb', 'avatar', 'network'], ['uri-id' => $contact_uriids, 'uid' => $contact_uid]); + $contacts_stmt = DBA::select('contact', ['id', 'uid', 'addr', 'url', 'alias', 'name', 'thumb', 'avatar', 'network'], ['uri-id' => $contact_uriids, 'uid' => $contact_uid]); if (DBA::isResult($contacts_stmt)) { $contacts_title = DI::l10n()->tt('%d Contact', '%d Contacts', $total); diff --git a/src/Content/Widget/VCard.php b/src/Content/Widget/VCard.php index e462ab0aaa..2cb0b0df13 100644 --- a/src/Content/Widget/VCard.php +++ b/src/Content/Widget/VCard.php @@ -29,6 +29,7 @@ use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\DI; use Friendica\Model\Contact; +use Friendica\Util\Network; use Friendica\Util\Strings; /** @@ -50,9 +51,15 @@ class VCard Logger::warning('Incomplete contact', ['contact' => $contact ?? [], 'callstack' => System::callstack(20)]); } + if (!Network::isValidHttpUrl($contact['url']) && Network::isValidHttpUrl($contact['alias'])) { + $url = $contact['alias']; + } else { + $url = $contact['url']; + } + if ($contact['network'] != '') { - $network_link = Strings::formatNetworkName($contact['network'], $contact['url']); - $network_avatar = ContactSelector::networkToIcon($contact['network'], $contact['url']); + $network_link = Strings::formatNetworkName($contact['network'], $url); + $network_avatar = ContactSelector::networkToIcon($contact['network'], $url); } else { $network_link = ''; $network_avatar = ''; @@ -83,9 +90,9 @@ class VCard if (empty($contact['self']) && Protocol::supportsFollow($contact['network'])) { if (in_array($rel, [Contact::SHARING, Contact::FRIEND])) { - $unfollow_link = 'contact/unfollow?url=' . urlencode($contact['url']) . '&auto=1'; + $unfollow_link = 'contact/unfollow?url=' . urlencode($url) . '&auto=1'; } elseif (!$pending) { - $follow_link = 'contact/follow?url=' . urlencode($contact['url']) . '&auto=1'; + $follow_link = 'contact/follow?url=' . urlencode($url) . '&auto=1'; } } @@ -97,7 +104,7 @@ class VCard return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/vcard.tpl'), [ '$contact' => $contact, '$photo' => $photo, - '$url' => Contact::magicLinkByContact($contact, $contact['url']), + '$url' => Contact::magicLinkByContact($contact, $url), '$about' => BBCode::convertForUriId($contact['uri-id'] ?? 0, $contact['about'] ?? ''), '$xmpp' => DI::l10n()->t('XMPP:'), '$matrix' => DI::l10n()->t('Matrix:'), diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 1a52164561..4787eeab9e 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -23,7 +23,7 @@ namespace Friendica\Model; use Friendica\Contact\Avatar; use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException; -use Friendica\Content\Conversation As ConversationContent; +use Friendica\Content\Conversation as ConversationContent; use Friendica\Content\Pager; use Friendica\Content\Text\HTML; use Friendica\Core\Hook; @@ -111,12 +111,12 @@ class Contact * @} */ - const MIRROR_DEACTIVATED = 0; - const MIRROR_FORWARDED = 1; // Deprecated, now does the same like MIRROR_OWN_POST - const MIRROR_OWN_POST = 2; - const MIRROR_NATIVE_RESHARE = 3; + const MIRROR_DEACTIVATED = 0; + const MIRROR_FORWARDED = 1; // Deprecated, now does the same like MIRROR_OWN_POST + const MIRROR_OWN_POST = 2; + const MIRROR_NATIVE_RESHARE = 3; - /** + /** * @param array $fields Array of selected fields, empty for all * @param array $condition Array of fields for condition * @param array $params Array of several parameters @@ -725,8 +725,11 @@ class Contact */ public static function createSelfFromUserId(int $uid): bool { - $user = DBA::selectFirst('user', ['uid', 'username', 'nickname', 'pubkey', 'prvkey'], - ['uid' => $uid, 'account_expired' => false]); + $user = DBA::selectFirst( + 'user', + ['uid', 'username', 'nickname', 'pubkey', 'prvkey'], + ['uid' => $uid, 'account_expired' => false] + ); if (!DBA::isResult($user)) { return false; } @@ -786,9 +789,11 @@ class Contact */ public static function updateSelfFromUserID(int $uid, bool $update_avatar = false): bool { - $fields = ['id', 'uri-id', 'name', 'nick', 'location', 'about', 'keywords', 'avatar', 'prvkey', 'pubkey', 'manually-approve', + $fields = [ + 'id', 'uri-id', 'name', 'nick', 'location', 'about', 'keywords', 'avatar', 'prvkey', 'pubkey', 'manually-approve', 'xmpp', 'matrix', 'contact-type', 'forum', 'prv', 'avatar-date', 'url', 'nurl', 'unsearchable', - 'photo', 'thumb', 'micro', 'header', 'addr', 'request', 'notify', 'poll', 'confirm', 'poco', 'network']; + 'photo', 'thumb', 'micro', 'header', 'addr', 'request', 'notify', 'poll', 'confirm', 'poco', 'network' + ]; $self = DBA::selectFirst('contact', $fields, ['uid' => $uid, 'self' => true]); if (!DBA::isResult($self)) { return false; @@ -800,8 +805,10 @@ class Contact return false; } - $fields = ['name', 'photo', 'thumb', 'about', 'address', 'locality', 'region', - 'country-name', 'pub_keywords', 'xmpp', 'matrix', 'net-publish']; + $fields = [ + 'name', 'photo', 'thumb', 'about', 'address', 'locality', 'region', + 'country-name', 'pub_keywords', 'xmpp', 'matrix', 'net-publish' + ]; $profile = DBA::selectFirst('profile', $fields, ['uid' => $uid]); if (!DBA::isResult($profile)) { return false; @@ -830,7 +837,7 @@ class Contact 'addr' => $user['nickname'] . '@' . substr(DI::baseUrl(), strpos(DI::baseUrl(), '://') + 3), 'request' => DI::baseUrl() . '/dfrn_request/' . $user['nickname'], 'notify' => DI::baseUrl() . '/dfrn_notify/' . $user['nickname'], - 'poll' => DI::baseUrl() . '/dfrn_poll/'. $user['nickname'], + 'poll' => DI::baseUrl() . '/dfrn_poll/' . $user['nickname'], 'confirm' => DI::baseUrl() . '/dfrn_confirm/' . $user['nickname'], ]; @@ -850,7 +857,7 @@ class Contact // We are adding a timestamp value so that other systems won't use cached content $timestamp = strtotime($fields['avatar-date']); - $prefix = DI::baseUrl() . '/photo/' .$avatar['resource-id'] . '-'; + $prefix = DI::baseUrl() . '/photo/' . $avatar['resource-id'] . '-'; $suffix = '.' . $file_suffix . '?ts=' . $timestamp; $fields['photo'] = $prefix . '4' . $suffix; @@ -1188,22 +1195,22 @@ class Contact */ if (empty($contact['uid'])) { $menu = [ - 'profile' => [DI::l10n()->t('View Profile') , $profile_link , true ], - 'network' => [DI::l10n()->t('Network Posts') , $posts_link , false], - 'edit' => [DI::l10n()->t('View Contact') , $contact_url , false], - 'follow' => [DI::l10n()->t('Connect/Follow'), $follow_link , true ], - 'unfollow' => [DI::l10n()->t('Unfollow') , $unfollow_link, true ], + 'profile' => [DI::l10n()->t('View Profile'), $profile_link, true], + 'network' => [DI::l10n()->t('Network Posts'), $posts_link, false], + 'edit' => [DI::l10n()->t('View Contact'), $contact_url, false], + 'follow' => [DI::l10n()->t('Connect/Follow'), $follow_link, true], + 'unfollow' => [DI::l10n()->t('Unfollow'), $unfollow_link, true], ]; } else { $menu = [ - 'status' => [DI::l10n()->t('View Status') , $status_link , true ], - 'profile' => [DI::l10n()->t('View Profile') , $profile_link , true ], - '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], - 'pm' => [DI::l10n()->t('Send PM') , $pm_url , false], - 'follow' => [DI::l10n()->t('Connect/Follow'), $follow_link , true ], - 'unfollow' => [DI::l10n()->t('Unfollow') , $unfollow_link, true ], + 'status' => [DI::l10n()->t('View Status'), $status_link, true], + 'profile' => [DI::l10n()->t('View Profile'), $profile_link, true], + '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], + 'pm' => [DI::l10n()->t('Send PM'), $pm_url, false], + 'follow' => [DI::l10n()->t('Connect/Follow'), $follow_link, true], + 'unfollow' => [DI::l10n()->t('Unfollow'), $unfollow_link, true], ]; if (!empty($contact['pending'])) { @@ -1310,9 +1317,11 @@ class Contact if (($uid == 0) && (empty($data['network']) || ($data['network'] == Protocol::PHANTOM))) { // Fetch data for the public contact via the first found personal contact /// @todo Check if this case can happen at all (possibly with mail accounts?) - $fields = ['name', 'nick', 'url', 'addr', 'alias', 'avatar', 'header', 'contact-type', + $fields = [ + 'name', 'nick', 'url', 'addr', 'alias', 'avatar', 'header', 'contact-type', 'keywords', 'location', 'about', 'unsearchable', 'batch', 'notify', 'poll', - 'request', 'confirm', 'poco', 'subscribe', 'network', 'baseurl', 'gsid']; + 'request', 'confirm', 'poco', 'subscribe', 'network', 'baseurl', 'gsid' + ]; $personal_contact = DBA::selectFirst('contact', $fields, ["`addr` = ? AND `uid` != 0", $url]); if (!DBA::isResult($personal_contact)) { @@ -1458,7 +1467,7 @@ class Contact if (!empty($contact['batch'])) { $condition = ['archive' => true, 'uid' => 0, 'network' => Protocol::FEDERATED, 'batch' => $contact['batch'], 'contact-type' => self::TYPE_RELAY]; return DBA::exists('contact', $condition); - } + } return false; } @@ -1551,11 +1560,15 @@ class Contact $contact_field = ((($contact["contact-type"] == self::TYPE_COMMUNITY) || ($contact['network'] == Protocol::MAIL)) ? 'owner-id' : 'author-id'); if ($thread_mode) { - $condition = ["((`$contact_field` = ? AND `gravity` = ?) OR (`author-id` = ? AND `gravity` = ? AND `vid` = ? AND `protocol` != ? AND `thr-parent-id` = `parent-uri-id`)) AND " . $sql, - $cid, Item::GRAVITY_PARENT, $cid, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA, DI::userSession()->getLocalUserId()]; + $condition = [ + "((`$contact_field` = ? AND `gravity` = ?) OR (`author-id` = ? AND `gravity` = ? AND `vid` = ? AND `protocol` != ? AND `thr-parent-id` = `parent-uri-id`)) AND " . $sql, + $cid, Item::GRAVITY_PARENT, $cid, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA, DI::userSession()->getLocalUserId() + ]; } else { - $condition = ["`$contact_field` = ? AND `gravity` IN (?, ?) AND " . $sql, - $cid, Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, DI::userSession()->getLocalUserId()]; + $condition = [ + "`$contact_field` = ? AND `gravity` IN (?, ?) AND " . $sql, + $cid, Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, DI::userSession()->getLocalUserId() + ]; } if (!empty($parent)) { @@ -1568,16 +1581,26 @@ 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]); + $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(DI::userSession()->getLocalUserId(), 'system', 'itemspage_mobile_network', - DI::config()->get('system', 'itemspage_network_mobile')); + $itemsPerPage = DI::pConfig()->get( + DI::userSession()->getLocalUserId(), + 'system', + 'itemspage_mobile_network', + DI::config()->get('system', 'itemspage_network_mobile') + ); } else { - $itemsPerPage = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'itemspage_network', - DI::config()->get('system', 'itemspage_network')); + $itemsPerPage = DI::pConfig()->get( + DI::userSession()->getLocalUserId(), + 'system', + 'itemspage_network', + DI::config()->get('system', 'itemspage_network') + ); } $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), $itemsPerPage); @@ -1611,8 +1634,10 @@ class Contact if ($pager->getStart() == 0) { $cdata = self::getPublicAndUserContactID($cid, DI::userSession()->getLocalUserId()); if (!empty($cdata['public'])) { - $condition = ["`uri-id` IN (SELECT `uri-id` FROM `collection-view` WHERE `cid` = ? AND `type` = ?)", - $cdata['public'], Post\Collection::FEATURED]; + $condition = [ + "`uri-id` IN (SELECT `uri-id` FROM `collection-view` WHERE `cid` = ? AND `type` = ?)", + $cdata['public'], Post\Collection::FEATURED + ]; $pinned = Post::toArray(Post::selectForUser(DI::userSession()->getLocalUserId(), $fields, $condition, $params)); $items = array_merge($pinned, $items); } @@ -1719,7 +1744,7 @@ class Contact } 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; + return; } } @@ -2121,8 +2146,10 @@ class Contact */ public static function getAvatarUrlForUrl(string $url, int $uid, string $size = ''): string { - $condition = ["`nurl` = ? AND ((`uid` = ? AND `network` IN (?, ?)) OR `uid` = ?)", - Strings::normaliseLink($url), $uid, Protocol::FEED, Protocol::MAIL, 0]; + $condition = [ + "`nurl` = ? AND ((`uid` = ? AND `network` IN (?, ?)) OR `uid` = ?)", + Strings::normaliseLink($url), $uid, Protocol::FEED, Protocol::MAIL, 0 + ]; $contact = self::selectFirst(['id', 'updated'], $condition, ['order' => ['uid' => true]]); return self::getAvatarUrlForId($contact['id'] ?? 0, $size, $contact['updated'] ?? ''); } @@ -2193,8 +2220,11 @@ 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', 'blurhash', 'xmpp', 'addr', 'nurl', 'url', 'network', 'uri-id'], - ['id' => $cid, 'self' => false]); + $contact = DBA::selectFirst( + 'contact', + ['uid', 'avatar', 'photo', 'thumb', 'micro', 'blurhash', 'xmpp', 'addr', 'nurl', 'url', 'network', 'uri-id'], + ['id' => $cid, 'self' => false] + ); if (!DBA::isResult($contact)) { return; } @@ -2268,10 +2298,12 @@ class Contact } if ($default_avatar && Proxy::isLocalImage($avatar)) { - $fields = ['avatar' => $avatar, 'avatar-date' => DateTimeFormat::utcNow(), + $fields = [ + 'avatar' => $avatar, 'avatar-date' => DateTimeFormat::utcNow(), 'photo' => $avatar, 'thumb' => self::getDefaultAvatar($contact, Proxy::SIZE_THUMB), - 'micro' => self::getDefaultAvatar($contact, Proxy::SIZE_MICRO)]; + 'micro' => self::getDefaultAvatar($contact, Proxy::SIZE_MICRO) + ]; Logger::debug('Use default avatar', ['id' => $cid, 'uid' => $uid]); } @@ -2330,8 +2362,11 @@ class Contact $uids = []; if (($uid == 0) && !in_array($contact['network'], [Protocol::FEED, Protocol::MAIL])) { // Collect all user contacts of the given public contact - $personal_contacts = DBA::select('contact', ['id', 'uid'], - ["`nurl` = ? AND `id` != ? AND NOT `self`", $contact['nurl'], $cid]); + $personal_contacts = DBA::select( + 'contact', + ['id', 'uid'], + ["`nurl` = ? AND `id` != ? AND NOT `self`", $contact['nurl'], $cid] + ); while ($personal_contact = DBA::fetch($personal_contacts)) { $cids[] = $personal_contact['id']; $uids[] = $personal_contact['uid']; @@ -2650,10 +2685,12 @@ class Contact // These fields aren't updated by this routine: // 'sensitive' - $fields = ['uid', 'uri-id', 'avatar', 'header', 'name', 'nick', 'location', 'keywords', 'about', 'subscribe', + $fields = [ + 'uid', 'uri-id', 'avatar', 'header', 'name', 'nick', 'location', 'keywords', 'about', 'subscribe', 'manually-approve', 'unsearchable', 'url', 'addr', 'batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'network', 'alias', 'baseurl', 'gsid', 'forum', 'prv', 'contact-type', 'pubkey', 'last-item', 'xmpp', 'matrix', - 'created', 'last-update']; + 'created', 'last-update' + ]; $contact = DBA::selectFirst('contact', $fields, ['id' => $id]); if (!DBA::isResult($contact)) { return false; @@ -2677,7 +2714,7 @@ class Contact return true; } - $has_local_data = self::hasLocalData($id, $contact); + $has_local_data = self::hasLocalData($id, $contact); $uid = $contact['uid']; unset($contact['uid']); @@ -2724,7 +2761,8 @@ class Contact // We must not try to update relay contacts via probe. They are no real contacts. // We check after the probing to be able to correct falsely detected contact types. if (($contact['contact-type'] == self::TYPE_RELAY) && - (!Strings::compareLink($ret['url'], $contact['url']) || in_array($ret['network'], [Protocol::FEED, Protocol::PHANTOM]))) { + (!Strings::compareLink($ret['url'], $contact['url']) || in_array($ret['network'], [Protocol::FEED, Protocol::PHANTOM])) + ) { self::updateContact($id, $uid, $uriid, $contact['url'], ['failed' => false, 'local-data' => $has_local_data, 'last-update' => $updated, 'next-update' => $success_next_update, 'success_update' => $updated]); Logger::info('Not updating relais', ['id' => $id, 'url' => $contact['url']]); return true; @@ -3078,11 +3116,11 @@ class Contact 'protocol' => $protocol, 'pubkey' => $ret['pubkey'], 'rel' => $new_relation, - 'priority'=> $ret['priority'], - 'writable'=> $writeable, + 'priority' => $ret['priority'], + 'writable' => $writeable, 'hidden' => $hidden, 'blocked' => 0, - 'readonly'=> 0, + 'readonly' => 0, 'pending' => $pending, 'subhub' => $subhub ]); @@ -3172,8 +3210,10 @@ class Contact } // Contact is blocked at user-level - if (!empty($contact['id']) && !empty($importer['id']) && - Contact\User::isBlocked($contact['id'], $importer['id'])) { + if ( + !empty($contact['id']) && !empty($importer['id']) && + Contact\User::isBlocked($contact['id'], $importer['id']) + ) { return false; } @@ -3181,9 +3221,12 @@ class Contact self::unmarkForArchival($contact); if (($contact['rel'] == self::SHARING) - || ($sharing && $contact['rel'] == self::FOLLOWER)) { - self::update(['rel' => self::FRIEND, 'writable' => true, 'pending' => false], - ['id' => $contact['id'], 'uid' => $importer['uid']]); + || ($sharing && $contact['rel'] == self::FOLLOWER) + ) { + self::update( + ['rel' => self::FRIEND, 'writable' => true, 'pending' => false], + ['id' => $contact['id'], 'uid' => $importer['uid']] + ); } // Ensure to always have the correct network type, independent from the connection request method @@ -3422,7 +3465,7 @@ class Contact */ public static function magicLinkById(int $cid, string $url = ''): string { - $contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'uid'], ['id' => $cid]); + $contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'alias', 'uid'], ['id' => $cid]); return self::magicLinkByContact($contact, $url); } @@ -3439,7 +3482,7 @@ class Contact */ public static function magicLinkByContact(array $contact, string $url = ''): string { - $destination = $url ?: $contact['url']; + $destination = $url ?: (!Network::isValidHttpUrl($contact['url']) && !empty($contact['alias']) && Network::isValidHttpUrl($contact['alias']) ? $contact['alias'] : $contact['url']); if (!DI::userSession()->isAuthenticated()) { return $destination; @@ -3568,8 +3611,10 @@ class Contact $params['limit'] = $limit; } - $condition = DBA::mergeConditions($condition, - ["(`addr` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?)", $search, $search, $search]); + $condition = DBA::mergeConditions( + $condition, + ["(`addr` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?)", $search, $search, $search] + ); return DBA::selectToArray('account-user-view', [], $condition, $params); } @@ -3619,7 +3664,7 @@ class Contact */ public static function getRandomContact(): array { - $contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'uid'], [ + $contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'alias', 'uid'], [ "`uid` = ? AND `network` = ? AND NOT `failed` AND `last-item` > ?", 0, Protocol::DFRN, DateTimeFormat::utc('now - 1 month'), ], ['order' => ['RAND()']]); diff --git a/src/Model/Event.php b/src/Model/Event.php index dc818d8f15..bc03370647 100644 --- a/src/Model/Event.php +++ b/src/Model/Event.php @@ -553,7 +553,8 @@ class Event WHERE `event`.`id` = ? AND `event`.`uid` = ? $sql_perms", - $event_id, $owner_uid + $event_id, + $owner_uid )); if (empty($events)) { throw new HTTPException\NotFoundException(DI::l10n()->t('Event not found.')); @@ -616,7 +617,8 @@ class Event AND `start` <= ? $sql_perms", $owner_uid, - $start, $start, + $start, + $start, $finish )); @@ -661,9 +663,9 @@ class Event $copy = null; $drop = null; if (DI::userSession()->getLocalUserId() && DI::userSession()->getLocalUserId() == $event['uid'] && $event['type'] == 'event') { - $edit = !$event['cid'] ? ['calendar/event/edit/' . $event['id'], DI::l10n()->t('Edit event') , '', ''] : null; - $copy = !$event['cid'] ? ['calendar/event/copy/' . $event['id'] , DI::l10n()->t('Duplicate event'), '', ''] : null; - $drop = ['calendar/api/delete/' . $event['id'] , DI::l10n()->t('Delete event') , '', '']; + $edit = !$event['cid'] ? ['calendar/event/edit/' . $event['id'], DI::l10n()->t('Edit event'), '', ''] : null; + $copy = !$event['cid'] ? ['calendar/event/copy/' . $event['id'], DI::l10n()->t('Duplicate event'), '', ''] : null; + $drop = ['calendar/api/delete/' . $event['id'], DI::l10n()->t('Delete event'), '', '']; } $title = BBCode::convertForUriId($event['uri-id'], Strings::escapeHtml($event['summary'])); @@ -708,7 +710,7 @@ class Event } switch ($format) { - // Format the exported data as a CSV file. + // Format the exported data as a CSV file. case "csv": $o .= '"Subject", "Start Date", "Start Time", "Description", "End Date", "End Time", "Location"' . PHP_EOL; @@ -728,7 +730,7 @@ class Event } break; - // Format the exported data as a ics file. + // Format the exported data as a ics file. case "ical": $o = 'BEGIN:VCALENDAR' . PHP_EOL . 'VERSION:2.0' . PHP_EOL @@ -929,8 +931,13 @@ class Event $location = self::locationToArray($item['event-location']); // Construct the profile link (magic-auth). - $author = ['uid' => 0, 'id' => $item['author-id'], - 'network' => $item['author-network'], 'url' => $item['author-link']]; + $author = [ + 'uid' => 0, + 'id' => $item['author-id'], + 'network' => $item['author-network'], + 'url' => $item['author-link'], + 'alias' => $item['author-alias'] + ]; $profile_link = Contact::magicLinkByContact($author); $tpl = Renderer::getMarkupTemplate('event_stream_item.tpl'); diff --git a/src/Model/Item.php b/src/Model/Item.php index 51ac03b4ef..de95d4e16c 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -108,31 +108,35 @@ class Item ]; // Field list that is used to deliver items via the protocols - const DELIVER_FIELDLIST = ['uid', 'id', 'parent', 'uri-id', 'uri', 'thr-parent', 'parent-uri', 'guid', - 'parent-guid', 'conversation', 'received', 'created', 'edited', 'verb', 'object-type', 'object', 'target', - 'private', 'title', 'body', 'raw-body', 'location', 'coord', 'app', - 'inform', 'deleted', 'extid', 'post-type', 'post-reason', 'gravity', - 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', - 'author-id', 'author-addr', 'author-link', 'author-name', 'author-avatar', 'owner-id', 'owner-link', 'contact-uid', - 'signed_text', 'network', 'wall', 'contact-id', 'plink', 'origin', - 'thr-parent-id', 'parent-uri-id', 'quote-uri', 'quote-uri-id', 'postopts', 'pubmail', - 'event-created', 'event-edited', 'event-start', 'event-finish', - 'event-summary', 'event-desc', 'event-location', 'event-type', - 'event-nofinish', 'event-ignore', 'event-id']; + const DELIVER_FIELDLIST = [ + 'uid', 'id', 'parent', 'uri-id', 'uri', 'thr-parent', 'parent-uri', 'guid', + 'parent-guid', 'conversation', 'received', 'created', 'edited', 'verb', 'object-type', 'object', 'target', + 'private', 'title', 'body', 'raw-body', 'location', 'coord', 'app', + 'inform', 'deleted', 'extid', 'post-type', 'post-reason', 'gravity', + 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', + 'author-id', 'author-addr', 'author-link', 'author-name', 'author-avatar', 'owner-id', 'owner-link', 'contact-uid', + 'signed_text', 'network', 'wall', 'contact-id', 'plink', 'origin', + 'thr-parent-id', 'parent-uri-id', 'quote-uri', 'quote-uri-id', 'postopts', 'pubmail', + 'event-created', 'event-edited', 'event-start', 'event-finish', + 'event-summary', 'event-desc', 'event-location', 'event-type', + 'event-nofinish', 'event-ignore', 'event-id' + ]; // All fields in the item table - const ITEM_FIELDLIST = ['id', 'uid', 'parent', 'uri', 'parent-uri', 'thr-parent', - 'guid', 'uri-id', 'parent-uri-id', 'thr-parent-id', 'conversation', 'vid', - 'quote-uri', 'quote-uri-id', 'contact-id', 'wall', 'gravity', 'extid', 'psid', - 'created', 'edited', 'commented', 'received', 'changed', 'verb', - 'postopts', 'plink', 'resource-id', 'event-id', 'inform', - 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'post-type', 'post-reason', - 'private', 'pubmail', 'visible', 'starred', - 'unseen', 'deleted', 'origin', 'mention', 'global', 'network', - 'title', 'content-warning', 'body', 'location', 'coord', 'app', - 'rendered-hash', 'rendered-html', 'object-type', 'object', 'target-type', 'target', - 'author-id', 'author-link', 'author-name', 'author-avatar', 'author-network', - 'owner-id', 'owner-link', 'owner-name', 'owner-avatar', 'causer-id']; + const ITEM_FIELDLIST = [ + 'id', 'uid', 'parent', 'uri', 'parent-uri', 'thr-parent', + 'guid', 'uri-id', 'parent-uri-id', 'thr-parent-id', 'conversation', 'vid', + 'quote-uri', 'quote-uri-id', 'contact-id', 'wall', 'gravity', 'extid', 'psid', + 'created', 'edited', 'commented', 'received', 'changed', 'verb', + 'postopts', 'plink', 'resource-id', 'event-id', 'inform', + 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'post-type', 'post-reason', + 'private', 'pubmail', 'visible', 'starred', + 'unseen', 'deleted', 'origin', 'mention', 'global', 'network', + 'title', 'content-warning', 'body', 'location', 'coord', 'app', + 'rendered-hash', 'rendered-html', 'object-type', 'object', 'target-type', 'target', + 'author-id', 'author-link', 'author-name', 'author-avatar', 'author-network', + 'owner-id', 'owner-link', 'owner-name', 'owner-avatar', 'causer-id' + ]; // List of all verbs that don't need additional content data. // Never reorder or remove entries from this list. Just add new ones at the end, if needed. @@ -140,7 +144,8 @@ class Item Activity::LIKE, Activity::DISLIKE, Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE, Activity::FOLLOW, - Activity::ANNOUNCE]; + Activity::ANNOUNCE + ]; // Privacy levels const PUBLIC = 0; @@ -191,8 +196,10 @@ class Item } // We only need to call the line by line update for specific fields - if (empty($fields['body']) && empty($fields['file']) && - empty($fields['attach']) && empty($fields['edited'])) { + if ( + empty($fields['body']) && empty($fields['file']) && + empty($fields['attach']) && empty($fields['edited']) + ) { return $rows; } @@ -319,9 +326,11 @@ class Item { Logger::info('Mark item for deletion by id', ['id' => $item_id, 'callstack' => System::callstack()]); // locate item to be deleted - $fields = ['id', 'uri', 'uri-id', 'uid', 'parent', 'parent-uri-id', 'origin', + $fields = [ + 'id', 'uri', 'uri-id', 'uid', 'parent', 'parent-uri-id', 'origin', 'deleted', 'resource-id', 'event-id', - 'verb', 'object-type', 'object', 'target', 'contact-id', 'psid', 'gravity']; + 'verb', 'object-type', 'object', 'target', 'contact-id', 'psid', 'gravity' + ]; $item = Post::selectFirst($fields, ['id' => $item_id]); if (!DBA::isResult($item)) { Logger::info('Item not found.', ['id' => $item_id]); @@ -359,7 +368,7 @@ class Item // If item has attachments, drop them $attachments = Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT]); - foreach($attachments as $attachment) { + foreach ($attachments as $attachment) { if (preg_match('|attach/(\d+)|', $attachment['url'], $matches)) { Attach::delete(['id' => $matches[1], 'uid' => $item['uid']]); } @@ -473,7 +482,7 @@ class Item private static function contactId(array $item): int { if ($item['uid'] == 0) { - return $item['author-id']; + return $item['owner-id']; } if ($item['origin']) { @@ -488,27 +497,20 @@ class Item } } - if ($item['gravity'] == self::GRAVITY_PARENT) { - if (Contact::isSharingByURL($item['owner-link'], $item['uid'], true)) { - $contact_id = Contact::getIdForURL($item['owner-link'], $item['uid']); + foreach (['owner-link', 'author-link', 'causer-link'] as $field) { + if (empty($item[$field])) { + continue; + } + if (Contact::isSharingByURL($item[$field], $item['uid'], true)) { + $contact_id = Contact::getIdForURL($item[$field], $item['uid']); } else { - $contact_id = Contact::getIdForURL($item['owner-link']); + $contact_id = Contact::getIdForURL($item[$field]); } if (!empty($contact_id)) { return $contact_id; } } - if (Contact::isSharingByURL($item['author-link'], $item['uid'], true)) { - $contact_id = Contact::getIdForURL($item['author-link'], $item['uid']); - } else { - $contact_id = Contact::getIdForURL($item['author-link']); - } - - if (!empty($contact_id)) { - return $contact_id; - } - Logger::warning('contact-id could not be fetched, using self contact instead.', ['uid' => $item['uid'], 'item' => $item]); $self = Contact::selectFirst(['id'], ['self' => true, 'uid' => $item['uid']]); return $self['id']; @@ -551,8 +553,10 @@ class Item return true; } - $condition = ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], - 'network' => [$item['network'], Protocol::DFRN]]; + $condition = [ + 'uri-id' => $item['uri-id'], 'uid' => $item['uid'], + 'network' => [$item['network'], Protocol::DFRN] + ]; if (Post::exists($condition)) { Logger::notice('duplicated item with the same uri found.', $condition); return true; @@ -567,8 +571,10 @@ class Item } } elseif ($item['network'] == Protocol::OSTATUS) { // Check for an existing post with the same content. There seems to be a problem with OStatus. - $condition = ["`body` = ? AND `network` = ? AND `created` = ? AND `contact-id` = ? AND `uid` = ?", - $item['body'], $item['network'], $item['created'], $item['contact-id'], $item['uid']]; + $condition = [ + "`body` = ? AND `network` = ? AND `created` = ? AND `contact-id` = ? AND `uid` = ?", + $item['body'], $item['network'], $item['created'], $item['contact-id'], $item['uid'] + ]; if (Post::exists($condition)) { Logger::notice('duplicated item with the same body found.', $item); return true; @@ -642,8 +648,10 @@ class Item return false; } - $condition = ['verb' => Activity::FOLLOW, 'uid' => $item['uid'], - 'parent-uri' => $item['parent-uri'], 'author-id' => $item['author-id']]; + $condition = [ + 'verb' => Activity::FOLLOW, 'uid' => $item['uid'], + 'parent-uri' => $item['parent-uri'], 'author-id' => $item['author-id'] + ]; if (Post::exists($condition)) { // It happens that we receive multiple follow requests by the same author - we only store one. Logger::info('Follow: Found existing follow request from author', ['author-id' => $item['author-id'], 'parent-uri' => $item['parent-uri']]); @@ -695,7 +703,8 @@ class Item private static function getDuplicateID(array $item): int { if (empty($item['network']) || in_array($item['network'], Protocol::FEDERATED)) { - $condition = ['`uri-id` = ? AND `uid` = ? AND `network` IN (?, ?, ?, ?)', + $condition = [ + '`uri-id` = ? AND `uid` = ? AND `network` IN (?, ?, ?, ?)', $item['uri-id'], $item['uid'], Protocol::ACTIVITYPUB, @@ -751,10 +760,12 @@ class Item */ private static function getTopLevelParent(array $item): array { - $fields = ['uid', 'uri', 'parent-uri', 'id', 'deleted', + $fields = [ + 'uid', 'uri', 'parent-uri', 'id', 'deleted', 'uri-id', 'parent-uri-id', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', - 'wall', 'private', 'origin', 'author-id']; + 'wall', 'private', 'origin', 'author-id' + ]; $condition = ['uri-id' => [$item['thr-parent-id'], $item['parent-uri-id']], 'uid' => $item['uid']]; $params = ['order' => ['id' => false]]; $parent = Post::selectFirst($fields, $condition, $params); @@ -779,9 +790,11 @@ class Item return $parent; } - $condition = ['uri-id' => $parent['parent-uri-id'], + $condition = [ + 'uri-id' => $parent['parent-uri-id'], 'parent-uri-id' => $parent['parent-uri-id'], - 'uid' => $parent['uid']]; + 'uid' => $parent['uid'] + ]; $params = ['order' => ['id' => false]]; $toplevel_parent = Post::selectFirst($fields, $condition, $params); @@ -946,7 +959,7 @@ class Item // Communities aren't working with the Diaspora protocol if (($uid != 0) && ($item['network'] == Protocol::DIASPORA)) { $user = User::getById($uid, ['account-type']); - if ($user['account-type'] == Contact::TYPE_COMMUNITY) { + if ($user['account-type'] == Contact::TYPE_COMMUNITY) { Logger::info('Community posts are not supported via Diaspora'); return 0; } @@ -966,12 +979,16 @@ class Item $item['gravity'] = self::getGravity($item); - $default = ['url' => $item['author-link'], 'name' => $item['author-name'], - 'photo' => $item['author-avatar'], 'network' => $item['network']]; + $default = [ + 'url' => $item['author-link'], 'name' => $item['author-name'], + 'photo' => $item['author-avatar'], 'network' => $item['network'] + ]; $item['author-id'] = ($item['author-id'] ?? 0) ?: Contact::getIdForURL($item['author-link'], 0, null, $default); - $default = ['url' => $item['owner-link'], 'name' => $item['owner-name'], - 'photo' => $item['owner-avatar'], 'network' => $item['network']]; + $default = [ + 'url' => $item['owner-link'], 'name' => $item['owner-name'], + 'photo' => $item['owner-avatar'], 'network' => $item['network'] + ]; $item['owner-id'] = ($item['owner-id'] ?? 0) ?: Contact::getIdForURL($item['owner-link'], 0, null, $default); $item['post-reason'] = self::getPostReason($item); @@ -982,8 +999,10 @@ class Item $item['contact-id'] = self::contactId($item); - if (!empty($item['direction']) && in_array($item['direction'], [Conversation::PUSH, Conversation::RELAY]) && - empty($item['origin']) && self::isTooOld($item)) { + if ( + !empty($item['direction']) && in_array($item['direction'], [Conversation::PUSH, Conversation::RELAY]) && + empty($item['origin']) && self::isTooOld($item) + ) { Logger::info('Item is too old', ['item' => $item]); return 0; } @@ -1124,7 +1143,8 @@ class Item $item['allow_gid'], $item['deny_cid'], $item['deny_gid'] - ))->id; + ) + )->id; if (!empty($item['extid'])) { $item['external-id'] = ItemURI::getIdByURI($item['extid']); @@ -1356,7 +1376,8 @@ class Item // Don't relay participation messages if (($posted_item['verb'] == Activity::FOLLOW) && - (!$posted_item['origin'] || ($posted_item['author-id'] != Contact::getPublicIdByUserId($uid)))) { + (!$posted_item['origin'] || ($posted_item['author-id'] != Contact::getPublicIdByUserId($uid))) + ) { Logger::info('Participation messages will not be relayed', ['item' => $posted_item['id'], 'uri' => $posted_item['uri'], 'verb' => $posted_item['verb']]); $transmit = false; } @@ -1429,8 +1450,10 @@ class Item */ private static function setOwnerforResharedItem(array $item) { - $parent = Post::selectFirst(['id', 'causer-id', 'owner-id', 'author-id', 'author-link', 'origin', 'post-reason'], - ['uri-id' => $item['thr-parent-id'], 'uid' => $item['uid']]); + $parent = Post::selectFirst( + ['id', 'causer-id', 'owner-id', 'author-id', 'author-link', 'origin', 'post-reason'], + ['uri-id' => $item['thr-parent-id'], 'uid' => $item['uid']] + ); if (!DBA::isResult($parent)) { Logger::error('Parent not found', ['uri-id' => $item['thr-parent-id'], 'uid' => $item['uid']]); return; @@ -1502,9 +1525,11 @@ class Item } // Only distribute public items from native networks - $condition = ['id' => $itemid, 'uid' => 0, - 'network' => array_merge(Protocol::FEDERATED ,['']), - 'visible' => true, 'deleted' => false, 'private' => [self::PUBLIC, self::UNLISTED]]; + $condition = [ + 'id' => $itemid, 'uid' => 0, + 'network' => array_merge(Protocol::FEDERATED, ['']), + 'visible' => true, 'deleted' => false, 'private' => [self::PUBLIC, self::UNLISTED] + ]; $item = Post::selectFirst(array_merge(self::ITEM_FIELDLIST, ['protocol']), $condition); if (!DBA::isResult($item)) { Logger::warning('Item not found', ['condition' => $condition]); @@ -1625,7 +1650,8 @@ class Item if (($uid != 0) && (($item['gravity'] == self::GRAVITY_PARENT) || $is_reshare) && DI::pConfig()->get($uid, 'system', 'accept_only_sharer') == self::COMPLETION_NONE && - !in_array($item['post-reason'], [self::PR_FOLLOWER, self::PR_TAG, self::PR_TO, self::PR_CC, self::PR_ACTIVITY, self::PR_AUDIENCE])) { + !in_array($item['post-reason'], [self::PR_FOLLOWER, self::PR_TAG, self::PR_TO, self::PR_CC, self::PR_ACTIVITY, self::PR_AUDIENCE]) + ) { Logger::info('Contact is not a follower, thread will not be stored', ['author' => $item['author-link'], 'uid' => $uid, 'uri-id' => $uri_id, 'post-reason' => $item['post-reason']]); return 0; } @@ -1821,7 +1847,7 @@ class Item } // is it an entry from a connector? Only add an entry for natively connected networks - if (!in_array($item["network"], array_merge(Protocol::FEDERATED ,['']))) { + if (!in_array($item["network"], array_merge(Protocol::FEDERATED, ['']))) { return; } @@ -2124,12 +2150,16 @@ class Item } // Now do the same for the system wide contacts with uid=0 if ($arr['private'] != self::PRIVATE) { - Contact::update(['failed' => false, 'local-data' => true, 'success_update' => $arr['received'], 'last-item' => $arr['received']], - ['id' => $arr['owner-id']]); + Contact::update( + ['failed' => false, 'local-data' => true, 'success_update' => $arr['received'], 'last-item' => $arr['received']], + ['id' => $arr['owner-id']] + ); if ($arr['owner-id'] != $arr['author-id']) { - Contact::update(['failed' => false, 'local-data' => true, 'success_update' => $arr['received'], 'last-item' => $arr['received']], - ['id' => $arr['author-id']]); + Contact::update( + ['failed' => false, 'local-data' => true, 'success_update' => $arr['received'], 'last-item' => $arr['received']], + ['id' => $arr['author-id']] + ); } } } @@ -2155,29 +2185,44 @@ class Item // All hashtags should point to the home server if "local_tags" is activated if (DI::config()->get('system', 'local_tags')) { - $body = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", - "#[url=" . DI::baseUrl() . "/search?tag=$2]$2[/url]", $body); + $body = preg_replace( + "/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", + "#[url=" . DI::baseUrl() . "/search?tag=$2]$2[/url]", + $body + ); } // mask hashtags inside of url, bookmarks and attachments to avoid urls in urls - $body = preg_replace_callback("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", + $body = preg_replace_callback( + "/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", function ($match) { return ("[url=" . str_replace("#", "#", $match[1]) . "]" . str_replace("#", "#", $match[2]) . "[/url]"); - }, $body); + }, + $body + ); - $body = preg_replace_callback("/\[bookmark\=([$URLSearchString]*)\](.*?)\[\/bookmark\]/ism", + $body = preg_replace_callback( + "/\[bookmark\=([$URLSearchString]*)\](.*?)\[\/bookmark\]/ism", function ($match) { return ("[bookmark=" . str_replace("#", "#", $match[1]) . "]" . str_replace("#", "#", $match[2]) . "[/bookmark]"); - }, $body); + }, + $body + ); - $body = preg_replace_callback("/\[attachment (.*?)\](.*?)\[\/attachment\]/ism", + $body = preg_replace_callback( + "/\[attachment (.*?)\](.*?)\[\/attachment\]/ism", function ($match) { return ("[attachment " . str_replace("#", "#", $match[1]) . "]" . $match[2] . "[/attachment]"); - }, $body); + }, + $body + ); // Repair recursive urls - $body = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", - "#$2", $body); + $body = preg_replace( + "/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", + "#$2", + $body + ); foreach ($tags as $tag) { if ((strpos($tag, '#') !== 0) || strpos($tag, '[url=') || strlen($tag) < 2 || $tag[1] == '#') { @@ -2329,10 +2374,13 @@ class Item } $datarray2 = $datarray; - Logger::info('remote-self start', ['contact' => $contact['url'], 'remote_self'=> $contact['remote_self'], 'item' => $datarray]); + Logger::info('remote-self start', ['contact' => $contact['url'], 'remote_self' => $contact['remote_self'], 'item' => $datarray]); - $self = DBA::selectFirst('contact', ['id', 'name', 'url', 'thumb'], - ['uid' => $contact['uid'], 'self' => true]); + $self = DBA::selectFirst( + 'contact', + ['id', 'name', 'url', 'thumb'], + ['uid' => $contact['uid'], 'self' => true] + ); if (!DBA::isResult($self)) { Logger::error('Self contact not found', ['uid' => $contact['uid']]); return false; @@ -2368,7 +2416,7 @@ class Item // Store the original post $result = self::insert($datarray2); - Logger::info('remote-self post original item', ['contact' => $contact['url'], 'result'=> $result, 'item' => $datarray2]); + Logger::info('remote-self post original item', ['contact' => $contact['url'], 'result' => $result, 'item' => $datarray2]); } else { $datarray['private'] = self::PUBLIC; $datarray['app'] = 'Feed'; @@ -2495,7 +2543,8 @@ class Item if (($obj1['allow_cid'] == $obj2['allow_cid']) && ($obj1['allow_gid'] == $obj2['allow_gid']) && ($obj1['deny_cid'] == $obj2['deny_cid']) - && ($obj1['deny_gid'] == $obj2['deny_gid'])) { + && ($obj1['deny_gid'] == $obj2['deny_gid']) + ) { return true; } @@ -2542,8 +2591,10 @@ class Item return; } - $condition = ["`uid` = ? AND NOT `deleted` AND `gravity` = ?", - $uid, self::GRAVITY_PARENT]; + $condition = [ + "`uid` = ? AND NOT `deleted` AND `gravity` = ?", + $uid, self::GRAVITY_PARENT + ]; /* * $expire_network_only = save your own wall posts @@ -2617,8 +2668,10 @@ class Item return false; } - $condition = ["`uid` = ? AND `wall` = ? AND NOT `deleted` AND `visible` AND `received` >= ?", - $uid, $wall, $user['register_date']]; + $condition = [ + "`uid` = ? AND `wall` = ? AND NOT `deleted` AND `visible` AND `received` >= ?", + $uid, $wall, $user['register_date'] + ]; $params = ['order' => ['received' => false]]; $thread = Post::selectFirstThread(['received'], $condition, $params); if (DBA::isResult($thread)) { @@ -2750,8 +2803,10 @@ class Item $vids = Verb::getID($activity); } - $condition = ['vid' => $vids, 'deleted' => false, 'gravity' => self::GRAVITY_ACTIVITY, - 'author-id' => $author_id, 'uid' => $uid, 'thr-parent-id' => $uri_id]; + $condition = [ + 'vid' => $vids, 'deleted' => false, 'gravity' => self::GRAVITY_ACTIVITY, + 'author-id' => $author_id, 'uid' => $uid, 'thr-parent-id' => $uri_id + ]; $like_item = Post::selectFirst(['id', 'guid', 'verb'], $condition); if (DBA::isResult($like_item)) { @@ -2855,12 +2910,14 @@ class Item // Profile owner - everything is visible $condition = []; } elseif ($remote_user) { - // Authenticated visitor - fetch the matching permissionsets + // Authenticated visitor - fetch the matching permissionsets $permissionSets = DI::permissionSet()->selectByContactId($remote_user, $owner_id); if (!empty($set)) { - $condition = ["(`private` != ? OR (`private` = ? AND `wall` + $condition = [ + "(`private` != ? OR (`private` = ? AND `wall` AND `psid` IN (" . implode(', ', array_fill(0, count($set), '?')) . ")))", - self::PRIVATE, self::PRIVATE]; + self::PRIVATE, self::PRIVATE + ]; $condition = array_merge($condition, $permissionSets->column('id')); } } @@ -2956,7 +3013,8 @@ class Item $rendered_hash = $item['rendered-hash'] ?? ''; $rendered_html = $item['rendered-html'] ?? ''; - if ($rendered_hash == '' + if ( + $rendered_hash == '' || $rendered_html == '' || $rendered_hash != hash('md5', BBCode::VERSION . '::' . $body) || DI::config()->get('system', 'ignore_cache') @@ -3261,8 +3319,10 @@ class Item } foreach ([0, 1, 2] as $size) { - if (preg_match('#/photo/.*-' . $size . '\.#ism', $url) && - strpos(preg_replace('#(/photo/.*)-[012]\.#ism', '$1-' . $size . '.', $body), $url)) { + if ( + preg_match('#/photo/.*-' . $size . '\.#ism', $url) && + strpos(preg_replace('#(/photo/.*)-[012]\.#ism', '$1-' . $size . '.', $body), $url) + ) { return true; } } @@ -3459,7 +3519,8 @@ class Item 'text' => '', 'title' => $attachment['name'] ?? '', 'type' => 'link', - 'url' => $attachment['url']]; + 'url' => $attachment['url'] + ]; if ($preview && !empty($attachment['preview'])) { if ($attachment['preview-width'] >= 500) { @@ -3549,8 +3610,13 @@ class Item continue; } - $author = ['uid' => 0, 'id' => $item['author-id'], - 'network' => $item['author-network'], 'url' => $item['author-link']]; + $author = [ + 'uid' => 0, + 'id' => $item['author-id'], + 'network' => $item['author-network'], + 'url' => $item['author-link'], + 'alias' => $item['author-alias'] + ]; $the_url = Contact::magicLinkByContact($author, $attachment['url']); $title = Strings::escapeHtml(trim(($attachment['description'] ?? '') ?: $attachment['url'])); @@ -3599,7 +3665,7 @@ class Item $summary = DI::l10n()->tt('%d voter.', '%d voters.', $question['voters']); } elseif (!empty($question['endtime'])) { $summary = DI::l10n()->t('Poll end: %s', Temporal::getRelativeDate($question['endtime'])); - } else { + } else { $summary = ''; } @@ -3608,7 +3674,7 @@ class Item '$options' => $options, '$summary' => $summary, ]); - } + } DI::profiler()->stopRecording(); return $content; } @@ -3637,8 +3703,13 @@ class Item ]; if (!empty($plink) && ($item['private'] == self::PRIVATE)) { - $author = ['uid' => 0, 'id' => $item['author-id'], - 'network' => $item['author-network'], 'url' => $item['author-link']]; + $author = [ + 'uid' => 0, + 'id' => $item['author-id'], + 'network' => $item['author-network'], + 'url' => $item['author-link'], + 'alias' => $item['author-alias'], + ]; $plink = Contact::magicLinkByContact($author, $plink); } diff --git a/src/Module/Contact.php b/src/Module/Contact.php index aad97fd167..6e480c1931 100644 --- a/src/Module/Contact.php +++ b/src/Module/Contact.php @@ -219,8 +219,7 @@ class Contact extends BaseModule DI::page()['aside'] .= $vcard_widget . $findpeople_widget . $follow_widget . $rel_widget . $circles_widget . $networks_widget . $account_widget; $tpl = Renderer::getMarkupTemplate('contacts-head.tpl'); - DI::page()['htmlhead'] .= Renderer::replaceMacros($tpl, [ - ]); + DI::page()['htmlhead'] .= Renderer::replaceMacros($tpl, []); $o = ''; Nav::setSelected('contact'); @@ -412,20 +411,41 @@ class Contact extends BaseModule $tabs_html = Renderer::replaceMacros($tabs_tpl, ['$tabs' => $tabs]); switch ($rel) { - case 'followers': $header = DI::l10n()->t('Followers'); break; - case 'following': $header = DI::l10n()->t('Following'); break; - case 'mutuals': $header = DI::l10n()->t('Mutual friends'); break; - case 'nothing': $header = DI::l10n()->t('No relationship'); break; - default: $header = DI::l10n()->t('Contacts'); + case 'followers': + $header = DI::l10n()->t('Followers'); + break; + case 'following': + $header = DI::l10n()->t('Following'); + break; + case 'mutuals': + $header = DI::l10n()->t('Mutual friends'); + break; + case 'nothing': + $header = DI::l10n()->t('No relationship'); + break; + default: + $header = DI::l10n()->t('Contacts'); } switch ($type) { - case 'pending': $header .= ' - ' . DI::l10n()->t('Pending'); break; - case 'blocked': $header .= ' - ' . DI::l10n()->t('Blocked'); break; - case 'hidden': $header .= ' - ' . DI::l10n()->t('Hidden'); break; - case 'ignored': $header .= ' - ' . DI::l10n()->t('Ignored'); break; - case 'collapsed': $header .= ' - ' . DI::l10n()->t('Collapsed'); break; - case 'archived': $header .= ' - ' . DI::l10n()->t('Archived'); break; + case 'pending': + $header .= ' - ' . DI::l10n()->t('Pending'); + break; + case 'blocked': + $header .= ' - ' . DI::l10n()->t('Blocked'); + break; + case 'hidden': + $header .= ' - ' . DI::l10n()->t('Hidden'); + break; + case 'ignored': + $header .= ' - ' . DI::l10n()->t('Ignored'); + break; + case 'collapsed': + $header .= ' - ' . DI::l10n()->t('Collapsed'); + break; + case 'archived': + $header .= ' - ' . DI::l10n()->t('Archived'); + break; } $header .= $nets ? ' - ' . ContactSelector::networkToName($nets) : ''; @@ -512,7 +532,8 @@ class Contact extends BaseModule 'id' => 'media-tab', 'accesskey' => 'd', ], - ['label' => DI::l10n()->t('Contacts'), + [ + 'label' => DI::l10n()->t('Contacts'), 'url' => 'contact/' . $pcid . '/contacts', 'sel' => (($active_tab == self::TAB_CONTACTS) ? 'active' : ''), 'title' => DI::l10n()->t('View all known contacts'), @@ -522,7 +543,8 @@ class Contact extends BaseModule ]; if (!empty($contact['network']) && in_array($contact['network'], [Protocol::FEED, Protocol::MAIL]) && ($cid != $pcid)) { - $tabs[] = ['label' => DI::l10n()->t('Advanced'), + $tabs[] = [ + 'label' => DI::l10n()->t('Advanced'), 'url' => 'contact/' . $cid . '/advanced/', 'sel' => (($active_tab == self::TAB_ADVANCED) ? 'active' : ''), 'title' => DI::l10n()->t('Advanced Contact Settings'), diff --git a/src/Module/Contact/Unfollow.php b/src/Module/Contact/Unfollow.php index 9bbc34eeed..670fe57e69 100644 --- a/src/Module/Contact/Unfollow.php +++ b/src/Module/Contact/Unfollow.php @@ -93,7 +93,7 @@ class Unfollow extends \Friendica\BaseModule Strings::normaliseLink($url), Strings::normaliseLink($url), $url, ]; - $contact = $this->database->selectFirst('contact', ['url', 'id', 'uid', 'network', 'addr', 'name'], $condition); + $contact = $this->database->selectFirst('contact', ['url', 'alias', 'id', 'uid', 'network', 'addr', 'name'], $condition); if (!$this->database->isResult($contact)) { $this->systemMessages->addNotice($this->t("You aren't following this contact.")); $this->baseUrl->redirect($base_return_path); diff --git a/src/Object/Post.php b/src/Object/Post.php index 1fa7588b41..2f68b1c53e 100644 --- a/src/Object/Post.php +++ b/src/Object/Post.php @@ -91,9 +91,13 @@ class Post } $this->writable = $this->getDataValue('writable') || $this->getDataValue('self'); - $author = ['uid' => 0, 'id' => $this->getDataValue('author-id'), + $author = [ + 'uid' => 0, + 'id' => $this->getDataValue('author-id'), 'network' => $this->getDataValue('author-network'), - 'url' => $this->getDataValue('author-link')]; + 'url' => $this->getDataValue('author-link'), + 'alias' => $this->getDataValue('author-alias') + ]; $this->redirect_url = Contact::magicLinkByContact($author); if (!$this->isToplevel()) { $this->threaded = true; @@ -286,8 +290,13 @@ class Post } if (DI::userSession()->isAuthenticated()) { - $author = ['uid' => 0, 'id' => $item['author-id'], - 'network' => $item['author-network'], 'url' => $item['author-link']]; + $author = [ + 'uid' => 0, + 'id' => $item['author-id'], + 'network' => $item['author-network'], + 'url' => $item['author-link'], + 'alias' => $item['author-alias'], + ]; $profile_link = Contact::magicLinkByContact($author); } else { $profile_link = $item['author-link']; @@ -388,7 +397,7 @@ class Post } if ($conv->isWritable()) { - $buttons['like'] = [DI::l10n()->t("I like this \x28toggle\x29") , DI::l10n()->t('Like')]; + $buttons['like'] = [DI::l10n()->t("I like this \x28toggle\x29"), DI::l10n()->t('Like')]; $buttons['dislike'] = [DI::l10n()->t("I don't like this \x28toggle\x29"), DI::l10n()->t('Dislike')]; if ($shareable) { $buttons['share'] = [DI::l10n()->t('Quote share this'), DI::l10n()->t('Quote Share')]; @@ -451,8 +460,10 @@ class Post // Fetching of Diaspora posts doesn't always work. There are issues with reshares and possibly comments if (!DI::userSession()->getLocalUserId() && ($item['network'] != Protocol::DIASPORA) && !empty(DI::session()->get('remote_comment'))) { - $remote_comment = [DI::l10n()->t('Comment this item on your system'), DI::l10n()->t('Remote comment'), - str_replace('{uri}', urlencode($item['uri']), DI::session()->get('remote_comment'))]; + $remote_comment = [ + DI::l10n()->t('Comment this item on your system'), DI::l10n()->t('Remote comment'), + str_replace('{uri}', urlencode($item['uri']), DI::session()->get('remote_comment')) + ]; // Ensure to either display the remote comment or the local activities $buttons = []; @@ -670,7 +681,6 @@ class Post $title = DI::l10n()->t('Reacted with %s by: %s', $element['emoji'], $actors); $icon = []; break; - break; } $emojis[$index] = ['emoji' => $element['emoji'], 'total' => $element['total'], 'title' => $title, 'icon' => $icon]; } @@ -719,8 +729,10 @@ class Post if ($item->getDataValue('network') === Protocol::MAIL && DI::userSession()->getLocalUserId() != $item->getDataValue('uid')) { Logger::warning('Post object does not belong to local user', ['post' => $item, 'local_user' => DI::userSession()->getLocalUserId()]); return false; - } elseif (DI::activity()->match($item->getDataValue('verb'), Activity::LIKE) || - DI::activity()->match($item->getDataValue('verb'), Activity::DISLIKE)) { + } elseif ( + DI::activity()->match($item->getDataValue('verb'), Activity::LIKE) || + DI::activity()->match($item->getDataValue('verb'), Activity::DISLIKE) + ) { Logger::warning('Post objects is a like/dislike', ['post' => $item]); return false; } @@ -1004,8 +1016,10 @@ class Post } $profile = Contact::getByURL($term['url'], false, ['addr', 'contact-type']); - if (!empty($profile['addr']) && (($profile['contact-type'] ?? Contact::TYPE_UNKNOWN) != Contact::TYPE_COMMUNITY) && - ($profile['addr'] != $owner['addr']) && !strstr($text, $profile['addr'])) { + if ( + !empty($profile['addr']) && (($profile['contact-type'] ?? Contact::TYPE_UNKNOWN) != Contact::TYPE_COMMUNITY) && + ($profile['addr'] != $owner['addr']) && !strstr($text, $profile['addr']) + ) { $text .= '@' . $profile['addr'] . ' '; } } @@ -1133,6 +1147,7 @@ class Post 'id' => $this->getDataValue('owner-id'), 'network' => $this->getDataValue('owner-network'), 'url' => $this->getDataValue('owner-link'), + 'alias' => $this->getDataValue('owner-alias'), ]; $this->owner_url = Contact::magicLinkByContact($owner); } diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 92ed8c8df1..33fd222c03 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -56,7 +56,7 @@ use Friendica\Database\DBA; // This file is required several times during the test in DbaDefinition which justifies this condition if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1520); + define('DB_UPDATE_VERSION', 1521); } return [ diff --git a/static/dbview.config.php b/static/dbview.config.php index b960cfaf3d..17d99d9499 100644 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -149,6 +149,7 @@ "author-addr" => ["author", "addr"], "author-name" => "IF (`contact`.`url` = `author`.`url` AND `contact`.`name` != '', `contact`.`name`, `author`.`name`)", "author-nick" => ["author", "nick"], + "author-alias" => ["author", "alias"], "author-avatar" => "IF (`contact`.`url` = `author`.`url` AND `contact`.`thumb` != '', `contact`.`thumb`, `author`.`thumb`)", "author-network" => ["author", "network"], "author-blocked" => ["author", "blocked"], @@ -161,6 +162,7 @@ "owner-addr" => ["owner", "addr"], "owner-name" => "IF (`contact`.`url` = `owner`.`url` AND `contact`.`name` != '', `contact`.`name`, `owner`.`name`)", "owner-nick" => ["owner", "nick"], + "owner-alias" => ["owner", "alias"], "owner-avatar" => "IF (`contact`.`url` = `owner`.`url` AND `contact`.`thumb` != '', `contact`.`thumb`, `owner`.`thumb`)", "owner-network" => ["owner", "network"], "owner-blocked" => ["owner", "blocked"], @@ -324,6 +326,7 @@ "author-addr" => ["author", "addr"], "author-name" => "IF (`contact`.`url` = `author`.`url` AND `contact`.`name` != '', `contact`.`name`, `author`.`name`)", "author-nick" => ["author", "nick"], + "author-alias" => ["author", "alias"], "author-avatar" => "IF (`contact`.`url` = `author`.`url` AND `contact`.`thumb` != '', `contact`.`thumb`, `author`.`thumb`)", "author-network" => ["author", "network"], "author-blocked" => ["author", "blocked"], @@ -336,6 +339,7 @@ "owner-addr" => ["owner", "addr"], "owner-name" => "IF (`contact`.`url` = `owner`.`url` AND `contact`.`name` != '', `contact`.`name`, `owner`.`name`)", "owner-nick" => ["owner", "nick"], + "owner-alias" => ["owner", "alias"], "owner-avatar" => "IF (`contact`.`url` = `owner`.`url` AND `contact`.`thumb` != '', `contact`.`thumb`, `owner`.`thumb`)", "owner-network" => ["owner", "network"], "owner-blocked" => ["owner", "blocked"], @@ -485,6 +489,7 @@ "author-addr" => ["author", "addr"], "author-name" => ["author", "name"], "author-nick" => ["author", "nick"], + "author-alias" => ["author", "alias"], "author-avatar" => ["author", "thumb"], "author-network" => ["author", "network"], "author-blocked" => ["author", "blocked"], @@ -497,6 +502,7 @@ "owner-addr" => ["owner", "addr"], "owner-name" => ["owner", "name"], "owner-nick" => ["owner", "nick"], + "owner-alias" => ["owner", "alias"], "owner-avatar" => ["owner", "thumb"], "owner-network" => ["owner", "network"], "owner-blocked" => ["owner", "blocked"], @@ -623,6 +629,7 @@ "author-addr" => ["author", "addr"], "author-name" => ["author", "name"], "author-nick" => ["author", "nick"], + "author-alias" => ["author", "alias"], "author-avatar" => ["author", "thumb"], "author-network" => ["author", "network"], "author-blocked" => ["author", "blocked"], @@ -635,6 +642,7 @@ "owner-addr" => ["owner", "addr"], "owner-name" => ["owner", "name"], "owner-nick" => ["owner", "nick"], + "owner-alias" => ["owner", "alias"], "owner-avatar" => ["owner", "thumb"], "owner-network" => ["owner", "network"], "owner-blocked" => ["owner", "blocked"],