*/
use Friendica\App;
+use Friendica\BaseObject;
use Friendica\Content\ContactSelector;
use Friendica\Content\Feature;
+use Friendica\Content\Item as ContentItem;
use Friendica\Content\Pager;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Config;
use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
+use Friendica\Core\Session;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Term;
use Friendica\Object\Post;
use Friendica\Object\Thread;
+use Friendica\Protocol\Activity;
+use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Proxy as ProxyUtils;
-use Friendica\Util\Temporal;
use Friendica\Util\Strings;
+use Friendica\Util\Temporal;
use Friendica\Util\XML;
-use Friendica\Util\Crypto;
function item_extract_images($body) {
During the further steps of the database restructuring I would like to address this issue.
*/
+ /** @var Activity $activity */
+ $activity = BaseObject::getClass(Activity::class);
+
$xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
- if (activity_match($item['verb'], ACTIVITY_LIKE)
- || activity_match($item['verb'], ACTIVITY_DISLIKE)
- || activity_match($item['verb'], ACTIVITY_ATTEND)
- || activity_match($item['verb'], ACTIVITY_ATTENDNO)
- || activity_match($item['verb'], ACTIVITY_ATTENDMAYBE)) {
+ if ($activity->match($item['verb'], Activity::LIKE)
+ || $activity->match($item['verb'], Activity::DISLIKE)
+ || $activity->match($item['verb'], Activity::ATTEND)
+ || $activity->match($item['verb'], Activity::ATTENDNO)
+ || $activity->match($item['verb'], Activity::ATTENDMAYBE)) {
$fields = ['author-link', 'author-name', 'verb', 'object-type', 'resource-id', 'body', 'plink'];
$obj = Item::selectFirst($fields, ['uri' => $item['parent-uri']]);
$objauthor = '[url=' . $obj['author-link'] . ']' . $obj['author-name'] . '[/url]';
switch ($obj['verb']) {
- case ACTIVITY_POST:
+ case Activity::POST:
switch ($obj['object-type']) {
- case ACTIVITY_OBJ_EVENT:
+ case Activity\ObjectType::EVENT:
$post_type = L10n::t('event');
break;
default:
$plink = '[url=' . $obj['plink'] . ']' . $post_type . '[/url]';
$bodyverb = '';
- if (activity_match($item['verb'], ACTIVITY_LIKE)) {
+ if ($activity->match($item['verb'], Activity::LIKE)) {
$bodyverb = L10n::t('%1$s likes %2$s\'s %3$s');
- } elseif (activity_match($item['verb'], ACTIVITY_DISLIKE)) {
+ } elseif ($activity->match($item['verb'], Activity::DISLIKE)) {
$bodyverb = L10n::t('%1$s doesn\'t like %2$s\'s %3$s');
- } elseif (activity_match($item['verb'], ACTIVITY_ATTEND)) {
+ } elseif ($activity->match($item['verb'], Activity::ATTEND)) {
$bodyverb = L10n::t('%1$s attends %2$s\'s %3$s');
- } elseif (activity_match($item['verb'], ACTIVITY_ATTENDNO)) {
+ } elseif ($activity->match($item['verb'], Activity::ATTENDNO)) {
$bodyverb = L10n::t('%1$s doesn\'t attend %2$s\'s %3$s');
- } elseif (activity_match($item['verb'], ACTIVITY_ATTENDMAYBE)) {
+ } elseif ($activity->match($item['verb'], Activity::ATTENDMAYBE)) {
$bodyverb = L10n::t('%1$s attends maybe %2$s\'s %3$s');
}
$item['body'] = sprintf($bodyverb, $author, $objauthor, $plink);
}
- if (activity_match($item['verb'], ACTIVITY_FRIEND)) {
+ if ($activity->match($item['verb'], Activity::FRIEND)) {
- if ($item['object-type']=="" || $item['object-type']!== ACTIVITY_OBJ_PERSON) return;
+ if ($item['object-type']=="" || $item['object-type']!== Activity\ObjectType::PERSON) return;
$Aname = $item['author-name'];
$Alink = $item['author-link'];
$item['body'] = L10n::t('%1$s is now friends with %2$s', $A, $B)."\n\n\n".$Bphoto;
}
- if (stristr($item['verb'], ACTIVITY_POKE)) {
+ if (stristr($item['verb'], Activity::POKE)) {
$verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1));
if (!$verb) {
return;
}
- if ($item['object-type']=="" || $item['object-type']!== ACTIVITY_OBJ_PERSON) {
+ if ($item['object-type']=="" || $item['object-type']!== Activity\ObjectType::PERSON) {
return;
}
}
- if (activity_match($item['verb'], ACTIVITY_TAG)) {
+ if ($activity->match($item['verb'], Activity::TAG)) {
$fields = ['author-id', 'author-link', 'author-name', 'author-network',
'verb', 'object-type', 'resource-id', 'body', 'plink'];
$obj = Item::selectFirst($fields, ['uri' => $item['parent-uri']]);
$objauthor = '[url=' . Contact::magicLinkByContact($author_arr) . ']' . $obj['author-name'] . '[/url]';
switch ($obj['verb']) {
- case ACTIVITY_POST:
+ case Activity::POST:
switch ($obj['object-type']) {
- case ACTIVITY_OBJ_EVENT:
+ case Activity\ObjectType::EVENT:
$post_type = L10n::t('event');
break;
default:
$item['body'] = L10n::t('%1$s tagged %2$s\'s %3$s with %4$s', $author, $objauthor, $plink, $tag);
}
- if (activity_match($item['verb'], ACTIVITY_FAVORITE)) {
+ if ($activity->match($item['verb'], Activity::FAVORITE)) {
if ($item['object-type'] == "") {
return;
}
'network' => $item['author-network'], 'url' => $item['author-link']];
// Only create a redirection to a magic link when logged in
- if (!empty($item['plink']) && (local_user() || remote_user())) {
+ if (!empty($item['plink']) && Session::isAuthenticated()) {
$item['plink'] = Contact::magicLinkByContact($author, $item['plink']);
}
}
function visible_activity($item) {
- /*
- * likes (etc.) can apply to other things besides posts. Check if they are post children,
- * in which case we handle them specially
- */
- $hidden_activities = [ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE, ACTIVITY_FOLLOW, ACTIVITY2_ANNOUNCE];
- foreach ($hidden_activities as $act) {
- if (activity_match($item['verb'], $act)) {
- return false;
- }
+ /** @var Activity $activity */
+ $activity = BaseObject::getClass(Activity::class);
+
+ if (empty($item['verb']) || $activity->isHidden($item['verb'])) {
+ return false;
}
// @TODO below if() block can be rewritten to a single line: $isVisible = allConditionsHere;
- if (activity_match($item['verb'], ACTIVITY_FOLLOW) && $item['object-type'] === ACTIVITY_OBJ_NOTE && empty($item['self']) && $item['uid'] == local_user()) {
+ if ($activity->match($item['verb'], Activity::FOLLOW) &&
+ $item['object-type'] === Activity\ObjectType::NOTE &&
+ empty($item['self']) &&
+ $item['uid'] == local_user()) {
return false;
}
if (!$update) {
$live_update_div = '<div id="live-display"></div>' . "\r\n"
- . "<script> var profile_uid = " . defaults($_SESSION, 'uid', 0) . ";"
+ . "<script> var profile_uid = " . Session::get('uid', 0) . ";"
. " var profile_page = 1; </script>";
}
} elseif ($mode === 'community') {
if (in_array($mode, ['community', 'contacts'])) {
$writable = true;
} else {
- $writable = ($items[0]['uid'] == 0) && in_array($items[0]['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]);
+ $writable = ($items[0]['uid'] == 0) && in_array($items[0]['network'], Protocol::FEDERATED);
}
if (!local_user()) {
$body = Item::prepareBody($item, true, $preview);
- list($categories, $folders) = get_cats_and_terms($item);
+ /** @var ContentItem $contItem */
+ $contItem = BaseObject::getClass(ContentItem::class);
+
+ list($categories, $folders) = $contItem->determineCategoriesTerms($item);
if (!empty($item['content-warning']) && PConfig::get(local_user(), 'system', 'disable_cw', false)) {
$title = ucfirst($item['content-warning']);
'guid' => ($preview ? 'Q0' : $item['guid']),
'network' => $item['network'],
'network_name' => ContactSelector::networkToName($item['network'], $item['author-link']),
+ 'network_icon' => ContactSelector::networkToIcon($item['network'], $item['author-link']),
'linktitle' => L10n::t('View %s\'s profile @ %s', $profile_name, $item['author-link']),
'profile_url' => $profile_link,
'item_photo_menu' => item_photo_menu($item),
/**
* Fetch all comments from a query. Additionally set the newest resharer as thread owner.
*
- * @param $thread_items Database statement with thread posts
+ * @param array $thread_items Database statement with thread posts
+ * @param boolean $pinned Is the item pinned?
+ *
* @return array items with parents and comments
*/
-function conversation_fetch_comments($thread_items) {
+function conversation_fetch_comments($thread_items, $pinned) {
$comments = [];
$parentlines = [];
$lineno = 0;
$actor = [];
- $created = '';
+ $received = '';
while ($row = Item::fetch($thread_items)) {
- if (($row['verb'] == ACTIVITY2_ANNOUNCE) && !empty($row['contact-uid']) && ($row['created'] > $created)) {
+ if (($row['verb'] == Activity::ANNOUNCE) && !empty($row['contact-uid']) && ($row['received'] > $received) && ($row['thr-parent'] == $row['parent-uri'])) {
$actor = ['link' => $row['author-link'], 'avatar' => $row['author-avatar'], 'name' => $row['author-name']];
- $created = $row['created'];
+ $received = $row['received'];
}
- if ($row['gravity'] == GRAVITY_PARENT) {
+
+ if ((($row['gravity'] == GRAVITY_PARENT) && !$row['origin'] && !in_array($row['network'], [Protocol::DIASPORA])) &&
+ (empty($row['contact-uid']) || !in_array($row['network'], Protocol::NATIVE_SUPPORT))) {
$parentlines[] = $lineno;
}
+ if ($row['gravity'] == GRAVITY_PARENT) {
+ $row['pinned'] = $pinned;
+ }
+
$comments[] = $row;
$lineno++;
}
if (!empty($actor)) {
foreach ($parentlines as $line) {
- if (!in_array($comments[$line]['network'], [Protocol::DIASPORA]) && !$comments[$line]['origin']) {
- $comments[$line]['owner-link'] = $actor['link'];
- $comments[$line]['owner-avatar'] = $actor['avatar'];
- $comments[$line]['owner-name'] = $actor['name'];
- }
+ $comments[$line]['owner-link'] = $actor['link'];
+ $comments[$line]['owner-avatar'] = $actor['avatar'];
+ $comments[$line]['owner-name'] = $actor['name'];
}
}
return $comments;
$thread_items = Item::selectForUser(local_user(), array_merge(Item::DISPLAY_FIELDLIST, ['contact-uid', 'gravity']), $condition, $params);
- $comments = conversation_fetch_comments($thread_items);
+ $comments = conversation_fetch_comments($thread_items, $parent['pinned'] ?? false);
if (count($comments) != 0) {
$items = array_merge($items, $comments);
foreach ($items as $index => $item) {
if ($item['uid'] == 0) {
- $items[$index]['writable'] = in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]);
+ $items[$index]['writable'] = in_array($item['network'], Protocol::FEDERATED);
}
}
$contact_url = 'contact/' . $cid;
$posts_link = 'contact/' . $cid . '/posts';
- if (in_array($network, [Protocol::DFRN, Protocol::DIASPORA])) {
+ if (in_array($network, [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA])) {
$pm_url = 'message/new/' . $cid;
}
}
}
if ((($cid == 0) || ($rel == Contact::FOLLOWER)) &&
- in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA])) {
+ in_array($item['network'], Protocol::FEDERATED)) {
$menu[L10n::t('Connect/Follow')] = 'follow?url=' . urlencode($item['author-link']);
}
} else {
switch ($mode) {
case 'like':
- $verb = ACTIVITY_LIKE;
+ $verb = Activity::LIKE;
break;
case 'dislike':
- $verb = ACTIVITY_DISLIKE;
+ $verb = Activity::DISLIKE;
break;
case 'attendyes':
- $verb = ACTIVITY_ATTEND;
+ $verb = Activity::ATTEND;
break;
case 'attendno':
- $verb = ACTIVITY_ATTENDNO;
+ $verb = Activity::ATTENDNO;
break;
case 'attendmaybe':
- $verb = ACTIVITY_ATTENDMAYBE;
+ $verb = Activity::ATTENDMAYBE;
break;
case 'announce':
- $verb = ACTIVITY2_ANNOUNCE;
+ $verb = Activity::ANNOUNCE;
break;
default:
return;
}
- if (activity_match($item['verb'], $verb) && ($item['id'] != $item['parent'])) {
+ /** @var Activity $activity */
+ $activity = BaseObject::getClass(Activity::class);
+
+ if (!empty($item['verb']) && $activity->match($item['verb'], $verb) && ($item['id'] != $item['parent'])) {
$author = ['uid' => 0, 'id' => $item['author-id'],
'network' => $item['author-network'], 'url' => $item['author-link']];
$url = Contact::magicLinkByContact($author);
'$new_post' => L10n::t('New Post'),
'$return_path' => $query_str,
'$action' => 'item',
- '$share' => defaults($x, 'button', L10n::t('Share')),
+ '$share' => ($x['button'] ?? '') ?: L10n::t('Share'),
'$upload' => L10n::t('Upload photo'),
'$shortupload' => L10n::t('upload photo'),
'$attach' => L10n::t('Attach file'),
'$shortsetloc' => L10n::t('set location'),
'$noloc' => L10n::t('Clear browser location'),
'$shortnoloc' => L10n::t('clear location'),
- '$title' => defaults($x, 'title', ''),
+ '$title' => $x['title'] ?? '',
'$placeholdertitle' => L10n::t('Set title'),
- '$category' => defaults($x, 'category', ''),
+ '$category' => $x['category'] ?? '',
'$placeholdercategory' => Feature::isEnabled(local_user(), 'categories') ? L10n::t("Categories \x28comma-separated list\x29") : '',
'$wait' => L10n::t('Please wait'),
'$permset' => L10n::t('Permission settings'),
'$shortpermset' => L10n::t('permissions'),
'$wall' => $notes_cid ? 0 : 1,
'$posttype' => $notes_cid ? Item::PT_PERSONAL_NOTE : Item::PT_ARTICLE,
- '$content' => defaults($x, 'content', ''),
- '$post_id' => defaults($x, 'post_id', ''),
+ '$content' => $x['content'] ?? '',
+ '$post_id' => $x['post_id'] ?? '',
'$baseurl' => System::baseUrl(true),
'$defloc' => $x['default_location'],
'$visitor' => $x['visitor'],
function sort_item_children(array $items)
{
$result = $items;
- usort($result, 'sort_thr_created_rev');
+ usort($result, 'sort_thr_received_rev');
foreach ($result as $k => $i) {
if (isset($result[$k]['children'])) {
$result[$k]['children'] = sort_item_children($result[$k]['children']);
if (isset($child['children']) && count($child['children'])) {
// This helps counting only the regular posts
$count_post_closure = function($var) {
- return $var['verb'] === ACTIVITY_POST;
+ return $var['verb'] === Activity::POST;
};
$child_post_count = count(array_filter($child['children'], $count_post_closure));
// Searches the post item in the children
$j = 0;
- while($child['children'][$j]['verb'] !== ACTIVITY_POST && $j < count($child['children'])) {
+ while($child['children'][$j]['verb'] !== Activity::POST && $j < count($child['children'])) {
$j ++;
}
/**
* Expands a flat list of items into corresponding tree-like conversation structures,
- * sort the top-level posts either on "created" or "commented", and finally
+ * sort the top-level posts either on "received" or "commented", and finally
* append all the items at the top level (???)
*
* @brief Expands a flat item list into a conversation array for display
*
* @param array $item_list A list of items belonging to one or more conversations
- * @param string $order Either on "created" or "commented"
+ * @param string $order Either on "received" or "commented"
* @return array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
}
}
- if (stristr($order, 'created')) {
- usort($parents, 'sort_thr_created');
+ if (stristr($order, 'pinned_received')) {
+ usort($parents, 'sort_thr_pinned_received');
+ } elseif (stristr($order, 'received')) {
+ usort($parents, 'sort_thr_received');
} elseif (stristr($order, 'commented')) {
usort($parents, 'sort_thr_commented');
}
$parents[$i]['children'] = sort_item_children($parents[$i]['children']);
}
- if (PConfig::get(local_user(), 'system', 'smart_threading', 0)) {
+ if (!PConfig::get(local_user(), 'system', 'no_smart_threading', 0)) {
foreach ($parents as $i => $parent) {
$parents[$i] = smart_flatten_conversation($parent);
}
}
/**
- * @brief usort() callback to sort item arrays by the created key
+ * @brief usort() callback to sort item arrays by pinned and the received key
+ *
+ * @param array $a
+ * @param array $b
+ * @return int
+ */
+function sort_thr_pinned_received(array $a, array $b)
+{
+ if ($b['pinned'] && !$a['pinned']) {
+ return 1;
+ } elseif (!$b['pinned'] && $a['pinned']) {
+ return -1;
+ }
+
+ return strcmp($b['received'], $a['received']);
+}
+
+/**
+ * @brief usort() callback to sort item arrays by the received key
*
* @param array $a
* @param array $b
* @return int
*/
-function sort_thr_created(array $a, array $b)
+function sort_thr_received(array $a, array $b)
{
- return strcmp($b['created'], $a['created']);
+ return strcmp($b['received'], $a['received']);
}
/**
- * @brief usort() callback to reverse sort item arrays by the created key
+ * @brief usort() callback to reverse sort item arrays by the received key
*
* @param array $a
* @param array $b
* @return int
*/
-function sort_thr_created_rev(array $a, array $b)
+function sort_thr_received_rev(array $a, array $b)
{
- return strcmp($a['created'], $b['created']);
+ return strcmp($a['received'], $b['received']);
}
/**
$ret = [];
foreach ($response_verbs as $v) {
$ret[$v] = [];
- $ret[$v]['count'] = defaults($conv_responses[$v], $item['uri'], 0);
- $ret[$v]['list'] = defaults($conv_responses[$v], $item['uri'] . '-l', []);
- $ret[$v]['self'] = defaults($conv_responses[$v], $item['uri'] . '-self', '0');
+ $ret[$v]['count'] = $conv_responses[$v][$item['uri']] ?? 0;
+ $ret[$v]['list'] = $conv_responses[$v][$item['uri'] . '-l'] ?? [];
+ $ret[$v]['self'] = $conv_responses[$v][$item['uri'] . '-self'] ?? '0';
if (count($ret[$v]['list']) > MAX_LIKERS) {
$ret[$v]['list_part'] = array_slice($ret[$v]['list'], 0, MAX_LIKERS);
array_push($ret[$v]['list_part'], '<a href="#" data-toggle="modal" data-target="#' . $v . 'Modal-'