streams/Zotlabs/Lib/ThreadItem.php

898 lines
27 KiB
PHP
Raw Normal View History

2013-02-26 01:09:40 +00:00
<?php /** @file */
namespace Zotlabs\Lib;
2012-09-11 05:00:56 +00:00
require_once('include/text.php');
/**
* A thread item
2012-09-11 05:00:56 +00:00
*/
class ThreadItem {
public $data = array();
2012-11-05 00:57:09 +00:00
private $template = 'conv_item.tpl';
2012-09-11 05:00:56 +00:00
private $comment_box_template = 'comment_item.tpl';
private $commentable = false;
// list of supported reaction emojis - a site can over-ride this via config system.reactions
private $reactions = ['1f60a','1f44f','1f37e','1f48b','1f61e','2665','1f606','1f62e','1f634','1f61c','1f607','1f608'];
2012-09-11 05:00:56 +00:00
private $toplevel = false;
private $children = array();
private $parent = null;
private $conversation = null;
private $redirect_url = null;
private $owner_url = '';
private $owner_photo = '';
private $owner_name = '';
private $wall_to_wall = false;
private $threaded = false;
private $visiting = false;
private $channel = null;
2014-11-17 04:23:22 +00:00
private $display_mode = 'normal';
private $reload = '';
2012-09-11 05:00:56 +00:00
public function __construct($data) {
2012-09-11 05:00:56 +00:00
$this->data = $data;
$this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
// Prepare the children
2017-12-04 07:56:01 +00:00
if($data['children']) {
2012-09-11 05:00:56 +00:00
foreach($data['children'] as $item) {
2013-02-11 01:03:33 +00:00
2012-09-11 05:00:56 +00:00
/*
2013-08-21 02:51:58 +00:00
* Only add those that will be displayed
2012-09-11 05:00:56 +00:00
*/
2013-02-11 01:03:33 +00:00
if((! visible_activity($item)) || array_key_exists('blocked',$item)) {
2012-09-11 05:00:56 +00:00
continue;
}
2013-02-11 01:03:33 +00:00
$child = new ThreadItem($item);
2012-09-11 05:00:56 +00:00
$this->add_child($child);
}
}
// allow a site to configure the order and content of the reaction emoji list
if($this->toplevel) {
$x = get_config('system','reactions');
if($x && is_array($x) && count($x)) {
$this->reactions = $x;
}
}
2012-09-11 05:00:56 +00:00
}
/**
* Get data in a form usable by a conversation template
*
* Returns:
* _ The data requested on success
* _ false on failure
*/
2018-08-02 00:58:54 +00:00
public function get_template_data($conv_responses, $thread_level = 1, $collapse_all = false) {
2012-09-11 05:00:56 +00:00
$result = array();
$item = $this->get_data();
2012-09-11 05:00:56 +00:00
$commentww = '';
$sparkle = '';
$buttons = '';
$dropping = false;
$star = false;
2016-04-30 18:39:57 +00:00
$isstarred = "unstarred fa-star-o";
$is_comment = false;
$is_item = false;
2012-09-11 05:00:56 +00:00
$osparkle = '';
$total_children = $this->count_descendants();
$unseen_comments = (($item['real_uid']) ? 0 : $this->count_unseen_descendants());
2012-09-11 05:00:56 +00:00
$conv = $this->get_conversation();
2013-07-10 12:14:23 +00:00
$observer = $conv->get_observer();
2012-09-11 05:00:56 +00:00
2015-01-29 04:56:04 +00:00
$lock = ((($item['item_private'] == 1) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
2012-09-11 05:00:56 +00:00
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
? t('Private Message')
: false);
2015-01-29 04:56:04 +00:00
$shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false);
2012-11-05 00:57:09 +00:00
// allow an exemption for sharing stuff from your private feeds
if($item['author']['xchan_network'] === 'rss')
$shareable = true;
$privacy_warning = false;
if(($item['item_private'] == 1) && ($item['owner']['xchan_network'] === 'activitypub')) {
$recips = get_iconfig($item['parent'], 'activitypub', 'recips');
if(! in_array($observer['xchan_url'], $recips['to']))
$privacy_warning = true;
}
2017-08-24 00:46:20 +00:00
$mode = $conv->get_mode();
2017-11-22 23:39:06 +00:00
switch($item['item_type']) {
case ITEM_TYPE_CARD:
$edlink = 'card_edit';
break;
case ITEM_TYPE_ARTICLE:
$edlink = 'article_edit';
break;
default:
$edlink = 'editpost';
break;
}
2017-08-24 00:46:20 +00:00
2015-01-29 04:56:04 +00:00
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
2017-08-24 00:46:20 +00:00
$edpost = array(z_root() . '/' . $edlink . '/' . $item['id'], t('Edit'));
2012-09-11 05:00:56 +00:00
else
$edpost = false;
2012-11-05 00:57:09 +00:00
2018-09-21 23:29:13 +00:00
if($item['verb'] === 'Announce') {
$edpost = false;
}
2014-09-23 04:37:19 +00:00
2013-07-10 12:14:23 +00:00
if($observer['xchan_hash'] == $this->get_data_value('author_xchan')
|| $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
2015-01-29 04:56:04 +00:00
|| $this->get_data_value('uid') == local_channel())
2012-09-11 05:00:56 +00:00
$dropping = true;
2014-09-23 04:37:19 +00:00
if(array_key_exists('real_uid',$item)) {
$edpost = false;
$dropping = false;
}
2012-11-05 00:57:09 +00:00
if($dropping) {
$drop = array(
'dropping' => $dropping,
'delete' => t('Delete'),
);
}
elseif(is_site_admin()) {
$drop = [ 'dropping' => true, 'delete' => t('Admin Delete') ];
}
2013-07-10 12:14:23 +00:00
// FIXME
2012-11-05 00:57:09 +00:00
if($observer_is_pageowner) {
$multidrop = array(
'select' => t('Select'),
);
}
2015-01-29 04:56:04 +00:00
$filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false);
2012-09-11 05:00:56 +00:00
2012-10-24 04:24:23 +00:00
$profile_avatar = $item['author']['xchan_photo_m'];
$profile_link = chanlink_hash($item['author_xchan']);
$profile_name = $item['author']['xchan_name'];
2012-10-08 04:44:11 +00:00
2018-09-20 03:47:31 +00:00
$profile_addr = $item['author']['xchan_addr'] ? : $item['author']['xchan_url'];
$location = format_location($item);
2015-02-10 08:11:37 +00:00
$isevent = false;
$attend = null;
2015-02-11 05:21:18 +00:00
$canvote = false;
// process action responses - e.g. like/dislike/attend/agree/whatever
$response_verbs = array('like');
if(feature_enabled($conv->get_profile_owner(),'dislike'))
$response_verbs[] = 'dislike';
2015-02-11 05:21:18 +00:00
if($item['obj_type'] === ACTIVITY_OBJ_EVENT) {
$response_verbs[] = 'attendyes';
$response_verbs[] = 'attendno';
$response_verbs[] = 'attendmaybe';
if($this->is_commentable() && $observer) {
2015-02-11 05:21:18 +00:00
$isevent = true;
$attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
}
}
2015-02-11 03:10:18 +00:00
$consensus = (intval($item['item_consensus']) ? true : false);
if($consensus) {
$response_verbs[] = 'agree';
$response_verbs[] = 'disagree';
$response_verbs[] = 'abstain';
if($this->is_commentable() && $observer) {
2015-02-11 05:21:18 +00:00
$conlabels = array( t('I agree'), t('I disagree'), t('I abstain'));
$canvote = true;
}
}
2015-02-11 05:21:18 +00:00
if(! feature_enabled($conv->get_profile_owner(),'dislike'))
unset($conv_responses['dislike']);
$responses = get_responses($conv_responses,$response_verbs,$this,$item);
$my_responses = [];
foreach($response_verbs as $v) {
$my_responses[$v] = (($conv_responses[$v][$item['mid'] . '-m']) ? 1 : 0);
}
$like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : '');
$like_list = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : '');
2017-12-04 07:56:01 +00:00
if (($like_list) && (count($like_list) > MAX_LIKERS)) {
$like_list_part = array_slice($like_list, 0, MAX_LIKERS);
array_push($like_list_part, '<a class="dropdown-item" href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
} else {
$like_list_part = '';
}
$like_button_label = tt('Like','Likes',$like_count,'noun');
2014-05-08 11:44:43 +00:00
if (feature_enabled($conv->get_profile_owner(),'dislike')) {
$dislike_count = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid']] : '');
$dislike_list = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : '');
$dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun');
2017-12-04 07:56:01 +00:00
if (($dislike_list) && (count($dislike_list) > MAX_LIKERS)) {
$dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS);
array_push($dislike_list_part, '<a class="dropdown-item" href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
} else {
$dislike_list_part = '';
}
2014-05-08 11:44:43 +00:00
}
2012-09-11 05:00:56 +00:00
$showlike = ((x($conv_responses['like'],$item['mid'])) ? format_like($conv_responses['like'][$item['mid']],$conv_responses['like'][$item['mid'] . '-l'],'like',$item['mid']) : '');
$showdislike = ((x($conv_responses['dislike'],$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike'))
? format_like($conv_responses['dislike'][$item['mid']],$conv_responses['dislike'][$item['mid'] . '-l'],'dislike',$item['mid']) : '');
2012-09-11 05:00:56 +00:00
/*
* We should avoid doing this all the time, but it depends on the conversation mode
* And the conv mode may change when we change the conv, or it changes its mode
* Maybe we should establish a way to be notified about conversation changes
*/
2012-09-11 05:00:56 +00:00
$this->check_wall_to_wall();
if($this->is_toplevel()) {
2013-07-01 06:04:27 +00:00
// FIXME check this permission
2015-01-29 04:56:04 +00:00
if(($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) {
2012-11-05 00:57:09 +00:00
2012-09-11 05:00:56 +00:00
$star = array(
'toggle' => t("Toggle Star Status"),
'isstarred' => ((intval($item['item_starred'])) ? true : false),
2012-11-05 00:57:09 +00:00
);
2012-09-11 05:00:56 +00:00
}
}
else {
$is_comment = true;
2012-09-11 05:00:56 +00:00
}
2013-10-03 04:04:48 +00:00
$verified = (intval($item['item_verified']) ? t('Message signature validated') : '');
$forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : '');
$unverified = '' ; // (($this->is_wall_to_wall() && (! intval($item['item_verified']))) ? t('Message cannot be verified') : '');
2013-10-03 04:04:48 +00:00
2013-07-01 06:04:27 +00:00
// FIXME - check this permission
2015-01-29 04:56:04 +00:00
if($conv->get_profile_owner() == local_channel()) {
2013-07-01 06:04:27 +00:00
$tagger = array(
'tagit' => t("Add Tag"),
2013-07-01 06:04:27 +00:00
'classtagger' => "",
);
}
2014-02-05 01:12:13 +00:00
$has_bookmarks = false;
if(is_array($item['term'])) {
foreach($item['term'] as $t) {
2018-07-31 06:55:09 +00:00
if($t['ttype'] == TERM_BOOKMARK)
2014-02-05 01:12:13 +00:00
$has_bookmarks = true;
}
}
2014-05-30 03:09:21 +00:00
$has_event = false;
2015-01-29 04:56:04 +00:00
if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel())
2014-05-30 03:09:21 +00:00
$has_event = true;
2014-02-05 01:12:13 +00:00
if($this->is_commentable() && $observer) {
2012-11-05 00:57:09 +00:00
$like = array( t("I like this \x28toggle\x29"), t("like"));
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
2012-09-11 05:00:56 +00:00
}
if ($shareable)
$share = array( t('Share This'), t('share'));
2015-11-23 01:12:30 +00:00
$dreport = '';
$keep_reports = intval(get_config('system','expire_delivery_reports'));
if($keep_reports === 0)
$keep_reports = 10;
2015-11-23 01:12:30 +00:00
2018-07-19 03:15:46 +00:00
if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0) {
2015-11-23 01:12:30 +00:00
$dreport = t('Delivery Report');
2018-07-19 03:15:46 +00:00
$dreport_link = gen_link_id($item['mid']);
}
2012-09-11 05:00:56 +00:00
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
$is_new = true;
2012-09-11 05:00:56 +00:00
2014-11-17 04:23:22 +00:00
localize_item($item);
2015-10-20 07:40:32 +00:00
2018-08-02 00:58:54 +00:00
if($this->is_toplevel() && $collapse_all) {
$item['collapse'] = true;
}
2012-09-11 05:00:56 +00:00
$body = prepare_body($item,true);
// $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link
// since we can't depend on llink or plink pointing to the right local location.
$owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@'));
$viewthread = $item['llink'];
if($conv->get_mode() === 'channel')
2018-07-19 03:15:46 +00:00
$viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . urlencode(gen_link_id($item['mid']));
2012-09-11 05:00:56 +00:00
2014-11-15 22:03:41 +00:00
$comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
$list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : '');
2014-11-15 22:03:41 +00:00
$children = $this->get_children();
$has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false);
$dropdown_extras_arr = [ 'item' => $item , 'dropdown_extras' => '' ];
call_hooks('dropdown_extras',$dropdown_extras_arr);
$dropdown_extras = $dropdown_extras_arr['dropdown_extras'];
2012-09-11 05:00:56 +00:00
$tmp_item = array(
'template' => $this->get_template(),
2017-09-06 01:32:37 +00:00
'mode' => $mode,
'item_type' => intval($item['item_type']),
2012-09-11 05:00:56 +00:00
'type' => implode("",array_slice(explode("/",$item['verb']),-1)),
'body' => $body['html'],
'tags' => $body['tags'],
'categories' => $body['categories'],
'mentions' => $body['mentions'],
'attachments' => $body['attachments'],
'folders' => $body['folders'],
'text' => strip_tags($body['html']),
2012-09-11 05:00:56 +00:00
'id' => $this->get_id(),
'mid' => $item['mid'],
2015-02-10 08:11:37 +00:00
'isevent' => $isevent,
'attend' => $attend,
2015-02-11 03:10:18 +00:00
'consensus' => $consensus,
'conlabels' => $conlabels,
2015-02-11 05:21:18 +00:00
'canvote' => $canvote,
2018-09-17 00:04:47 +00:00
'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url'])),
'olinktitle' => sprintf( t('View %s\'s profile - %s'), $this->get_owner_name(), (($item['owner']['xchan_addr']) ? $item['owner']['xchan_addr'] : $item['owner']['xchan_url'])),
'llink' => $item['llink'],
'viewthread' => $viewthread,
2012-09-11 05:00:56 +00:00
'to' => t('to'),
'via' => t('via'),
2012-09-11 05:00:56 +00:00
'wall' => t('Wall-to-Wall'),
'vwall' => t('via Wall-To-Wall:'),
'profile_url' => $profile_link,
'thread_action_menu' => thread_action_menu($item,$conv->get_mode()),
'thread_author_menu' => thread_author_menu($item,$conv->get_mode()),
2015-11-23 01:12:30 +00:00
'dreport' => $dreport,
2018-07-19 03:15:46 +00:00
'dreport_link' => $dreport_link,
'name' => $profile_name,
2012-09-11 05:00:56 +00:00
'thumb' => $profile_avatar,
'osparkle' => $osparkle,
'sparkle' => $sparkle,
'title' => $item['title'],
'title_tosource' => get_pconfig($conv->get_profile_owner(),'system','title_tosource'),
2013-05-22 03:52:18 +00:00
'ago' => relative_date($item['created']),
'app' => $item['app'],
'str_app' => sprintf( t('from %s'), $item['app']),
'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'),
2012-09-11 05:00:56 +00:00
'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'),
'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''),
2016-09-26 00:06:13 +00:00
'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''),
2012-09-11 05:00:56 +00:00
'lock' => $lock,
'privacy_warning' => $privacy_warning,
2018-09-03 03:51:17 +00:00
'repeated' => ($item['verb'] === 'Announce'),
2013-10-03 04:04:48 +00:00
'verified' => $verified,
'unverified' => $unverified,
2014-10-16 23:19:19 +00:00
'forged' => $forged,
'location' => $location,
'divider' => get_pconfig($conv->get_profile_owner(),'system','item_divider'),
'attend_label' => t('Attend'),
'attend_title' => t('Attendance Options'),
'vote_label' => t('Vote'),
'vote_title' => t('Voting Options'),
'is_comment' => $is_comment,
'is_new' => $is_new,
2012-09-11 05:00:56 +00:00
'owner_url' => $this->get_owner_url(),
'owner_photo' => $this->get_owner_photo(),
2013-01-25 07:49:44 +00:00
'owner_name' => $this->get_owner_name(),
'photo' => $body['photo'],
2015-11-26 11:26:27 +00:00
'event' => $body['event'],
'has_tags' => $has_tags,
'reactions' => $this->reactions,
2012-11-05 00:57:09 +00:00
// Item toolbar buttons
2018-07-09 05:28:15 +00:00
'emojis' => '', // (($this->is_toplevel() && $this->is_commentable() && $observer && feature_enabled($conv->get_profile_owner(),'emojis')) ? '1' : ''),
2012-11-05 00:57:09 +00:00
'like' => $like,
'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike : ''),
'share' => $share,
2014-02-08 17:49:09 +00:00
'rawmid' => $item['mid'],
2014-01-10 00:23:58 +00:00
'plink' => get_plink($item),
2014-12-17 08:50:55 +00:00
'edpost' => $edpost, // ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''),
2012-11-09 07:04:34 +00:00
'star' => ((feature_enabled($conv->get_profile_owner(),'star_posts')) ? $star : ''),
2012-11-05 00:57:09 +00:00
'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''),
'filer' => ((feature_enabled($conv->get_profile_owner(),'filing')) ? $filer : ''),
2015-01-29 04:56:04 +00:00
'bookmark' => (($conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks) ? t('Save Bookmarks') : ''),
2014-05-30 03:09:21 +00:00
'addtocal' => (($has_event) ? t('Add to Calendar') : ''),
2012-11-05 00:57:09 +00:00
'drop' => $drop,
'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''),
'dropdown_extras' => $dropdown_extras,
2012-11-05 00:57:09 +00:00
// end toolbar buttons
'unseen_comments' => $unseen_comments,
2014-11-15 22:03:41 +00:00
'comment_count' => $total_children,
'comment_count_txt' => $comment_count_txt,
'list_unseen_txt' => $list_unseen_txt,
'markseen' => t('Mark all seen'),
'responses' => $responses,
'my_responses' => $my_responses,
2014-05-08 11:44:43 +00:00
'like_count' => $like_count,
'like_list' => $like_list,
'like_list_part' => $like_list_part,
2014-05-08 11:44:43 +00:00
'like_button_label' => $like_button_label,
'like_modal_title' => t('Likes','noun'),
'dislike_modal_title' => t('Dislikes','noun'),
2014-05-08 11:44:43 +00:00
'dislike_count' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_count : ''),
'dislike_list' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list : ''),
'dislike_list_part' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list_part : ''),
2014-05-08 11:44:43 +00:00
'dislike_button_label' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_button_label : ''),
'modal_dismiss' => t('Close'),
2012-11-05 00:57:09 +00:00
'showlike' => $showlike,
'showdislike' => $showdislike,
2012-09-11 05:00:56 +00:00
'comment' => $this->get_comment_box($indent),
'previewing' => ($conv->is_preview() ? true : false ),
'preview_lbl' => t('This is an unsaved preview'),
2012-09-11 05:00:56 +00:00
'wait' => t('Please wait'),
'submid' => str_replace(['+','='], ['',''], base64_encode($item['mid'])),
2012-09-11 05:00:56 +00:00
'thread_level' => $thread_level
);
$arr = array('item' => $item, 'output' => $tmp_item);
call_hooks('display_item', $arr);
$result = $arr['output'];
2018-08-02 00:58:54 +00:00
$censored = false;
if(strpos($body['html'],"<button id=\"nsfw-wrap-") !== false && $collapse_all === false) {
$censored = true;
}
2018-09-20 03:47:31 +00:00
$result['children'] = [];
// place to store all the author addresses (links if not available) in the thread so we can auto-mention them in JS.
$result['authors'] = [];
$add_top_author = true;
if($observer && ($profile_addr === $observer['xchan_hash'] || $profile_addr === $observer['xchan_addr'])) {
$add_top_author = false;
}
if($add_top_author) {
$result['authors'][] = $profile_addr;
}
2018-09-20 03:47:31 +00:00
2012-09-11 05:00:56 +00:00
$nb_children = count($children);
2014-11-17 04:23:22 +00:00
$visible_comments = get_config('system','expanded_comments');
if($visible_comments === false)
$visible_comments = 3;
2018-08-02 00:58:54 +00:00
if($collapse_all) {
$visible_comments = 0;
}
2014-11-17 04:23:22 +00:00
if(($this->get_display_mode() === 'normal') && ($nb_children > 0)) {
2012-09-11 05:00:56 +00:00
foreach($children as $child) {
2018-08-02 00:58:54 +00:00
$xz = $child->get_template_data($conv_responses, $thread_level + 1);
if(strpos($xz['body'],"<button id=\"nsfw-wrap-") !== false && $collapse_all === false) {
$censored = true;
}
2018-09-20 03:47:31 +00:00
$author = $child->get_author();
if($author && ! in_array($author,$result['authors'])) {
if($observer && ($author === $observer['xchan_hash'] || $author === $observer['xchan_addr'])) {
continue;
}
2018-09-20 03:47:31 +00:00
$result['authors'][] = $author;
}
2018-08-02 00:58:54 +00:00
$result['children'][] = $xz;
2012-09-11 05:00:56 +00:00
}
// Collapse
if(($nb_children > $visible_comments) || ($thread_level > 1)) {
2012-09-11 05:00:56 +00:00
$result['children'][0]['comment_firstcollapsed'] = true;
2014-11-15 22:03:41 +00:00
$result['children'][0]['num_comments'] = $comment_count_txt;
2016-06-27 23:50:06 +00:00
$result['children'][0]['hide_text'] = sprintf( t('%s show all'), '<i class="fa fa-chevron-down"></i>');
2012-09-11 05:00:56 +00:00
if($thread_level > 1) {
$result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
}
else {
$result['children'][$nb_children - ($visible_comments + 1)]['comment_lastcollapsed'] = true;
2012-09-11 05:00:56 +00:00
}
}
}
if(count($result['authors']) > 6) {
$slice = array_slice($result['authors'],0,3);
$slice2 = array_slice($result['authors'],-3,3);
$result['authors'] = array_merge($slice,$slice2);
}
2018-09-21 23:29:13 +00:00
//logger('authors: ' . print_r($result['authors'],true));
2018-09-20 03:47:31 +00:00
$result['private'] = $item['item_private'];
2012-09-11 05:00:56 +00:00
$result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : '');
if($this->is_threaded()) {
$result['flatten'] = false;
$result['threaded'] = true;
}
else {
$result['flatten'] = true;
$result['threaded'] = false;
}
2018-08-02 00:58:54 +00:00
if($result['toplevel'] && $censored && (! $collapse_all) && get_pconfig($conv->get_profile_owner(),'nsfw','collapse_all',true)) {
$copy = $conv_responses;
$result = $this->get_template_data($copy, 1, true);
}
2012-09-11 05:00:56 +00:00
return $result;
}
public function get_id() {
return $this->get_data_value('id');
}
2014-11-17 04:23:22 +00:00
public function get_display_mode() {
return $this->display_mode;
}
public function set_display_mode($mode) {
$this->display_mode = $mode;
}
2012-09-11 05:00:56 +00:00
public function is_threaded() {
return $this->threaded;
}
2018-09-20 03:47:31 +00:00
public function get_author() {
$xchan = $this->get_data_value('author');
if($xchan['xchan_addr']) {
return $xchan['xchan_addr'];
}
return $xchan['xchan_url'];
}
public function set_reload($val) {
$this->reload = $val;
}
public function get_reload() {
return $this->reload;
}
public function set_commentable($val) {
$this->commentable = $val;
foreach($this->get_children() as $child)
$child->set_commentable($val);
}
public function is_commentable() {
return $this->commentable;
}
2012-09-11 05:00:56 +00:00
/**
* Add a child item
*/
public function add_child($item) {
$item_id = $item->get_id();
if(!$item_id) {
logger('[ERROR] Item::add_child : Item has no ID!!', LOGGER_DEBUG);
return false;
}
if($this->get_child($item->get_id())) {
logger('[WARN] Item::add_child : Item already exists ('. $item->get_id() .').', LOGGER_DEBUG);
return false;
}
/*
* Only add what will be displayed
*/
if(activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE)) {
2012-09-11 05:00:56 +00:00
return false;
}
$item->set_parent($this);
$this->children[] = $item;
return end($this->children);
}
/**
* Get a child by its ID
*/
public function get_child($id) {
foreach($this->get_children() as $child) {
if($child->get_id() == $id)
return $child;
}
return null;
}
/**
* Get all our children
2012-09-11 05:00:56 +00:00
*/
public function get_children() {
return $this->children;
}
/**
* Set our parent
*/
protected function set_parent($item) {
$parent = $this->get_parent();
if($parent) {
$parent->remove_child($this);
}
$this->parent = $item;
$this->set_conversation($item->get_conversation());
}
/**
* Remove our parent
*/
protected function remove_parent() {
$this->parent = null;
$this->conversation = null;
}
/**
* Remove a child
*/
public function remove_child($item) {
$id = $item->get_id();
foreach($this->get_children() as $key => $child) {
if($child->get_id() == $id) {
$child->remove_parent();
unset($this->children[$key]);
// Reindex the array, in order to make sure there won't be any trouble on loops using count()
$this->children = array_values($this->children);
return true;
}
}
logger('[WARN] Item::remove_child : Item is not a child ('. $id .').', LOGGER_DEBUG);
return false;
}
/**
* Get parent item
*/
protected function get_parent() {
return $this->parent;
}
/**
* set conversation
*/
public function set_conversation($conv) {
$previous_mode = ($this->conversation ? $this->conversation->get_mode() : '');
$this->conversation = $conv;
// Set it on our children too
foreach($this->get_children() as $child)
$child->set_conversation($conv);
}
/**
* get conversation
*/
public function get_conversation() {
return $this->conversation;
}
/**
* Get raw data
*
* We shouldn't need this
*/
public function get_data() {
return $this->data;
}
/**
* Get a data value
*
* Returns:
* _ value on success
* _ false on failure
*/
public function get_data_value($name) {
if(!isset($this->data[$name])) {
// logger('[ERROR] Item::get_data_value : Item has no value name "'. $name .'".', LOGGER_DEBUG);
2012-09-11 05:00:56 +00:00
return false;
}
return $this->data[$name];
}
/**
* Get template
*/
public function get_template() {
2012-09-11 05:00:56 +00:00
return $this->template;
}
public function set_template($t) {
$this->template = $t;
}
2012-09-11 05:00:56 +00:00
/**
* Check if this is a toplevel post
*/
private function is_toplevel() {
return $this->toplevel;
}
/**
* Count the total of our descendants
*/
private function count_descendants() {
$children = $this->get_children();
$total = count($children);
if($total > 0) {
foreach($children as $child) {
$total += $child->count_descendants();
}
}
return $total;
}
private function count_unseen_descendants() {
$children = $this->get_children();
$total = count($children);
if($total > 0) {
$total = 0;
foreach($children as $child) {
if((! visible_activity($child->data)) || array_key_exists('author_blocked',$child->data)) {
continue;
}
if(intval($child->data['item_unseen']))
$total ++;
}
}
return $total;
}
2012-09-11 05:00:56 +00:00
/**
* Get the template for the comment box
*/
private function get_comment_box_template() {
return $this->comment_box_template;
}
/**
* Get the comment box
*
* Returns:
* _ The comment box string (empty if no comment box)
* _ false on failure
*/
private function get_comment_box($indent) {
2012-09-11 05:00:56 +00:00
if(!$this->is_toplevel() && !get_config('system','thread_allow')) {
return '';
}
$comment_box = '';
$conv = $this->get_conversation();
// logger('Commentable conv: ' . $conv->is_commentable());
if(! $this->is_commentable())
2013-02-11 01:03:33 +00:00
return;
2012-09-11 05:00:56 +00:00
$template = get_markup_template($this->get_comment_box_template());
$observer = $conv->get_observer();
$arr = array('comment_buttons' => '','id' => $this->get_id());
2016-02-05 03:06:11 +00:00
call_hooks('comment_buttons',$arr);
$comment_buttons = $arr['comment_buttons'];
$feature_auto_save_draft = ((feature_enabled($conv->get_profile_owner(), 'auto_save_draft')) ? "true" : "false");
2016-02-05 03:06:11 +00:00
$comment_box = replace_macros($template,array(
'$return_path' => '',
'$threaded' => $this->is_threaded(),
'$jsreload' => $conv->reload,
'$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
'$id' => $this->get_id(),
'$parent' => $this->get_id(),
2016-02-05 03:06:11 +00:00
'$comment_buttons' => $comment_buttons,
'$profile_uid' => $conv->get_profile_owner(),
'$mylink' => $observer['xchan_url'],
'$mytitle' => t('This is you'),
'$myphoto' => $observer['xchan_photo_s'],
'$comment' => t('Comment'),
'$submit' => t('Submit'),
2018-10-04 02:10:52 +00:00
'$edat' => ((defined('NOMADIC')) ? '' : t('Add Conversation Mentions')),
'$edbold' => t('Bold'),
'$editalic' => t('Italic'),
'$eduline' => t('Underline'),
'$edquote' => t('Quote'),
'$edcode' => t('Code'),
'$edimg' => t('Image'),
'$edatt' => t('Attach/Upload file'),
'$edurl' => t('Insert Link'),
'$edvideo' => t('Video'),
2014-12-17 09:01:22 +00:00
'$preview' => t('Preview'), // ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
'$indent' => $indent,
'$can_upload' => (perm_is_allowed($conv->get_profile_owner(),get_observer_hash(),'write_storage') && $conv->is_uploadable()),
'$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false),
'$encrypt' => t('Encrypt text'),
'$cipher' => $conv->get_cipher(),
'$sourceapp' => \App::$sourcename,
'$observer' => get_observer_hash(),
'$anoncomments' => ((($conv->get_mode() === 'channel' || $conv->get_mode() === 'display') && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false),
2017-08-28 21:42:17 +00:00
'$anonname' => [ 'anonname', t('Your full name (required)') ],
'$anonmail' => [ 'anonmail', t('Your email address (required)') ],
'$anonurl' => [ 'anonurl', t('Your website URL (optional)') ],
'$auto_save_draft' => $feature_auto_save_draft,
));
2012-09-11 05:00:56 +00:00
return $comment_box;
}
private function get_redirect_url() {
return $this->redirect_url;
}
/**
* Check if we are a wall to wall item and set the relevant properties
*/
protected function check_wall_to_wall() {
$conv = $this->get_conversation();
$this->wall_to_wall = false;
$this->owner_url = '';
$this->owner_photo = '';
$this->owner_name = '';
2013-01-25 07:10:37 +00:00
if($conv->get_mode() === 'channel')
return;
2012-09-11 05:00:56 +00:00
if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) {
$this->owner_url = chanlink_hash($this->data['owner']['xchan_hash']);
$this->owner_photo = $this->data['owner']['xchan_photo_m'];
$this->owner_name = $this->data['owner']['xchan_name'];
$this->wall_to_wall = true;
2012-09-11 05:00:56 +00:00
}
}
private function is_wall_to_wall() {
return $this->wall_to_wall;
}
private function get_owner_url() {
return $this->owner_url;
}
private function get_owner_photo() {
return $this->owner_photo;
}
private function get_owner_name() {
return $this->owner_name;
}
private function is_visiting() {
return $this->visiting;
}
2012-09-11 05:00:56 +00:00
}