data = $data;
$this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
// Prepare the children
if($data['children']) {
foreach($data['children'] as $item) {
/*
* Only add those that will be displayed
*/
if((! visible_activity($item)) || array_key_exists('blocked',$item)) {
continue;
}
$child = new ThreadItem($item);
$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;
}
}
}
/**
* Get data in a form usable by a conversation template
*
* Returns:
* _ The data requested on success
* _ false on failure
*/
public function get_template_data($conv_responses, $thread_level = 1, $collapse_all = false) {
$result = array();
$item = $this->get_data();
$commentww = '';
$sparkle = '';
$buttons = '';
$dropping = false;
$star = false;
$isstarred = "unstarred fa-star-o";
$is_comment = false;
$is_item = false;
$osparkle = '';
$total_children = $this->count_descendants();
$unseen_comments = (($item['real_uid']) ? 0 : $this->count_unseen_descendants());
$conv = $this->get_conversation();
$observer = $conv->get_observer();
$lock = ((($item['item_private'] == 1) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
? t('Private Message')
: false);
$shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false);
// 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;
}
$mode = $conv->get_mode();
switch($item['item_type']) {
case ITEM_TYPE_CARD:
$edlink = 'card_edit';
break;
case ITEM_TYPE_ARTICLE:
$edlink = 'article_edit';
break;
default:
$edlink = 'editpost';
break;
}
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
$edpost = array(z_root() . '/' . $edlink . '/' . $item['id'], t('Edit'));
else
$edpost = false;
if($item['verb'] === 'Announce') {
$edpost = false;
}
if($observer['xchan_hash'] == $this->get_data_value('author_xchan')
|| $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
|| $this->get_data_value('uid') == local_channel())
$dropping = true;
if(array_key_exists('real_uid',$item)) {
$edpost = false;
$dropping = false;
}
if($dropping) {
$drop = array(
'dropping' => $dropping,
'delete' => t('Delete'),
);
}
elseif(is_site_admin()) {
$drop = [ 'dropping' => true, 'delete' => t('Admin Delete') ];
}
// FIXME
if($observer_is_pageowner) {
$multidrop = array(
'select' => t('Select'),
);
}
$filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false);
$profile_avatar = $item['author']['xchan_photo_m'];
$profile_link = chanlink_hash($item['author_xchan']);
$profile_name = $item['author']['xchan_name'];
$profile_addr = $item['author']['xchan_addr'] ? : $item['author']['xchan_url'];
$location = format_location($item);
$isevent = false;
$attend = null;
$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';
if($item['obj_type'] === ACTIVITY_OBJ_EVENT) {
$response_verbs[] = 'attendyes';
$response_verbs[] = 'attendno';
$response_verbs[] = 'attendmaybe';
if($this->is_commentable() && $observer) {
$isevent = true;
$attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
}
}
$consensus = (intval($item['item_consensus']) ? true : false);
if($consensus) {
$response_verbs[] = 'agree';
$response_verbs[] = 'disagree';
$response_verbs[] = 'abstain';
if($this->is_commentable() && $observer) {
$conlabels = array( t('I agree'), t('I disagree'), t('I abstain'));
$canvote = true;
}
}
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'] : '');
if (($like_list) && (count($like_list) > MAX_LIKERS)) {
$like_list_part = array_slice($like_list, 0, MAX_LIKERS);
array_push($like_list_part, '' . t('View all') . '');
} else {
$like_list_part = '';
}
$like_button_label = tt('Like','Likes',$like_count,'noun');
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');
if (($dislike_list) && (count($dislike_list) > MAX_LIKERS)) {
$dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS);
array_push($dislike_list_part, '' . t('View all') . '');
} else {
$dislike_list_part = '';
}
}
$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']) : '');
/*
* 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
*/
$this->check_wall_to_wall();
if($this->is_toplevel()) {
// FIXME check this permission
if(($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) {
$star = array(
'toggle' => t("Toggle Star Status"),
'isstarred' => ((intval($item['item_starred'])) ? true : false),
);
}
}
else {
$is_comment = true;
}
$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') : '');
// FIXME - check this permission
if($conv->get_profile_owner() == local_channel()) {
$tagger = array(
'tagit' => t("Add Tag"),
'classtagger' => "",
);
}
$has_bookmarks = false;
if(is_array($item['term'])) {
foreach($item['term'] as $t) {
if($t['ttype'] == TERM_BOOKMARK)
$has_bookmarks = true;
}
}
$has_event = false;
if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel())
$has_event = true;
if($this->is_commentable() && $observer) {
$like = array( t("I like this \x28toggle\x29"), t("like"));
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
}
if ($shareable)
$share = array( t('Share This'), t('share'));
$dreport = '';
$keep_reports = intval(get_config('system','expire_delivery_reports'));
if($keep_reports === 0)
$keep_reports = 10;
if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0) {
$dreport = t('Delivery Report');
$dreport_link = gen_link_id($item['mid']);
}
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
$is_new = true;
localize_item($item);
if($this->is_toplevel() && $collapse_all) {
$item['collapse'] = true;
}
$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')
$viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . urlencode(gen_link_id($item['mid']));
$comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
$list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : '');
$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'];
$tmp_item = array(
'template' => $this->get_template(),
'mode' => $mode,
'item_type' => intval($item['item_type']),
'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']),
'id' => $this->get_id(),
'mid' => $item['mid'],
'isevent' => $isevent,
'attend' => $attend,
'consensus' => $consensus,
'conlabels' => $conlabels,
'canvote' => $canvote,
'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,
'to' => t('to'),
'via' => t('via'),
'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()),
'dreport' => $dreport,
'dreport_link' => $dreport_link,
'name' => $profile_name,
'thumb' => $profile_avatar,
'osparkle' => $osparkle,
'sparkle' => $sparkle,
'title' => $item['title'],
'title_tosource' => get_pconfig($conv->get_profile_owner(),'system','title_tosource'),
'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'),
'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')) : ''),
'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''),
'lock' => $lock,
'privacy_warning' => $privacy_warning,
'verified' => $verified,
'unverified' => $unverified,
'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,
'owner_url' => $this->get_owner_url(),
'owner_photo' => $this->get_owner_photo(),
'owner_name' => $this->get_owner_name(),
'photo' => $body['photo'],
'event' => $body['event'],
'has_tags' => $has_tags,
'reactions' => $this->reactions,
// Item toolbar buttons
'emojis' => '', // (($this->is_toplevel() && $this->is_commentable() && $observer && feature_enabled($conv->get_profile_owner(),'emojis')) ? '1' : ''),
'like' => $like,
'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike : ''),
'share' => $share,
'rawmid' => $item['mid'],
'plink' => get_plink($item),
'edpost' => $edpost, // ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''),
'star' => ((feature_enabled($conv->get_profile_owner(),'star_posts')) ? $star : ''),
'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''),
'filer' => ((feature_enabled($conv->get_profile_owner(),'filing')) ? $filer : ''),
'bookmark' => (($conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks) ? t('Save Bookmarks') : ''),
'addtocal' => (($has_event) ? t('Add to Calendar') : ''),
'drop' => $drop,
'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''),
'dropdown_extras' => $dropdown_extras,
// end toolbar buttons
'unseen_comments' => $unseen_comments,
'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,
'like_count' => $like_count,
'like_list' => $like_list,
'like_list_part' => $like_list_part,
'like_button_label' => $like_button_label,
'like_modal_title' => t('Likes','noun'),
'dislike_modal_title' => t('Dislikes','noun'),
'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 : ''),
'dislike_button_label' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_button_label : ''),
'modal_dismiss' => t('Close'),
'showlike' => $showlike,
'showdislike' => $showdislike,
'comment' => $this->get_comment_box($indent),
'previewing' => ($conv->is_preview() ? true : false ),
'preview_lbl' => t('This is an unsaved preview'),
'wait' => t('Please wait'),
'submid' => str_replace(['+','='], ['',''], base64_encode($item['mid'])),
'thread_level' => $thread_level
);
$arr = array('item' => $item, 'output' => $tmp_item);
call_hooks('display_item', $arr);
$result = $arr['output'];
$censored = false;
if(strpos($body['html'],"