X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fconversation.php;h=1f337859b50c0bad9543a00280694bba4465d753;hb=fd73b0e1d2866701ed48d432ebcc0b32ee10a09f;hp=3261311012b4eba8c6da9f09cdc88488e1ce8979;hpb=dc2fd43c822f17c652782a7126b1bae51f213683;p=friendica.git diff --git a/include/conversation.php b/include/conversation.php index 3261311012..1f337859b5 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1,6 +1,6 @@ $new_body, 'images' => $saved_image]; -} - -function item_redir_and_replace_images($body, $images, $cid) { - - $origbody = $body; - $newbody = ''; - - $cnt = 1; - $pos = BBCode::getTagPosition($origbody, 'url', 0); - while ($pos !== false && $cnt < 1000) { - - $search = '/\[url\=(.*?)\]\[!#saved_image([0-9]*)#!\]\[\/url\]' . '/is'; - $replace = '[url=' . DI::baseUrl() . '/redir/' . $cid - . '?url=' . '$1' . '][!#saved_image' . '$2' .'#!][/url]'; - - $newbody .= substr($origbody, 0, $pos['start']['open']); - $subject = substr($origbody, $pos['start']['open'], $pos['end']['close'] - $pos['start']['open']); - $origbody = substr($origbody, $pos['end']['close']); - if ($origbody === false) { - $origbody = ''; - } - - $subject = preg_replace($search, $replace, $subject); - $newbody .= $subject; - - $cnt++; - // Isn't this supposed to use $cnt value for $occurrences? - @MrPetovan - $pos = BBCode::getTagPosition($origbody, 'url', 0); - } - $newbody .= $origbody; - - $cnt = 0; - foreach ($images as $image) { - /* - * We're depending on the property of 'foreach' (specified on the PHP website) that - * it loops over the array starting from the first element and going sequentially - * to the last element. - */ - $newbody = str_replace('[!#saved_image' . $cnt . '#!]', '[img]' . $image . '[/img]', $newbody); - $cnt++; - } - return $newbody; -} - /** * Render actions localized * @@ -140,12 +56,8 @@ function item_redir_and_replace_images($body, $images, $cid) { */ function localize_item(&$item) { - $extracted = item_extract_images($item['body']); - if ($extracted['images']) { - $item['body'] = item_redir_and_replace_images($extracted['body'], $extracted['images'], $item['contact-id']); - } - - /// @todo The following functionality needs to be cleaned up. + DI::profiler()->startRecording('rendering'); + /// @todo The following functionality needs to be cleaned up. if (!empty($item['verb'])) { $activity = DI::activity(); @@ -154,15 +66,14 @@ function localize_item(&$item) if (stristr($item['verb'], Activity::POKE)) { $verb = urldecode(substr($item['verb'], strpos($item['verb'],'#') + 1)); if (!$verb) { + DI::profiler()->stopRecording(); return; } if ($item['object-type'] == "" || $item['object-type'] !== Activity\ObjectType::PERSON) { + DI::profiler()->stopRecording(); return; } - $Aname = $item['author-name']; - $Alink = $item['author-link']; - $obj = XML::parseString($xmlhead . $item['object']); $Bname = $obj->title; @@ -177,9 +88,17 @@ function localize_item(&$item) } } - $A = '[url=' . Contact::magicLink($Alink) . ']' . $Aname . '[/url]'; - $B = '[url=' . Contact::magicLink($Blink) . ']' . $Bname . '[/url]'; - if ($Bphoto != "") { + $author = ['uid' => 0, 'id' => $item['author-id'], + 'network' => $item['author-network'], 'url' => $item['author-link']]; + $A = '[url=' . Contact::magicLinkByContact($author) . ']' . $item['author-name'] . '[/url]'; + + if (!empty($Blink)) { + $B = '[url=' . Contact::magicLink($Blink) . ']' . $Bname . '[/url]'; + } else { + $B = ''; + } + + if ($Bphoto != "" && !empty($Blink)) { $Bphoto = '[url=' . Contact::magicLink($Blink) . '][img=80x80]' . $Bphoto . '[/img][/url]'; } @@ -204,6 +123,7 @@ function localize_item(&$item) 'verb', 'object-type', 'resource-id', 'body', 'plink']; $obj = Post::selectFirst($fields, ['uri' => $item['parent-uri']]); if (!DBA::isResult($obj)) { + DI::profiler()->stopRecording(); return; } @@ -254,21 +174,14 @@ function localize_item(&$item) } } - // add zrl's to public images - $photo_pattern = "/\[url=(.*?)\/photos\/(.*?)\/image\/(.*?)\]\[img(.*?)\]h(.*?)\[\/img\]\[\/url\]/is"; - if (preg_match($photo_pattern, $item['body'])) { - $photo_replace = '[url=' . Profile::zrl('$1' . '/photos/' . '$2' . '/image/' . '$3' , true) . '][img' . '$4' . ']h' . '$5' . '[/img][/url]'; - $item['body'] = BBCode::pregReplaceInTag($photo_pattern, $photo_replace, 'url', $item['body']); - } - // add sparkle links to appropriate permalinks - $author = ['uid' => 0, 'id' => $item['author-id'], - 'network' => $item['author-network'], 'url' => $item['author-link']]; - // Only create a redirection to a magic link when logged in if (!empty($item['plink']) && Session::isAuthenticated()) { + $author = ['uid' => 0, 'id' => $item['author-id'], + 'network' => $item['author-network'], 'url' => $item['author-link']]; $item['plink'] = Contact::magicLinkByContact($author, $item['plink']); } + DI::profiler()->stopRecording(); } /** @@ -355,6 +268,7 @@ function conv_get_blocklist() */ function conversation(App $a, array $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0) { + DI::profiler()->startRecording('rendering'); $page = DI::page(); $page->registerFooterScript(Theme::getPathForFile('asset/typeahead.js/dist/typeahead.bundle.js')); @@ -364,7 +278,6 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o $ssl_state = (local_user() ? true : false); - $profile_owner = 0; $live_update_div = ''; $blocklist = conv_get_blocklist(); @@ -373,7 +286,6 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o if ($mode === 'network') { $items = conversation_add_children($items, false, $order, $uid); - $profile_owner = local_user(); if (!$update) { /* * The special div is needed for liveUpdate to kick in for this page. @@ -400,7 +312,6 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o } } elseif ($mode === 'profile') { $items = conversation_add_children($items, false, $order, $uid); - $profile_owner = $a->profile['uid']; if (!$update) { $tab = 'posts'; @@ -414,13 +325,12 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o */ $live_update_div = '
' . "\r\n" - . "\r\n"; } } } elseif ($mode === 'notes') { $items = conversation_add_children($items, false, $order, local_user()); - $profile_owner = local_user(); if (!$update) { $live_update_div = '' . "\r\n" @@ -429,7 +339,6 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o } } elseif ($mode === 'display') { $items = conversation_add_children($items, false, $order, $uid); - $profile_owner = $a->profile['uid']; if (!$update) { $live_update_div = '' . "\r\n" @@ -438,7 +347,6 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o } } elseif ($mode === 'community') { $items = conversation_add_children($items, true, $order, $uid); - $profile_owner = 0; if (!$update) { $live_update_div = '' . "\r\n" @@ -449,7 +357,6 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o } } elseif ($mode === 'contacts') { $items = conversation_add_children($items, false, $order, $uid); - $profile_owner = 0; if (!$update) { $live_update_div = '' . "\r\n" @@ -460,7 +367,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o $live_update_div = '' . "\r\n"; } - $page_dropping = ((local_user() && local_user() == $profile_owner) ? true : false); + $page_dropping = ((local_user() && local_user() == $uid) ? true : false); if (!$update) { $_SESSION['return_path'] = DI::args()->getQueryString(); @@ -477,7 +384,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o 'attendyes' => [], 'attendno' => [], 'attendmaybe' => [], - 'announce' => [], + 'announce' => [], ]; if (DI::pConfig()->get(local_user(), 'system', 'hide_dislike')) { @@ -574,7 +481,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o $body_html = Item::prepareBody($item, true, $preview); - list($categories, $folders) = DI::contentItem()->determineCategoriesTerms($item); + list($categories, $folders) = DI::contentItem()->determineCategoriesTerms($item, local_user()); if (!empty($item['content-warning']) && DI::pConfig()->get(local_user(), 'system', 'disable_cw', false)) { $title = ucfirst($item['content-warning']); @@ -599,7 +506,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o 'name' => $profile_name, 'sparkle' => $sparkle, 'lock' => false, - 'thumb' => DI::baseUrl()->remove($item['author-avatar']), + 'thumb' => DI::baseUrl()->remove(Contact::getAvatarUrlForUrl($item['author-link'], $item['uid'], Proxy::SIZE_THUMB)), 'title' => $title, 'body_html' => $body_html, 'tags' => $tags['tags'], @@ -619,7 +526,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o 'indent' => '', 'owner_name' => '', 'owner_url' => '', - 'owner_photo' => DI::baseUrl()->remove($item['owner-avatar']), + 'owner_photo' => DI::baseUrl()->remove(Contact::getAvatarUrlForUrl($item['owner-link'], $item['uid'], Proxy::SIZE_THUMB)), 'plink' => Item::getPlink($item), 'edpost' => false, 'isstarred' => 'unstarred', @@ -698,102 +605,96 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o '$remove' => DI::l10n()->t('remove'), '$mode' => $mode, '$update' => $update, - '$user' => $a->user, '$threads' => $threads, '$dropping' => ($page_dropping ? DI::l10n()->t('Delete Selected Items') : False), ]); + DI::profiler()->stopRecording(); return $o; } /** - * Fetch all comments from a query. Additionally set the newest resharer as thread owner. + * Adds some information (Causer, post reason, direction) to the fetched post row. * - * @param mixed $thread_items Database statement with thread posts - * @param boolean $pinned Is the item pinned? - * @param array $activity Contact data of the resharer + * @param array $row Post row + * @param array $activity Contact data of the resharer * * @return array items with parents and comments */ -function conversation_fetch_comments($thread_items, bool $pinned, array $activity) { - $comments = []; - - while ($row = Item::fetch($thread_items)) { - if (!empty($activity)) { - if (($row['gravity'] == GRAVITY_PARENT)) { - $row['post-type'] = Item::PT_ANNOUNCEMENT; - $row = array_merge($row, $activity); - $contact = Contact::getById($activity['causer-id'], ['url', 'name', 'thumb']); - $row['causer-link'] = $contact['url']; - $row['causer-avatar'] = $contact['thumb']; - $row['causer-name'] = $contact['name']; - } elseif (($row['gravity'] == GRAVITY_ACTIVITY) && ($row['verb'] == Activity::ANNOUNCE) && - ($row['author-id'] == $activity['causer-id'])) { - continue; - } - } +function conversation_add_row_information(array $row, array $activity) { + DI::profiler()->startRecording('rendering'); - $name = $row['causer-contact-type'] == Contact::TYPE_RELAY ? $row['causer-link'] : $row['causer-name']; + if ($row['uid'] == 0) { + $row['writable'] = in_array($row['network'], Protocol::FEDERATED); + } - switch ($row['post-type']) { - case Item::PT_TO: - $row['direction'] = ['direction' => 7, 'title' => DI::l10n()->t('You had been addressed (%s).', 'to')]; - break; - case Item::PT_CC: - $row['direction'] = ['direction' => 7, 'title' => DI::l10n()->t('You had been addressed (%s).', 'cc')]; - break; - case Item::PT_BTO: - $row['direction'] = ['direction' => 7, 'title' => DI::l10n()->t('You had been addressed (%s).', 'bto')]; - break; - case Item::PT_BCC: - $row['direction'] = ['direction' => 7, 'title' => DI::l10n()->t('You had been addressed (%s).', 'bcc')]; - break; - case Item::PT_FOLLOWER: - $row['direction'] = ['direction' => 6, 'title' => DI::l10n()->t('You are following %s.', $row['author-name'])]; - break; - case Item::PT_TAG: - $row['direction'] = ['direction' => 4, 'title' => DI::l10n()->t('Tagged')]; - break; - case Item::PT_ANNOUNCEMENT: - if (!empty($row['causer-id']) && DI::pConfig()->get(local_user(), 'system', 'display_resharer')) { - $row['owner-id'] = $row['causer-id']; - $row['owner-link'] = $row['causer-link']; - $row['owner-avatar'] = $row['causer-avatar']; - $row['owner-name'] = $row['causer-name']; - } + if (!empty($activity)) { + if (($row['gravity'] == GRAVITY_PARENT)) { + $row['post-reason'] = Item::PR_ANNOUNCEMENT; + $row = array_merge($row, $activity); + $contact = Contact::getById($activity['causer-id'], ['url', 'name', 'thumb']); + $row['causer-link'] = $contact['url']; + $row['causer-avatar'] = $contact['thumb']; + $row['causer-name'] = $contact['name']; + } elseif (($row['gravity'] == GRAVITY_ACTIVITY) && ($row['verb'] == Activity::ANNOUNCE) && + ($row['author-id'] == $activity['causer-id'])) { + return $row; + } + } - if (($row['gravity'] == GRAVITY_PARENT) && !empty($row['causer-id'])) { - $row['reshared'] = DI::l10n()->t('%s reshared this.', '' . htmlentities($name) . ''); - } - $row['direction'] = ['direction' => 3, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Reshared') : DI::l10n()->t('Reshared by %s', $name))]; - break; - case Item::PT_COMMENT: - $row['direction'] = ['direction' => 5, 'title' => DI::l10n()->t('%s is participating in this thread.', $row['author-name'])]; - break; - case Item::PT_STORED: - $row['direction'] = ['direction' => 8, 'title' => DI::l10n()->t('Stored')]; - break; - case Item::PT_GLOBAL: - $row['direction'] = ['direction' => 9, 'title' => DI::l10n()->t('Global')]; - break; - case Item::PT_RELAY: - $row['direction'] = ['direction' => 10, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Relayed') : DI::l10n()->t('Relayed by %s.', $name))]; - break; - case Item::PT_FETCHED: - $row['direction'] = ['direction' => 2, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Fetched') : DI::l10n()->t('Fetched because of %s', $name))]; - break; + switch ($row['post-reason']) { + case Item::PR_TO: + $row['direction'] = ['direction' => 7, 'title' => DI::l10n()->t('You had been addressed (%s).', 'to')]; + break; + case Item::PR_CC: + $row['direction'] = ['direction' => 7, 'title' => DI::l10n()->t('You had been addressed (%s).', 'cc')]; + break; + case Item::PR_BTO: + $row['direction'] = ['direction' => 7, 'title' => DI::l10n()->t('You had been addressed (%s).', 'bto')]; + break; + case Item::PR_BCC: + $row['direction'] = ['direction' => 7, 'title' => DI::l10n()->t('You had been addressed (%s).', 'bcc')]; + break; + case Item::PR_FOLLOWER: + $row['direction'] = ['direction' => 6, 'title' => DI::l10n()->t('You are following %s.', $row['author-name'])]; + break; + case Item::PR_TAG: + $row['direction'] = ['direction' => 4, 'title' => DI::l10n()->t('Tagged')]; + break; + case Item::PR_ANNOUNCEMENT: + if (!empty($row['causer-id']) && DI::pConfig()->get(local_user(), 'system', 'display_resharer')) { + $row['owner-id'] = $row['causer-id']; + $row['owner-link'] = $row['causer-link']; + $row['owner-avatar'] = $row['causer-avatar']; + $row['owner-name'] = $row['causer-name']; } - if ($row['gravity'] == GRAVITY_PARENT) { - $row['pinned'] = $pinned; - } - - $comments[] = $row; + if (($row['gravity'] == GRAVITY_PARENT) && !empty($row['causer-id'])) { + $causer = ['uid' => 0, 'id' => $row['causer-id'], + 'network' => $row['causer-network'], 'url' => $row['causer-link']]; + $row['reshared'] = DI::l10n()->t('%s reshared this.', '' . htmlentities($row['causer-name']) . ''); + } + $row['direction'] = ['direction' => 3, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Reshared') : DI::l10n()->t('Reshared by %s <%s>', $row['causer-name'], $row['causer-link']))]; + break; + case Item::PR_COMMENT: + $row['direction'] = ['direction' => 5, 'title' => DI::l10n()->t('%s is participating in this thread.', $row['author-name'])]; + break; + case Item::PR_STORED: + $row['direction'] = ['direction' => 8, 'title' => DI::l10n()->t('Stored')]; + break; + case Item::PR_GLOBAL: + $row['direction'] = ['direction' => 9, 'title' => DI::l10n()->t('Global')]; + break; + case Item::PR_RELAY: + $row['direction'] = ['direction' => 10, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Relayed') : DI::l10n()->t('Relayed by %s <%s>', $row['causer-name'], $row['causer-link']))]; + break; + case Item::PR_FETCHED: + $row['direction'] = ['direction' => 2, 'title' => (empty($row['causer-id']) ? DI::l10n()->t('Fetched') : DI::l10n()->t('Fetched because of %s <%s>', $row['causer-name'], $row['causer-link']))]; + break; } - DBA::close($thread_items); - - return $comments; + DI::profiler()->stopRecording(); + return $row; } /** @@ -811,78 +712,79 @@ function conversation_fetch_comments($thread_items, bool $pinned, array $activit * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ function conversation_add_children(array $parents, $block_authors, $order, $uid) { + DI::profiler()->startRecording('rendering'); if (count($parents) > 1) { $max_comments = DI::config()->get('system', 'max_comments', 100); } else { $max_comments = DI::config()->get('system', 'max_display_comments', 1000); } - $params = ['order' => ['gravity', 'uid', 'commented' => true]]; - - if ($max_comments > 0) { - $params['limit'] = $max_comments; - } + $params = ['order' => ['uri-id' => true, 'uid' => true]]; - $items = []; + $activities = []; + $uriids = []; + $commentcounter = []; + $activitycounter = []; foreach ($parents AS $parent) { if (!empty($parent['thr-parent-id']) && !empty($parent['gravity']) && ($parent['gravity'] == GRAVITY_ACTIVITY)) { - $condition = ["`item`.`parent-uri-id` = ? AND `item`.`uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)", - $parent['thr-parent-id'], $uid, Verb::getID(Activity::FOLLOW)]; + $uriid = $parent['thr-parent-id']; if (!empty($parent['author-id'])) { - $activity = ['causer-id' => $parent['author-id']]; + $activities[$uriid] = ['causer-id' => $parent['author-id']]; foreach (['commented', 'received', 'created'] as $orderfields) { if (!empty($parent[$orderfields])) { - $activity[$orderfields] = $parent[$orderfields]; - } + $activities[$uriid][$orderfields] = $parent[$orderfields]; + } } } } else { - $condition = ["`item`.`parent-uri` = ? AND `item`.`uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)", - $parent['uri'], $uid, Verb::getID(Activity::FOLLOW)]; - $activity = []; + $uriid = $parent['uri-id']; } - $items = conversation_fetch_items($parent, $items, $condition, $block_authors, $params, $activity); + $uriids[] = $uriid; + + $commentcounter[$uriid] = 0; + $activitycounter[$uriid] = 0; } - foreach ($items as $index => $item) { - if ($item['uid'] == 0) { - $items[$index]['writable'] = in_array($item['network'], Protocol::FEDERATED); - } + $condition = ['parent-uri-id' => $uriids]; + if ($block_authors) { + $condition['author-hidden'] = false; } - $items = conv_sort($items, $order); + $condition = DBA::mergeConditions($condition, + ["`uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)", $uid, Verb::getID(Activity::FOLLOW)]); - return $items; -} + $thread_items = Post::selectForUser(local_user(), array_merge(Item::DISPLAY_FIELDLIST, ['pinned', 'contact-uid', 'gravity', 'post-type', 'post-reason']), $condition, $params); -/** - * Fetch conversation items - * - * @param array $parent Parent Item array - * @param array $items Item array - * @param array $condition SQL condition - * @param boolean $block_authors Don't show posts from contacts that are hidden (used on the community page) - * @param array $params SQL parameters - * @param array $activity Contact data of the resharer - * @return array - */ -function conversation_fetch_items(array $parent, array $items, array $condition, bool $block_authors, array $params, array $activity) { - if ($block_authors) { - $condition[0] .= " AND NOT `author`.`hidden`"; + $items = []; + + while ($row = Post::fetch($thread_items)) { + if (!empty($items[$row['uri-id']]) && ($row['uid'] == 0)) { + continue; + } + + if ($max_comments > 0) { + if (($row['gravity'] == GRAVITY_COMMENT) && (++$commentcounter[$row['parent-uri-id']] > $max_comments)) { + continue; + } + if (($row['gravity'] == GRAVITY_ACTIVITY) && (++$activitycounter[$row['parent-uri-id']] > $max_comments)) { + continue; + } + } + $items[$row['uri-id']] = conversation_add_row_information($row, $activities[$row['uri-id']] ?? []); } - $thread_items = Item::selectForUser(local_user(), array_merge(Item::DISPLAY_FIELDLIST, ['pinned', 'contact-uid', 'gravity', 'post-type']), $condition, $params); + DBA::close($thread_items); - $comments = conversation_fetch_comments($thread_items, $parent['pinned'] ?? false, $activity); + $items = conv_sort($items, $order); - if (count($comments) != 0) { - $items = array_merge($items, $comments); - } + DI::profiler()->stopRecording(); return $items; } -function item_photo_menu($item) { +function item_photo_menu($item) +{ + DI::profiler()->startRecording('rendering'); $sub_link = ''; $poke_link = ''; $contact_url = ''; @@ -893,8 +795,8 @@ function item_photo_menu($item) { $block_link = ''; $ignore_link = ''; - if (local_user() && local_user() == $item['uid'] && $item['gravity'] == GRAVITY_PARENT && !$item['self']) { - $sub_link = 'javascript:dosubthread(' . $item['id'] . '); return false;'; + if (local_user() && local_user() == $item['uid'] && $item['gravity'] == GRAVITY_PARENT && !$item['self'] && !$item['mention']) { + $sub_link = 'javascript:doFollowThread(' . $item['id'] . '); return false;'; } $author = ['uid' => 0, 'id' => $item['author-id'], @@ -903,7 +805,7 @@ function item_photo_menu($item) { $sparkle = (strpos($profile_link, 'redir/') === 0); $cid = 0; - $pcid = Contact::getIdForURL($item['author-link'], 0, false); + $pcid = $item['author-id']; $network = ''; $rel = 0; $condition = ['uid' => local_user(), 'nurl' => Strings::normaliseLink($item['author-link'])]; @@ -923,8 +825,8 @@ function item_photo_menu($item) { if (!empty($pcid)) { $contact_url = 'contact/' . $pcid; $posts_link = $contact_url . '/posts'; - $block_link = $contact_url . '/block'; - $ignore_link = $contact_url . '/ignore'; + $block_link = $item['self'] ? '' : $contact_url . '/block'; + $ignore_link = $item['self'] ? '' : $contact_url . '/ignore'; } if ($cid && !$item['self']) { @@ -977,10 +879,11 @@ function item_photo_menu($item) { if (strpos($v, 'javascript:') === 0) { $v = substr($v, 11); $o .= '