2021-12-03 03:01:39 +00:00
< ? php
/** @file */
2011-04-11 04:21:16 +00:00
2022-02-16 04:08:28 +00:00
use Code\Lib\Apps ;
use Code\Lib\LibBlock ;
2023-06-04 20:57:12 +00:00
use Code\Lib\PConfig ;
2022-02-16 04:08:28 +00:00
use Code\Lib\ThreadStream ;
use Code\Lib\ThreadItem ;
use Code\Lib\Channel ;
use Code\Lib\Features ;
use Code\Extend\Hook ;
use Code\Access\Permissions ;
use Code\Access\PermissionLimits ;
2024-03-10 02:40:50 +00:00
use Code\Lib\Time ;
2023-01-26 07:29:09 +00:00
use Code\Lib\XConfig ;
2022-02-16 04:08:28 +00:00
use Code\Render\Theme ;
2022-02-12 20:43:29 +00:00
2011-04-18 15:37:02 +00:00
/**
* Render actions localized
*/
2012-11-14 00:04:22 +00:00
2021-12-03 03:01:39 +00:00
function localize_item ( & $item )
{
2022-10-24 08:35:13 +00:00
if ( activity_match ( $item [ 'verb' ], ACTIVITY_LIKE ) || activity_match ( $item [ 'verb' ], ACTIVITY_DISLIKE )
|| $item [ 'verb' ] === 'Announce' ) {
2021-12-03 03:01:39 +00:00
if ( ! $item [ 'obj' ]) {
return ;
}
if ( intval ( $item [ 'item_thread_top' ])) {
return ;
}
$obj = (( is_array ( $item [ 'obj' ])) ? $item [ 'obj' ] : json_decode ( $item [ 'obj' ], true ));
if ( ! is_array ( $obj )) {
logger ( 'localize_item: failed to decode object: ' . print_r ( $item [ 'obj' ], true ));
return ;
}
2022-04-25 00:22:18 +00:00
if ( isset ( $obj [ 'actor' ]) && is_string ( $obj [ 'actor' ]) && $obj [ 'actor' ]) {
$author_link = $obj [ 'actor' ];
2022-10-24 08:35:13 +00:00
}
elseif ( isset ( $obj [ 'attributedTo' ]) && is_string ( $obj [ 'attributedTo' ]) && $obj [ 'attributedTo' ]) {
2022-04-25 00:22:18 +00:00
$author_link = $obj [ 'attributedTo' ];
}
else {
$author_link = EMPTY_STR ;
2021-12-03 03:01:39 +00:00
}
2022-04-25 00:22:18 +00:00
$author_name = (( array_path_exists ( 'author/name' , $obj ) && $obj [ 'author' ][ 'name' ]) ? $obj [ 'author' ][ 'name' ] : '' );
2021-12-03 03:01:39 +00:00
2022-04-25 00:22:18 +00:00
if ( isset ( $obj [ 'link' ])) {
$item_url = get_rel_link ( $obj [ 'link' ], 'alternate' );
}
2021-12-03 03:01:39 +00:00
$Bphoto = '' ;
switch ( $obj [ 'type' ]) {
case ACTIVITY_OBJ_PHOTO :
$post_type = t ( 'photo' );
break ;
case ACTIVITY_OBJ_EVENT :
$post_type = t ( 'event' );
break ;
case ACTIVITY_OBJ_PERSON :
$post_type = t ( 'channel' );
$author_name = $obj [ 'title' ];
if ( $obj [ 'link' ]) {
$author_link = get_rel_link ( $obj [ 'link' ], 'alternate' );
$Bphoto = get_rel_link ( $obj [ 'link' ], 'photo' );
}
break ;
case ACTIVITY_OBJ_THING :
$post_type = $obj [ 'title' ];
if ( $obj [ 'owner' ]) {
if ( array_key_exists ( 'name' , $obj [ 'owner' ])) {
2022-09-17 23:28:33 +00:00
$author_name = $obj [ 'owner' ][ 'name' ];
2021-12-03 03:01:39 +00:00
}
if ( array_key_exists ( 'link' , $obj [ 'owner' ])) {
$author_link = get_rel_link ( $obj [ 'owner' ][ 'link' ], 'alternate' );
}
}
if ( $obj [ 'link' ]) {
$Bphoto = get_rel_link ( $obj [ 'link' ], 'photo' );
}
break ;
case ACTIVITY_OBJ_NOTE :
default :
$post_type = t ( 'post' );
if ( $obj [ 'id' ] != $obj [ 'parent' ]) {
$post_type = t ( 'comment' );
}
break ;
}
// If we couldn't parse something useful, don't bother translating.
// We need something better than zid here, probably magic_link(), but it needs writing
if ( $author_link && $author_name && $item_url ) {
$author = '[zrl=' . chanlink_url ( $item [ 'author' ][ 'xchan_url' ]) . ']' . $item [ 'author' ][ 'xchan_name' ] . '[/zrl]' ;
$objauthor = '[zrl=' . chanlink_url ( $author_link ) . ']' . $author_name . '[/zrl]' ;
$plink = '[zrl=' . zid ( $item_url ) . ']' . $post_type . '[/zrl]' ;
if ( activity_match ( $item [ 'verb' ], ACTIVITY_LIKE )) {
$bodyverb = t ( '%1$s likes %2$s\'s %3$s' );
} elseif ( activity_match ( $item [ 'verb' ], ACTIVITY_DISLIKE )) {
$bodyverb = t ( '%1$s doesn\'t like %2$s\'s %3$s' );
} elseif ( $item [ 'verb' ] === 'Announce' ) {
$bodyverb = t ( '%1$s repeated %2$s\'s %3$s' );
}
// short version, in notification strings the author will be displayed separately
if ( activity_match ( $item [ 'verb' ], ACTIVITY_LIKE )) {
$shortbodyverb = t ( 'likes %1$s\'s %2$s' );
} elseif ( activity_match ( $item [ 'verb' ], ACTIVITY_DISLIKE )) {
$shortbodyverb = t ( 'doesn\'t like %1$s\'s %2$s' );
} elseif ( $item [ 'verb' ] === 'Announce' ) {
$shortbodyverb = t ( 'repeated %1$s\'s %2$s' );
}
if ( $shortbodyverb ) {
$item [ 'shortlocalize' ] = sprintf ( $shortbodyverb , $objauthor , $plink );
}
$item [ 'body' ] = $item [ 'localize' ] = sprintf ( $bodyverb , $author , $objauthor , $plink );
if ( $Bphoto != " " ) {
$item [ 'body' ] .= " \n \n \n " . '[zrl=' . chanlink_url ( $author_link ) . '][zmg width="80" height="80"]' . $Bphoto . '[/zmg][/zrl]' ;
}
}
}
2012-09-11 05:00:56 +00:00
2021-12-03 03:01:39 +00:00
if ( activity_match ( $item [ 'verb' ], ACTIVITY_FRIEND )) {
if ( $item [ 'obj_type' ] == " " || $item [ 'obj_type' ] !== ACTIVITY_OBJ_PERSON ) {
return ;
}
2012-11-07 00:16:26 +00:00
2021-12-03 03:01:39 +00:00
$Aname = $item [ 'author' ][ 'xchan_name' ];
$Alink = $item [ 'author' ][ 'xchan_url' ];
2011-04-18 15:37:02 +00:00
2011-04-20 11:50:12 +00:00
2021-12-03 03:01:39 +00:00
$obj = json_decode ( $item [ 'obj' ], true );
2012-09-11 05:00:56 +00:00
2021-12-03 03:01:39 +00:00
$Blink = $Bphoto = '' ;
2012-09-11 05:00:56 +00:00
2021-12-03 03:01:39 +00:00
if ( $obj [ 'link' ]) {
$Blink = get_rel_link ( $obj [ 'link' ], 'alternate' );
$Bphoto = get_rel_link ( $obj [ 'link' ], 'photo' );
}
$Bname = $obj [ 'title' ];
2012-09-11 05:00:56 +00:00
2012-11-14 03:32:59 +00:00
2021-12-03 03:01:39 +00:00
$A = '[zrl=' . chanlink_url ( $Alink ) . ']' . $Aname . '[/zrl]' ;
$B = '[zrl=' . chanlink_url ( $Blink ) . ']' . $Bname . '[/zrl]' ;
if ( $Bphoto != " " ) {
$Bphoto = '[zrl=' . chanlink_url ( $Blink ) . '][zmg=80x80]' . $Bphoto . '[/zmg][/zrl]' ;
}
2012-09-11 05:00:56 +00:00
2021-12-03 03:01:39 +00:00
$item [ 'body' ] = $item [ 'localize' ] = sprintf ( t ( '%1$s is now connected with %2$s' ), $A , $B );
$item [ 'body' ] .= " \n \n \n " . $Bphoto ;
}
2011-04-18 15:37:02 +00:00
2021-12-03 03:01:39 +00:00
if ( stristr ( $item [ 'verb' ], ACTIVITY_POKE )) {
2012-11-14 03:32:59 +00:00
2021-12-03 03:01:39 +00:00
$verb = urldecode ( substr ( $item [ 'verb' ], strpos ( $item [ 'verb' ], '#' ) + 1 ));
if ( ! $verb ) {
return ;
}
2013-12-08 07:29:26 +00:00
2021-12-03 03:01:39 +00:00
if ( $item [ 'obj_type' ] == " " || $item [ 'obj_type' ] !== ACTIVITY_OBJ_PERSON ) {
return ;
}
2015-03-21 21:03:59 +00:00
2021-12-03 03:01:39 +00:00
$Aname = $item [ 'author' ][ 'xchan_name' ];
$Alink = $item [ 'author' ][ 'xchan_url' ];
2012-07-20 01:53:26 +00:00
2021-12-03 03:01:39 +00:00
$obj = json_decode ( $item [ 'obj' ], true );
2012-09-11 05:00:56 +00:00
2021-12-03 03:01:39 +00:00
$Blink = $Bphoto = '' ;
2015-03-21 21:03:59 +00:00
2021-12-03 03:01:39 +00:00
if ( $obj [ 'link' ]) {
$Blink = get_rel_link ( $obj [ 'link' ], 'alternate' );
$Bphoto = get_rel_link ( $obj [ 'link' ], 'photo' );
}
$Bname = $obj [ 'title' ];
2012-09-11 05:00:56 +00:00
2021-12-03 03:01:39 +00:00
$A = '[zrl=' . chanlink_url ( $Alink ) . ']' . $Aname . '[/zrl]' ;
$B = '[zrl=' . chanlink_url ( $Blink ) . ']' . $Bname . '[/zrl]' ;
if ( $Bphoto != " " ) {
$Bphoto = '[zrl=' . chanlink_url ( $Blink ) . '][zmg=80x80]' . $Bphoto . '[/zmg][/zrl]' ;
}
2012-09-11 05:00:56 +00:00
2021-12-03 03:01:39 +00:00
// we can't have a translation string with three positions but no distinguishable text
2022-12-22 07:51:22 +00:00
// So here is the translation string.
2012-07-20 01:53:26 +00:00
2021-12-03 03:01:39 +00:00
$txt = t ( '%1$s poked %2$s' );
2012-07-20 01:53:26 +00:00
2021-12-03 03:01:39 +00:00
// now translate the verb
2012-07-20 01:53:26 +00:00
2021-12-03 03:01:39 +00:00
$txt = str_replace ( t ( 'poked' ), t ( $verb ), $txt );
2012-07-20 01:53:26 +00:00
2021-12-03 03:01:39 +00:00
// then do the sprintf on the translation string
2012-07-20 01:53:26 +00:00
2021-12-03 03:01:39 +00:00
$item [ 'body' ] = $item [ 'localize' ] = sprintf ( $txt , $A , $B );
$item [ 'body' ] .= " \n \n \n " . $Bphoto ;
}
if ( stristr ( $item [ 'verb' ], ACTIVITY_MOOD )) {
$verb = urldecode ( substr ( $item [ 'verb' ], strpos ( $item [ 'verb' ], '#' ) + 1 ));
if ( ! $verb ) {
return ;
}
2012-07-20 01:53:26 +00:00
2021-12-03 03:01:39 +00:00
$Aname = $item [ 'author' ][ 'xchan_name' ];
$Alink = $item [ 'author' ][ 'xchan_url' ];
2012-08-24 03:00:10 +00:00
2021-12-03 03:01:39 +00:00
$A = '[zrl=' . chanlink_url ( $Alink ) . ']' . $Aname . '[/zrl]' ;
2012-11-14 03:32:59 +00:00
2021-12-03 03:01:39 +00:00
$txt = t ( '%1$s is %2$s' , 'mood' );
2012-08-24 03:00:10 +00:00
2021-12-03 03:01:39 +00:00
$item [ 'body' ] = sprintf ( $txt , $A , t ( $verb ));
}
2011-04-18 15:37:02 +00:00
}
2012-08-09 23:26:44 +00:00
/**
2015-03-21 21:03:59 +00:00
* @ brief Count the total of comments on this item and its desendants .
*
2022-10-24 08:35:13 +00:00
* @ param array $item an associative item - array which provides :
2015-03-21 21:03:59 +00:00
* * \e array \b children
* @ return number
2012-08-09 23:26:44 +00:00
*/
2017-03-24 04:49:20 +00:00
2021-12-03 03:01:39 +00:00
function count_descendants ( $item )
{
2012-09-21 00:04:22 +00:00
2021-12-03 03:01:39 +00:00
$total = count ( $item [ 'children' ]);
2012-08-09 23:26:44 +00:00
2021-12-03 03:01:39 +00:00
if ( $total > 0 ) {
foreach ( $item [ 'children' ] as $child ) {
if ( ! visible_activity ( $child )) {
$total -- ;
}
2015-03-21 21:03:59 +00:00
2021-12-03 03:01:39 +00:00
$total += count_descendants ( $child );
}
}
2012-08-09 23:26:44 +00:00
2021-12-03 03:01:39 +00:00
return $total ;
2012-08-09 23:26:44 +00:00
}
2015-03-21 21:03:59 +00:00
/**
* @ brief Check if the activity of the item is visible .
*
* likes ( etc . ) can apply to other things besides posts . Check if they are post
2015-08-27 00:49:57 +00:00
* children , in which case we handle them specially . Activities which are unrecognised
* as having special meaning and hidden will be treated as posts or comments and visible
2021-12-03 03:01:39 +00:00
* in the stream .
2015-03-21 21:03:59 +00:00
*
* @ param array $item
2021-12-02 23:02:31 +00:00
* @ return bool
2015-03-21 21:03:59 +00:00
*/
2021-12-03 03:01:39 +00:00
function visible_activity ( $item )
{
2024-03-22 07:41:37 +00:00
$hidden_activities = [ ACTIVITY_LIKE , ACTIVITY_DISLIKE , 'Announce' , 'Undo' , 'Accept' , 'Reject' ];
2012-09-21 00:04:22 +00:00
2021-12-03 03:01:39 +00:00
if ( intval ( $item [ 'item_notshown' ])) {
return false ;
}
2024-01-31 09:29:16 +00:00
2023-08-18 21:14:59 +00:00
// normal poll responses
2021-12-03 03:01:39 +00:00
if ( $item [ 'obj_type' ] === 'Answer' ) {
return false ;
}
2021-06-22 09:16:28 +00:00
2023-08-18 21:14:59 +00:00
// imported poll responses
if ( $item [ 'title' ] && $item [ 'mid' ] !== $item [ 'parent_mid' ] && ! $item [ 'body' ] && ! $item [ 'summary' ]) {
return false ;
}
2024-02-24 22:43:13 +00:00
// we didn't receive the initial post over the network so hide the initial add activity from yourself.
// It is just a duplicate of your top-level post.
if ( $item [ 'verb' ] === 'Add' && ( int ) $item [ 'item_level' ] === 1 && $item [ 'item_wall' ]) {
return false ;
}
2021-12-03 03:01:39 +00:00
// This is an experiment at group federation with microblog platforms.
// We need the Announce or "boost" for group replies by non-connections to end up in the personal timeline
// of those patforms. Hide them on our own platform because they make the conversation look like dung.
// Performance wise this is a mess because we need to send two activities for every group comment.
2021-06-22 09:16:28 +00:00
2023-03-07 04:56:57 +00:00
if ( $item [ 'verb' ] === 'Announce' ) {
2024-03-05 05:09:24 +00:00
// if ($item['author_xchan'] === $item['owner_xchan']) {
// return false;
// }
2023-03-07 04:56:57 +00:00
if ( isset ( $item [ 'author' ]) && intval ( $item [ 'author' ][ 'xchan_type' ]) === XCHAN_TYPE_GROUP ) {
return false ;
}
2021-12-03 03:01:39 +00:00
}
2015-03-21 21:03:59 +00:00
2021-12-03 03:01:39 +00:00
foreach ( $hidden_activities as $act ) {
if (( activity_match ( $item [ 'verb' ], $act )) && ( $item [ 'mid' ] != $item [ 'parent_mid' ])) {
return false ;
}
}
2016-10-25 23:21:56 +00:00
2021-12-03 03:01:39 +00:00
if ( in_array ( $item [ 'obj_type' ], [ 'Event' , 'Invite' ]) && in_array ( $item [ 'verb' ], [ 'Accept' , 'Reject' , 'TentativeAccept' , 'TentativeReject' , 'Ignore' ])) {
return false ;
}
return true ;
2016-10-25 23:21:56 +00:00
}
2011-04-13 00:58:16 +00:00
/**
2015-03-21 21:03:59 +00:00
* @ brief " Render " a conversation or list of items for HTML display .
*
2011-04-13 00:58:16 +00:00
* There are two major forms of display :
2015-03-21 21:03:59 +00:00
* - Sequential or unthreaded ( " New Item View " or search results )
* - conversation view
*
2011-04-13 00:58:16 +00:00
* The $mode parameter decides between the various renderings and also
2012-09-11 05:00:56 +00:00
* figures out how to determine page owner and other contextual items
2011-04-13 00:58:16 +00:00
* that are based on unique features of the calling module .
*
2015-03-21 21:03:59 +00:00
* @ param array $items
* @ param string $mode
2021-12-02 23:02:31 +00:00
* @ param bool $update
2015-03-21 21:03:59 +00:00
* @ param string $page_mode default traditional
* @ param string $prepared_item
* @ return string
2011-04-13 00:58:16 +00:00
*/
2021-12-03 03:01:39 +00:00
function conversation ( $items , $mode , $update , $page_mode = 'traditional' , $prepared_item = '' )
{
2011-04-11 06:01:38 +00:00
2021-12-03 03:01:39 +00:00
$content_html = '' ;
$o = '' ;
2012-10-26 01:42:42 +00:00
2021-12-03 03:01:39 +00:00
require_once ( 'bbcode.php' );
2012-11-29 02:45:11 +00:00
2022-09-17 23:28:33 +00:00
$ssl_state = ( bool ) local_channel ();
2012-11-29 02:45:11 +00:00
2021-12-03 03:01:39 +00:00
if ( local_channel ()) {
2022-09-18 00:14:35 +00:00
load_pconfig ( local_channel ());
2021-12-03 03:01:39 +00:00
}
2012-07-25 05:06:21 +00:00
2021-12-03 03:01:39 +00:00
$profile_owner = 0 ;
$live_update_div = '' ;
$jsreload = '' ;
2022-09-18 00:14:35 +00:00
$preview = $page_mode === 'preview' ;
2021-12-03 03:01:39 +00:00
$previewing = (( $preview ) ? ' preview ' : '' );
$preview_lbl = t ( 'This is an unsaved preview' );
if ( in_array ( $mode , [ 'stream' , 'pubstream' ])) {
$profile_owner = local_channel ();
if ( ! $update ) {
// The special div is needed for liveUpdate to kick in for this page.
// We only launch liveUpdate if you aren't filtering in some incompatible
2022-12-22 07:51:22 +00:00
// way, and also you aren't writing a comment (discovered in javascript).
2021-12-03 03:01:39 +00:00
$live_update_div = '<div id="live-stream"></div>' . " \r \n "
2022-09-17 23:28:33 +00:00
. " <script> let profile_uid = " . (( isset ( $_SESSION [ 'uid' ])) ? intval ( $_SESSION [ 'uid' ]) : 0 )
. " ; let netargs = ' " . substr ( App :: $cmd , 8 )
2021-12-03 03:01:39 +00:00
. '?f='
. (( x ( $_GET , 'cid' )) ? '&cid=' . $_GET [ 'cid' ] : '' )
. (( x ( $_GET , 'search' )) ? '&search=' . $_GET [ 'search' ] : '' )
. (( x ( $_GET , 'star' )) ? '&star=' . $_GET [ 'star' ] : '' )
. (( x ( $_GET , 'order' )) ? '&order=' . $_GET [ 'order' ] : '' )
. (( x ( $_GET , 'bmark' )) ? '&bmark=' . $_GET [ 'bmark' ] : '' )
. (( x ( $_GET , 'liked' )) ? '&liked=' . $_GET [ 'liked' ] : '' )
. (( x ( $_GET , 'conv' )) ? '&conv=' . $_GET [ 'conv' ] : '' )
. (( x ( $_GET , 'spam' )) ? '&spam=' . $_GET [ 'spam' ] : '' )
. (( x ( $_GET , 'nets' )) ? '&nets=' . $_GET [ 'nets' ] : '' )
. (( x ( $_GET , 'cmin' )) ? '&cmin=' . $_GET [ 'cmin' ] : '' )
. (( x ( $_GET , 'cmax' )) ? '&cmax=' . $_GET [ 'cmax' ] : '' )
. (( x ( $_GET , 'file' )) ? '&file=' . $_GET [ 'file' ] : '' )
. (( x ( $_GET , 'uri' )) ? '&uri=' . $_GET [ 'uri' ] : '' )
. (( x ( $_GET , 'pf' )) ? '&pf=' . $_GET [ 'pf' ] : '' )
2022-09-17 23:28:33 +00:00
. " '; let profile_page = " . App :: $pager [ 'page' ] . " ; </script> \r \n " ;
2021-12-03 03:01:39 +00:00
}
} elseif ( $mode === 'channel' ) {
$profile_owner = App :: $profile [ 'profile_uid' ];
if ( ! $update ) {
$tab = notags ( trim ( $_GET [ 'tab' ]));
if ( $tab === 'posts' ) {
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
// because browser prefetching might change it on us. We have to deliver it with the page.
$live_update_div = '<div id="live-channel"></div>' . " \r \n "
2022-09-18 00:14:35 +00:00
. " <script> let profile_uid = " . App :: $profile [ 'profile_uid' ]
. " ; let netargs = '?f='; let profile_page = " . App :: $pager [ 'page' ] . " ; </script> \r \n " ;
2021-12-03 03:01:39 +00:00
}
}
} elseif ( $mode === 'display' ) {
$profile_owner = local_channel ();
$live_update_div = '<div id="live-display"></div>' . " \r \n " ;
} elseif ( $mode === 'page' ) {
$profile_owner = App :: $profile [ 'uid' ];
$live_update_div = '<div id="live-page"></div>' . " \r \n " ;
} elseif ( $mode === 'search' ) {
$live_update_div = '<div id="live-search"></div>' . " \r \n " ;
} elseif ( $mode === 'moderate' ) {
$profile_owner = local_channel ();
} elseif ( $mode === 'photos' ) {
$profile_owner = App :: $profile [ 'profile_uid' ];
$live_update_div = '<div id="live-photos"></div>' . " \r \n " ;
// for photos we've already formatted the top-level item (the photo)
$content_html = App :: $data [ 'photo_html' ];
}
2011-04-11 04:21:16 +00:00
2021-12-03 03:01:39 +00:00
$page_dropping = (( local_channel () && local_channel () == $profile_owner ) ? true : false );
2012-01-11 01:47:11 +00:00
2022-01-25 23:20:02 +00:00
if ( ! Features :: enabled ( $profile_owner , 'multi_delete' )) {
2021-12-03 03:01:39 +00:00
$page_dropping = false ;
}
2011-04-11 04:21:16 +00:00
2021-12-03 03:01:39 +00:00
$uploading = (( local_channel ()) ? true : false );
2015-02-10 22:47:09 +00:00
2021-12-03 03:01:39 +00:00
$channel = App :: get_channel ();
$observer = App :: get_observer ();
2012-09-11 05:00:56 +00:00
2021-12-03 03:01:39 +00:00
if ( $update && isset ( $_SESSION [ 'return_url' ])) {
$return_url = $_SESSION [ 'return_url' ];
} else {
$return_url = $_SESSION [ 'return_url' ] = App :: $query_string ;
}
load_contact_links ( local_channel ());
2022-09-17 23:28:33 +00:00
$cb = [ 'items' => $items , 'mode' => $mode , 'update' => $update , 'preview' => $preview ];
2022-02-12 08:50:48 +00:00
Hook :: call ( 'conversation_start' , $cb );
2021-12-03 03:01:39 +00:00
$items = $cb [ 'items' ];
$conv_responses = [
'like' => [ 'title' => t ( 'Likes' , 'title' ) ],
'dislike' => [ 'title' => t ( 'Dislikes' , 'title' ) ],
2024-03-22 07:27:28 +00:00
'repeat' => [ 'title' => t ( 'Repeats' , 'title' ) ],
2021-12-03 03:01:39 +00:00
'attendyes' => [ 'title' => t ( 'Attending' , 'title' ) ],
'attendno' => [ 'title' => t ( 'Not attending' , 'title' ) ],
'attendmaybe' => [ 'title' => t ( 'Might attend' , 'title' ) ]
];
2012-08-09 23:26:44 +00:00
2012-09-11 05:00:56 +00:00
2021-12-03 03:01:39 +00:00
// array with html for each thread (parent+comments)
$threads = [];
$threadsid = - 1 ;
2011-04-11 04:21:16 +00:00
2022-02-12 20:43:29 +00:00
$page_template = Theme :: get_template ( " conversation.tpl " );
2011-04-11 04:21:16 +00:00
2021-12-03 03:01:39 +00:00
if ( $items ) {
if ( in_array ( $mode , [ 'stream-new' , 'search' , 'community' , 'moderate' ])) {
// "New Item View" on stream page or search page results
// - just loop through the items and format them minimally for display
2011-04-11 04:21:16 +00:00
2021-12-03 03:01:39 +00:00
$tpl = 'search_item.tpl' ;
2011-04-11 04:21:16 +00:00
2021-12-03 03:01:39 +00:00
foreach ( $items as $item ) {
$x = [
'mode' => $mode ,
'item' => $item
];
2022-02-12 08:50:48 +00:00
Hook :: call ( 'stream_item' , $x );
2013-04-29 05:46:07 +00:00
2021-12-03 03:01:39 +00:00
$item = $x [ 'item' ];
2013-04-29 05:46:07 +00:00
2021-12-03 03:01:39 +00:00
$threadsid ++ ;
$comment = '' ;
$owner_url = '' ;
$owner_photo = '' ;
$owner_name = '' ;
$sparkle = '' ;
$is_new = false ;
if ( $mode === 'search' || $mode === 'community' ) {
if (
(( activity_match ( $item [ 'verb' ], ACTIVITY_LIKE )) || ( activity_match ( $item [ 'verb' ], ACTIVITY_DISLIKE )))
&& ( $item [ 'id' ] != $item [ 'parent' ])
) {
continue ;
}
}
$profile_name = $item [ 'author' ][ 'xchan_name' ];
$profile_link = $item [ 'author' ][ 'xchan_url' ];
$profile_avatar = $item [ 'author' ][ 'xchan_photo_m' ];
2022-12-02 19:42:40 +00:00
$large_avatar = $item [ 'author' ][ 'xchan_photo_l' ];
2021-12-03 03:01:39 +00:00
if ( $item [ 'mid' ] === $item [ 'parent_mid' ] && $item [ 'author_xchan' ] !== $item [ 'owner_xchan' ]) {
$owner_name = $item [ 'owner' ][ 'xchan_name' ];
$owner_url = $item [ 'owner' ][ 'xchan_url' ];
$owner_photo = $item [ 'owner' ][ 'xchan_photo' ];
}
$location = format_location ( $item );
localize_item ( $item );
if ( $mode === 'stream-new' ) {
2024-06-11 05:44:29 +00:00
$dropping = ( bool ) local_channel () === ( int ) $item [ 'uid' ];
2021-12-03 03:01:39 +00:00
} else {
$dropping = false ;
}
2022-09-17 23:28:33 +00:00
$drop = [
2021-12-03 03:01:39 +00:00
'pagedropping' => $page_dropping ,
'dropping' => $dropping ,
'select' => t ( 'Select' ),
'delete' => t ( 'Delete' ),
2022-09-17 23:28:33 +00:00
];
2021-12-03 03:01:39 +00:00
2022-09-17 23:28:33 +00:00
$star = [
2021-12-03 03:01:39 +00:00
'toggle' => t ( " Toggle Star Status " ),
2023-01-16 07:12:31 +00:00
'isstarred' => ( bool ) intval ( $item [ 'item_starred' ]),
2022-09-17 23:28:33 +00:00
];
2021-12-03 03:01:39 +00:00
2022-08-05 21:14:47 +00:00
$lock = t ( 'Public visibility' );
if ( intval ( $item [ 'item_private' ]) === 2 ) {
$lock = t ( 'Direct message (private mail)' );
}
if ( intval ( $item [ 'item_private' ]) === 1 ) {
$lock = t ( 'Restricted visibility' );
}
2021-12-21 22:03:17 +00:00
2022-08-05 21:14:47 +00:00
$locktype = intval ( $item [ 'item_private' ]);
2021-12-03 03:01:39 +00:00
$verified = ( intval ( $item [ 'item_verified' ]) ? t ( 'Message signature validated' ) : '' );
$forged = ((( $item [ 'sig' ]) && ( ! intval ( $item [ 'item_verified' ]))) ? t ( 'Message signature incorrect' ) : '' );
$unverified = '' ;
$body = prepare_body ( $item , true );
2022-10-24 08:35:13 +00:00
$has_tags = $body [ 'tags' ] || $body [ 'categories' ] || $body [ 'mentions' ] || $body [ 'attachments' ] || $body [ 'folders' ];
2021-12-03 03:01:39 +00:00
2024-03-10 02:40:50 +00:00
if ( strcmp ( Time :: convert ( 'UTC' , 'UTC' , $item [ 'created' ]), Time :: convert ( 'UTC' , 'UTC' , 'now - 12 hours' )) > 0 ) {
2021-12-03 03:01:39 +00:00
$is_new = true ;
}
$conv_link_mid = (( $mode == 'moderate' ) ? $item [ 'parent_mid' ] : $item [ 'mid' ]);
2022-07-20 11:26:28 +00:00
$conv_link = (( in_array ( $item [ 'item_type' ], [ ITEM_TYPE_CARD , ITEM_TYPE_ARTICLE ])) ? $item [ 'plink' ] : z_root () . '/display/?mid=' . gen_link_id ( $conv_link_mid ));
2021-12-03 03:01:39 +00:00
2022-10-24 08:35:13 +00:00
$allowed_type = in_array ( $item [ 'item_type' ], get_config ( 'system' , 'pin_types' , [ ITEM_TYPE_POST ]));
2021-12-03 03:01:39 +00:00
$pinned_items = ( $allowed_type ? get_pconfig ( $item [ 'uid' ], 'pinned' , $item [ 'item_type' ], []) : []);
2022-10-24 08:35:13 +00:00
$pinned = ! empty ( $pinned_items ) && in_array ( $item [ 'mid' ], $pinned_items );
2021-12-03 03:01:39 +00:00
2022-12-22 07:04:09 +00:00
$locicon = ( $item [ 'verb' ] === 'Arrive' ) ? '<i class="fa fa-fw fa-sign-in"></i> ' : '' ;
2022-11-21 21:44:58 +00:00
if ( ! $locicon ) {
$locicon = ( $item [ 'verb' ] === 'Leave' ) ? '<i class="fa fa-fw fa-sign-out"></i> ' : '' ;
}
2022-09-17 23:28:33 +00:00
$tmp_item = [
2021-12-03 03:01:39 +00:00
'template' => $tpl ,
'toplevel' => 'toplevel_item' ,
'item_type' => intval ( $item [ 'item_type' ]),
'mode' => $mode ,
'approve' => t ( 'Approve' ),
'delete' => t ( 'Delete' ),
'preview_lbl' => $preview_lbl ,
'id' => (( $preview ) ? 'P0' : $item [ 'item_id' ]),
2022-09-04 05:51:24 +00:00
'linktitle' => sprintf ( t ( 'View %s\'s profile @ %s' ), $profile_name , $profile_link ),
2021-12-03 03:01:39 +00:00
'profile_url' => $profile_link ,
'thread_action_menu' => thread_action_menu ( $item , $mode ),
'thread_author_menu' => thread_author_menu ( $item , $mode ),
'name' => $profile_name ,
'sparkle' => $sparkle ,
'lock' => $lock ,
2022-08-05 21:14:47 +00:00
'locktype' => $locktype ,
2021-12-03 03:01:39 +00:00
'thumb' => $profile_avatar ,
2022-12-02 19:42:40 +00:00
'large_avatar' => $large_avatar ,
2022-11-21 21:44:58 +00:00
'title' => $locicon . $item [ 'title' ],
2021-12-03 03:01:39 +00:00
'body' => $body [ 'html' ],
'event' => $body [ 'event' ],
'photo' => $body [ 'photo' ],
'tags' => $body [ 'tags' ],
'categories' => $body [ 'categories' ],
'mentions' => $body [ 'mentions' ],
'attachments' => $body [ 'attachments' ],
'folders' => $body [ 'folders' ],
'verified' => $verified ,
'unverified' => $unverified ,
'forged' => $forged ,
'repeated' => ( $item [ 'verb' ] === 'Announce' ),
'txt_cats' => t ( 'Categories:' ),
'txt_folders' => t ( 'Filed under:' ),
'has_cats' => (( $body [ 'categories' ]) ? 'true' : '' ),
'has_folders' => (( $body [ 'folders' ]) ? 'true' : '' ),
'text' => strip_tags ( $body [ 'html' ]),
'via' => t ( 'via' ),
'ago' => relative_date ( $item [ 'created' ]),
'app' => $item [ 'app' ],
'str_app' => sprintf ( t ( 'from %s' ), $item [ 'app' ]),
2024-03-10 02:40:50 +00:00
'isotime' => Time :: convert ( 'UTC' , date_default_timezone_get (), $item [ 'created' ], 'c' ),
'localtime' => Time :: convert ( 'UTC' , date_default_timezone_get (), $item [ 'created' ], 'r' ),
'editedtime' => (( $item [ 'edited' ] != $item [ 'created' ]) ? sprintf ( t ( 'last edited: %s' ), Time :: convert ( 'UTC' , date_default_timezone_get (), $item [ 'edited' ], 'r' )) : '' ),
'expiretime' => (( $item [ 'expires' ] > NULL_DATE ) ? sprintf ( t ( 'Expires: %s' ), Time :: convert ( 'UTC' , date_default_timezone_get (), $item [ 'expires' ], 'r' )) : '' ),
2021-12-03 03:01:39 +00:00
'location' => $location ,
'divider' => false ,
'indent' => '' ,
'owner_name' => $owner_name ,
'owner_url' => $owner_url ,
'owner_photo' => $owner_photo ,
'plink' => get_plink ( $item , false ),
'edpost' => false ,
2022-01-25 23:20:02 +00:00
'star' => (( Features :: enabled ( local_channel (), 'star_posts' )) ? $star : '' ),
2021-12-03 03:01:39 +00:00
'drop' => $drop ,
2022-10-24 08:35:13 +00:00
'vote' => false ,
2021-12-03 03:01:39 +00:00
'like' => '' ,
'dislike' => '' ,
'comment' => '' ,
'pinned' => ( $pinned ? t ( 'Pinned post' ) : '' ),
2023-06-04 20:57:12 +00:00
'pinnable' => ( in_array ( $item [ 'mid' ], ( intval ( $item [ 'uid' ]) === local_channel ()) ? PConfig :: Get ( intval ( $item [ 'uid' ]), 'pinned' , $item [ 'item_type' ], []) : [])),
2021-12-03 03:01:39 +00:00
'pinme' => ( $pinned ? t ( 'Unpin this post' ) : t ( 'Pin this post' )),
2022-09-17 23:28:33 +00:00
'conv' => (( $preview ) ? '' : [ 'href' => $conv_link , 'title' => t ( 'View Conversation' )]),
2021-12-03 03:01:39 +00:00
'previewing' => $previewing ,
'wait' => t ( 'Please wait' ),
'thread_level' => 1 ,
'has_tags' => $has_tags ,
'is_new' => $is_new
2022-09-17 23:28:33 +00:00
];
2021-12-03 03:01:39 +00:00
2022-09-17 23:28:33 +00:00
$arr = [ 'item' => $item , 'output' => $tmp_item ];
2022-02-12 08:50:48 +00:00
Hook :: call ( 'display_item' , $arr );
2021-12-03 03:01:39 +00:00
// $threads[$threadsid]['id'] = $item['item_id'];
$threads [] = $arr [ 'output' ];
}
} else {
// Normal View
// logger('conv: items: ' . print_r($items,true));
$conv = new ThreadStream ( $mode , $preview , $uploading , $prepared_item );
// In the display mode we don't have a profile owner.
if ( $mode === 'display' && $items ) {
$conv -> set_profile_owner ( $items [ 0 ][ 'uid' ]);
}
// get all the topmost parents
// this shouldn't be needed, as we should have only them in our array
// But for now, this array respects the old style, just in case
$threads = [];
foreach ( $items as $item ) {
$x = [ 'mode' => $mode , 'item' => $item ];
2022-02-12 08:50:48 +00:00
Hook :: call ( 'stream_item' , $x );
2021-12-03 03:01:39 +00:00
$item = $x [ 'item' ];
builtin_activity_puller ( $item , $conv_responses );
if ( ! visible_activity ( $item )) {
continue ;
}
$item [ 'pagedrop' ] = $page_dropping ;
if ( $item [ 'id' ] == $item [ 'parent' ]) {
$item_object = new ThreadItem ( $item );
$conv -> add_thread ( $item_object );
if (( $page_mode === 'list' ) || ( $page_mode === 'pager_list' )) {
$item_object -> set_template ( 'conv_list.tpl' );
$item_object -> set_display_mode ( 'list' );
}
if ( $mode === 'cards' || $mode === 'articles' ) {
$item_object -> set_reload ( $jsreload );
}
}
}
$threads = $conv -> get_template_data ( $conv_responses );
if ( ! $threads ) {
logger ( '[ERROR] conversation : Failed to get template data.' , LOGGER_DEBUG );
$threads = [];
}
//logger('threads: ' . print_r($threads,true), LOGGER_DATA);
}
}
2012-11-29 02:45:11 +00:00
2021-12-03 03:01:39 +00:00
if ( in_array ( $page_mode , [ 'traditional' , 'preview' , 'pager_list' ])) {
2022-02-12 20:43:29 +00:00
$page_template = Theme :: get_template ( " threaded_conversation.tpl " );
2021-12-03 03:01:39 +00:00
} elseif ( $update ) {
2022-02-12 20:43:29 +00:00
$page_template = Theme :: get_template ( " convobj.tpl " );
2021-12-03 03:01:39 +00:00
} else {
2022-02-12 20:43:29 +00:00
$page_template = Theme :: get_template ( " conv_frame.tpl " );
2021-12-03 03:01:39 +00:00
$threads = null ;
}
2012-11-29 02:45:11 +00:00
2022-09-17 23:28:33 +00:00
$o .= replace_macros ( $page_template , [
2021-12-03 03:01:39 +00:00
'$baseurl' => z_root (),
'$photo_item' => $content_html ,
'$live_update' => $live_update_div ,
'$remove' => t ( 'remove' ),
'$mode' => $mode ,
'$user' => App :: $user ,
'$threads' => $threads ,
'$wait' => t ( 'Loading...' ),
'$dropping' => ( $page_dropping ? t ( 'Delete Selected Items' ) : false ),
2022-09-17 23:28:33 +00:00
]);
2021-12-03 03:01:39 +00:00
return $o ;
2013-06-14 23:54:58 +00:00
}
2012-10-26 04:58:33 +00:00
2021-12-03 03:01:39 +00:00
function thread_action_menu ( $item , $mode = '' )
{
$menu = [];
if (( local_channel ()) && local_channel () == $item [ 'uid' ]) {
$menu [] = [
'menu' => 'view_source' ,
2023-10-09 06:11:45 +00:00
'title' => t ( 'View source' ),
2021-12-03 03:01:39 +00:00
'icon' => 'code' ,
'action' => 'viewsrc(' . $item [ 'id' ] . '); return false;' ,
'href' => '#'
];
if ( ! in_array ( $mode , [ 'stream-new' , 'search' , 'community' ])) {
if ( $item [ 'parent' ] == $item [ 'id' ] && ( get_observer_hash () != $item [ 'author_xchan' ])) {
$menu [] = [
'menu' => 'follow_thread' ,
2023-10-09 06:11:45 +00:00
'title' => t ( 'Follow thread' ),
2021-12-03 03:01:39 +00:00
'icon' => 'plus' ,
'action' => 'dosubthread(' . $item [ 'id' ] . '); return false;' ,
'href' => '#'
];
}
$menu [] = [
'menu' => 'unfollow_thread' ,
2023-10-09 06:11:45 +00:00
'title' => t ( 'Unfollow thread' ),
2021-12-03 03:01:39 +00:00
'icon' => 'minus' ,
'action' => 'dounsubthread(' . $item [ 'id' ] . '); return false;' ,
'href' => '#'
];
}
}
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
$args = [ 'item' => $item , 'mode' => $mode , 'menu' => $menu ];
2022-02-12 08:50:48 +00:00
Hook :: call ( 'thread_action_menu' , $args );
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
return $args [ 'menu' ];
2016-12-19 00:26:00 +00:00
}
2017-03-27 22:49:48 +00:00
2021-12-03 03:01:39 +00:00
function thread_author_menu ( $item , $mode = '' )
{
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
$menu = [];
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
$local_channel = local_channel ();
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
if ( $local_channel ) {
2023-01-26 20:09:37 +00:00
if ( empty ( App :: $contacts )) {
2021-12-03 03:01:39 +00:00
load_contact_links ( $local_channel );
}
$channel = App :: get_channel ();
}
2017-03-27 22:49:48 +00:00
2021-12-03 03:01:39 +00:00
$profile_link = chanlink_hash ( $item [ 'author_xchan' ]);
$contact = false ;
if ( $channel [ 'channel_hash' ] !== $item [ 'author_xchan' ]) {
if ( App :: $contacts && array_key_exists ( $item [ 'author_xchan' ], App :: $contacts )) {
$contact = App :: $contacts [ $item [ 'author_xchan' ]];
} else {
if ( $local_channel && ( ! in_array ( $item [ 'author' ][ 'xchan_network' ], [ 'rss' , 'anon' , 'token' , 'unknown' ]))) {
2023-01-16 07:12:31 +00:00
$follow_url = z_root () . '/follow/?f=&url=' . urlencode (( $item [ 'author' ][ 'xchan_addr' ]) ? : $item [ 'author' ][ 'xchan_url' ]) . '&interactive=0' ;
2021-12-03 03:01:39 +00:00
}
}
}
2021-07-26 00:20:10 +00:00
2021-12-03 03:01:39 +00:00
$poke_label = ucfirst ( t ( get_pconfig ( $local_channel , 'system' , 'pokeverb' , 'poke' )));
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
if ( $contact ) {
2023-01-26 07:29:09 +00:00
if ( their_perms_contains ( $local_channel , $contact [ 'xchan_hash' ], 'search_stream' )) {
$collections = XConfig :: Get ( $contact [ 'xchan_hash' ], 'activitypub' , 'collections' );
if ( $collections && $collections [ 'searchContent' ]) {
2023-01-27 09:05:24 +00:00
$search_url = zid ( $collections [ 'searchContent' ]);
2023-01-26 07:29:09 +00:00
}
}
2021-12-03 03:01:39 +00:00
if ( ! ( isset ( $contact [ 'abook_self' ]) && intval ( $contact [ 'abook_self' ]))) {
$contact_url = z_root () . '/connedit/' . $contact [ 'abook_id' ];
}
$posts_link = z_root () . '/stream/?cid=' . $contact [ 'abook_id' ];
$clean_url = $item [ 'author' ][ 'xchan_url' ];
}
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
$can_dm = false ;
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
if ( $local_channel && $contact ) {
2021-12-15 08:32:39 +00:00
$can_dm = perm_is_allowed ( $local_channel , $item [ 'author_xchan' ], 'post_mail' ) && intval ( $contact [ 'xchan_type' ]) !== XCHAN_TYPE_GROUP ;
2021-12-03 03:01:39 +00:00
} elseif ( $item [ 'author' ][ 'xchan_network' ] === 'activitypub' ) {
$can_dm = true ;
}
2021-12-15 08:32:39 +00:00
if ( $can_dm ) {
$pm_url = z_root ()
2022-08-05 21:14:47 +00:00
. '/rpost?to='
. urlencode ( $item [ 'author_xchan' ]);
}
2021-12-03 03:01:39 +00:00
2023-01-27 09:05:24 +00:00
if ( isset ( $search_url ) && $search_url ) {
$menu [] = [
'menu' => 'search_posts' ,
'title' => t ( 'Remote Search' ),
'icon' => 'fw' ,
'action' => '' ,
'href' => $search_url ,
'input' => true ,
'id' => new_uuid (),
];
}
2021-12-03 03:01:39 +00:00
if ( $profile_link ) {
$menu [] = [
'menu' => 'view_profile' ,
'title' => t ( 'Visit' ),
'icon' => 'fw' ,
'action' => '' ,
2023-11-21 19:42:11 +00:00
'href' => $profile_link ,
2021-12-03 03:01:39 +00:00
];
}
2016-12-19 00:26:00 +00:00
2023-01-16 07:12:31 +00:00
if ( $local_channel && ( $item [ 'lat' ] || $item [ 'lon' ])) {
2022-11-10 08:56:42 +00:00
$menu [] = [
'menu' => 'distance_search' ,
'title' => t ( 'Nearby' ),
'icon' => 'fw' ,
'action' => '' ,
2023-11-21 19:42:11 +00:00
'href' => 'stream?distance=1&distance_from=' . $item [ 'lat' ] . ',' . $item [ 'lon' ],
2022-11-10 08:56:42 +00:00
];
}
2021-12-03 03:01:39 +00:00
if ( isset ( $posts_link ) && $posts_link ) {
$menu [] = [
'menu' => 'view_posts' ,
'title' => t ( 'Recent Activity' ),
'icon' => 'fw' ,
'action' => '' ,
'href' => $posts_link
];
}
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
if ( isset ( $follow_url ) && $follow_url ) {
$menu [] = [
'menu' => 'follow' ,
'title' => t ( 'Connect' ),
'icon' => 'fw' ,
'action' => 'doFollowAuthor(\'' . $follow_url . '\'); return false;' ,
'href' => '#' ,
];
}
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
if ( isset ( $contact_url ) && $contact_url ) {
$menu [] = [
'menu' => 'connedit' ,
'title' => t ( 'Edit Connection' ),
'icon' => 'fw' ,
'action' => '' ,
2023-11-21 19:42:11 +00:00
'href' => $contact_url ,
2021-12-03 03:01:39 +00:00
];
}
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
if ( isset ( $pm_url ) && $pm_url ) {
$menu [] = [
'menu' => 'prv_message' ,
'title' => t ( 'Direct Message' ),
'icon' => 'fw' ,
'action' => '' ,
2023-11-21 19:42:11 +00:00
'href' => $pm_url ,
2021-12-03 03:01:39 +00:00
];
}
2021-07-26 00:20:10 +00:00
2021-12-03 03:01:39 +00:00
if ( Apps :: system_app_installed ( $local_channel , 'Poke' )) {
$menu [] = [
'menu' => 'poke' ,
'title' => $poke_label ,
'icon' => 'fw' ,
'action' => 'doPoke(\'' . urlencode ( $item [ 'author_xchan' ]) . '\'); return false;' ,
'href' => '#'
];
}
2020-03-20 04:08:50 +00:00
2023-01-22 20:13:39 +00:00
if ( $local_channel && $item [ 'author_xchan' ] !== $channel [ 'channel_hash' ]) {
2021-12-03 03:01:39 +00:00
$menu [] = [
'menu' => 'superblocksite' ,
'title' => t ( 'Block author\'s site' ),
'icon' => 'fw' ,
'action' => 'blocksite(\'' . urlencode ( $item [ 'author_xchan' ]) . '\',' . $item [ 'id' ] . '); return false;' ,
'href' => '#'
];
$menu [] = [
'menu' => 'superblock' ,
'title' => t ( 'Block author' ),
'icon' => 'fw' ,
'action' => 'superblock(\'' . urlencode ( $item [ 'author_xchan' ]) . '\',' . $item [ 'id' ] . '); return false;' ,
'href' => '#'
];
}
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
$args = [ 'item' => $item , 'mode' => $mode , 'menu' => $menu ];
2022-02-12 08:50:48 +00:00
Hook :: call ( 'thread_author_menu' , $args );
2016-12-19 00:26:00 +00:00
2021-12-03 03:01:39 +00:00
return $args [ 'menu' ];
2016-12-19 00:26:00 +00:00
}
2014-09-21 15:51:01 +00:00
/**
2015-02-10 22:47:09 +00:00
* @ brief Checks item to see if it is one of the builtin activities ( like / dislike , event attendance , consensus items , etc . )
2015-03-21 21:03:59 +00:00
*
2015-02-10 22:47:09 +00:00
* Increments the count of each matching activity and adds a link to the author as needed .
2014-09-21 15:51:01 +00:00
*
* @ param array $item
2015-02-10 22:47:09 +00:00
* @ param array & $conv_responses ( already created with builtin activity structure )
2014-09-21 15:51:01 +00:00
*/
2021-12-03 03:01:39 +00:00
function builtin_activity_puller ( $item , & $conv_responses )
{
// if this item is a post or comment there's nothing for us to do here, just return.
if ( in_array ( $item [ 'verb' ], [ 'Create' ])) {
return ;
}
foreach ( $conv_responses as $mode => $v ) {
$url = '' ;
2024-05-10 20:57:56 +00:00
if ( ! $item [ 'author' ][ 'xchan_name' ]) {
2024-05-10 21:42:03 +00:00
logger ( 'Unidentified author for item: ' . $item [ 'id' ]);
logger ( 'Unidentified item: ' . print_r ( $item , true ), LOGGER_DATA );
2024-05-10 20:57:56 +00:00
continue ;
}
2021-12-03 03:01:39 +00:00
switch ( $mode ) {
case 'like' :
$verb = ACTIVITY_LIKE ;
break ;
case 'dislike' :
$verb = ACTIVITY_DISLIKE ;
break ;
2024-03-22 07:27:28 +00:00
case 'repeat' :
$verb = 'Announce' ;
break ;
2021-12-03 03:01:39 +00:00
case 'attendyes' :
$verb = 'Accept' ;
break ;
case 'attendno' :
$verb = 'Reject' ;
break ;
case 'attendmaybe' :
$verb = 'TentativeAccept' ;
break ;
default :
return ;
}
if (( activity_match ( $item [ 'verb' ], $verb )) && ( $item [ 'id' ] != $item [ 'parent' ])) {
2024-05-10 21:42:03 +00:00
$name = $item [ 'author' ][ 'xchan_name' ] ? : t ( 'Unknown' );
2021-12-03 03:01:39 +00:00
$url = (( $item [ 'author_xchan' ] && $item [ 'author' ][ 'xchan_photo_s' ])
2024-05-14 23:24:44 +00:00
? '<a class="dropdown-item" href="' . chanlink_hash ( $item [ 'author_xchan' ]) . '">' . '<img class="menu-img-1" src="' . zid ( $item [ 'author' ][ 'xchan_photo_s' ]) . '" alt="' . urlencode ( $name ) . '" /> ' . $name . ' (' . relative_date ( $item [ 'created' ]) . ')</a>'
: '<a class="dropdown-item" href="#" class="disabled">' . $name . ' (' . relative_date ( $item [ 'created' ]) . ')</a>'
2021-12-03 03:01:39 +00:00
);
if ( ! $item [ 'thr_parent' ]) {
$item [ 'thr_parent' ] = $item [ 'parent_mid' ];
}
if (
! (( isset ( $conv_responses [ $mode ][ $item [ 'thr_parent' ] . '-l' ]))
&& ( is_array ( $conv_responses [ $mode ][ $item [ 'thr_parent' ] . '-l' ])))
) {
$conv_responses [ $mode ][ $item [ 'thr_parent' ] . '-l' ] = [];
}
// only list each unique author once
if ( in_array ( $url , $conv_responses [ $mode ][ $item [ 'thr_parent' ] . '-l' ])) {
continue ;
}
if ( ! isset ( $conv_responses [ $mode ][ $item [ 'thr_parent' ]])) {
$conv_responses [ $mode ][ $item [ 'thr_parent' ]] = 1 ;
} else {
$conv_responses [ $mode ][ $item [ 'thr_parent' ]] ++ ;
}
$conv_responses [ $mode ][ $item [ 'thr_parent' ] . '-l' ][] = $url ;
if ( get_observer_hash () && get_observer_hash () === $item [ 'author_xchan' ]) {
$conv_responses [ $mode ][ $item [ 'thr_parent' ] . '-m' ] = true ;
2024-04-19 22:27:57 +00:00
$conv_responses [ $mode ][ $item [ 'thr_parent' ] . '-mitem' ] = $item [ 'id' ];
2021-12-03 03:01:39 +00:00
}
// there can only be one activity verb per item so if we found anything, we can stop looking
return ;
}
}
2013-06-19 01:48:41 +00:00
}
2011-04-13 00:58:16 +00:00
2018-10-09 04:27:35 +00:00
/**
* Wrapper to allow addons to replace the status editor if desired .
*/
2021-12-03 03:01:39 +00:00
function status_editor ( $x , $popup = false , $module = '' )
{
2018-10-09 04:27:35 +00:00
$hook_info = [ 'editor_html' => '' , 'x' => $x , 'popup' => $popup , 'module' => $module ];
2022-02-12 08:50:48 +00:00
Hook :: call ( 'status_editor' , $hook_info );
2018-10-09 04:27:35 +00:00
if ( $hook_info [ 'editor_html' ] == '' ) {
2021-12-03 03:01:39 +00:00
return z_status_editor ( $x , $popup );
} else {
return $hook_info [ 'editor_html' ];
2018-10-09 04:27:35 +00:00
}
}
2015-11-13 01:47:38 +00:00
/**
2021-12-03 03:01:39 +00:00
* This is our general purpose content editor .
2015-11-13 01:47:38 +00:00
* It was once nicknamed " jot " and you may see references to " jot " littered throughout the code .
2021-12-03 03:01:39 +00:00
* They are referring to the content editor or components thereof .
2015-11-13 01:47:38 +00:00
*/
2021-12-03 03:01:39 +00:00
function z_status_editor ( $x , $popup = false )
{
$o = '' ;
2011-04-20 12:48:12 +00:00
2022-01-25 01:26:12 +00:00
$c = Channel :: from_id ( $x [ 'profile_uid' ]);
2021-12-03 03:01:39 +00:00
if ( $c && $c [ 'channel_moved' ]) {
return $o ;
}
2011-04-20 12:48:12 +00:00
2021-12-03 03:01:39 +00:00
$plaintext = true ;
$webpage = false ;
$feature_voting = false ;
2012-09-11 05:00:56 +00:00
2021-12-03 03:01:39 +00:00
$feature_comment_control = Apps :: system_app_installed ( $x [ 'profile_uid' ], 'Comment Control' );
if ( x ( $x , 'disable_comment_control' )) {
$feature_comment_control = false ;
}
2016-03-09 08:46:17 +00:00
2020-02-27 04:48:28 +00:00
2021-12-03 03:01:39 +00:00
$feature_expire = (( Apps :: system_app_installed ( $x [ 'profile_uid' ], 'Expire Posts' ) && ( ! $webpage )) ? true : false );
if ( x ( $x , 'hide_expire' )) {
$feature_expire = false ;
}
2020-11-24 03:14:44 +00:00
2021-12-03 03:01:39 +00:00
$feature_future = (( Apps :: system_app_installed ( $x [ 'profile_uid' ], 'Future Posting' ) && ( ! $webpage )) ? true : false );
if ( x ( $x , 'hide_future' )) {
$feature_future = false ;
}
2020-11-24 03:14:44 +00:00
2021-12-03 03:01:39 +00:00
$feature_markup = (( Apps :: system_app_installed ( $x [ 'profile_uid' ], 'Markup' ) && ( ! $webpage )) ? true : false );
if ( x ( $x , 'hide_markup' )) {
$feature_markup = false ;
}
2016-04-29 11:18:42 +00:00
2022-11-15 20:58:15 +00:00
$body = (( x ( $x , 'body' )) ? htmlspecialchars ( $x [ 'body' ], ENT_COMPAT , 'UTF-8' ) : '' );
2022-11-10 08:56:42 +00:00
$feature_checkin = true ;
2022-11-15 20:16:26 +00:00
$checkin_checked = isset ( $x [ 'checkin' ]) ? intval ( $x [ 'checkin' ]) : 0 ;
2022-11-21 19:15:54 +00:00
$feature_checkout = true ;
$checkout_checked = isset ( $x [ 'checkout' ]) ? intval ( $x [ 'checkout' ]) : 0 ;
if ( $checkin_checked || $checkout_checked ) {
2022-11-15 20:58:15 +00:00
$body = preg_replace ( '/\[map=(.*?)\]/' , '' , $body );
$body = preg_replace ( '/\[map\](.*?)\[\/map\]/' , '' , $body );
}
2022-09-16 10:57:04 +00:00
$lat = '' ;
$lon = '' ;
2022-02-12 20:43:29 +00:00
$geotag = (( $x [ 'allow_location' ]) ? replace_macros ( Theme :: get_template ( 'jot_geotag.tpl' ), []) : '' );
2021-12-03 03:01:39 +00:00
$setloc = t ( 'Set your location' );
2022-09-16 10:57:04 +00:00
$clearloc = t ( 'Clear your location' );
$set_location = get_pconfig ( $x [ 'profile_uid' ], 'system' , 'set_location' );
if ( $set_location ) {
$tmp = explode ( ',' , $set_location );
if ( count ( $tmp ) > 1 ) {
$lat = floatval ( trim ( $tmp [ 0 ]));
$lon = floatval ( trim ( $tmp [ 1 ]));
}
}
2021-12-03 03:01:39 +00:00
if ( x ( $x , 'hide_location' )) {
2022-09-16 10:57:04 +00:00
$geotag = $setloc = $clearloc = $lat = $lon = '' ;
2021-12-03 03:01:39 +00:00
}
2020-09-24 00:59:09 +00:00
2021-12-03 03:01:39 +00:00
$summaryenabled = (( array_key_exists ( 'allow_summary' , $x )) ? intval ( $x [ 'allow_summary' ]) : false );
2020-09-24 00:59:09 +00:00
2021-12-06 00:49:55 +00:00
$mimetype = (( x ( $x , 'mimetype' )) ? $x [ 'mimetype' ] : 'text/x-multicode' );
2015-02-11 03:10:18 +00:00
2021-12-03 03:01:39 +00:00
$mimeselect = (( x ( $x , 'mimeselect' )) ? $x [ 'mimeselect' ] : false );
if ( $mimeselect ) {
$mimeselect = mimetype_select ( $x [ 'profile_uid' ], $mimetype );
} else {
$mimeselect = '<input type="hidden" name="mimetype" value="' . $mimetype . '" />' ;
}
2018-08-16 01:56:18 +00:00
2021-12-06 00:49:55 +00:00
$weblink = (( $mimetype === 'text/x-multicode' ) ? t ( 'Insert web link' ) : false );
2021-12-03 03:01:39 +00:00
if ( x ( $x , 'hide_weblink' )) {
$weblink = false ;
}
2016-05-07 21:05:48 +00:00
2023-04-06 22:21:54 +00:00
$embedPhotos = t ( 'Attach file from your personal cloud' );
2023-04-06 22:29:16 +00:00
$embedFiles = t ( 'Attach/Embed file' );
2023-02-17 18:55:58 +00:00
$insertFile = t ( 'Insert File' );
2023-03-15 10:28:13 +00:00
$fromDevice = t ( 'from device' );
$fromCloud = t ( 'from personal cloud' );
2023-02-17 18:55:58 +00:00
2021-12-06 00:49:55 +00:00
$writefiles = (( $mimetype === 'text/x-multicode' ) ? perm_is_allowed ( $x [ 'profile_uid' ], get_observer_hash (), 'write_storage' ) : false );
2021-12-03 03:01:39 +00:00
if ( x ( $x , 'hide_attach' )) {
$writefiles = false ;
}
if ( perm_is_allowed ( $x [ 'profile_uid' ], get_observer_hash (), 'moderated' )) {
$writefiles = false ;
}
2016-05-01 13:45:42 +00:00
2021-12-03 03:01:39 +00:00
$layout = (( x ( $x , 'layout' )) ? $x [ 'layout' ] : '' );
2016-05-01 13:45:42 +00:00
2021-12-03 03:01:39 +00:00
$layoutselect = (( x ( $x , 'layoutselect' )) ? $x [ 'layoutselect' ] : false );
if ( $layoutselect ) {
$layoutselect = layout_select ( $x [ 'profile_uid' ], $layout );
} else {
$layoutselect = '<input type="hidden" name="layout_mid" value="' . $layout . '" />' ;
}
2016-05-09 09:56:42 +00:00
2021-12-03 03:01:39 +00:00
if ( array_key_exists ( 'channel_select' , $x ) && $x [ 'channel_select' ]) {
2022-01-25 01:26:12 +00:00
$id_select = Channel :: identity_selector ();
2021-12-03 03:01:39 +00:00
} else {
$id_select = '' ;
}
2016-05-09 09:56:42 +00:00
2021-12-03 03:01:39 +00:00
$webpage = (( x ( $x , 'webpage' )) ? $x [ 'webpage' ] : '' );
2014-04-05 09:32:07 +00:00
2021-12-03 03:01:39 +00:00
$reset = (( x ( $x , 'reset' )) ? $x [ 'reset' ] : '' );
2018-05-20 07:23:44 +00:00
2022-01-25 23:20:02 +00:00
$feature_auto_save_draft = (( Features :: enabled ( $x [ 'profile_uid' ], 'auto_save_draft' )) ? " true " : " false " );
2015-03-10 20:42:26 +00:00
2022-02-12 20:43:29 +00:00
$tpl = Theme :: get_template ( 'jot-header.tpl' );
2021-03-11 03:30:25 +00:00
2021-12-03 03:01:39 +00:00
if ( ! isset ( App :: $page [ 'htmlhead' ])) {
App :: $page [ 'htmlhead' ] = EMPTY_STR ;
}
2019-05-29 23:29:55 +00:00
2022-09-17 23:28:33 +00:00
App :: $page [ 'htmlhead' ] .= replace_macros ( $tpl , [
2021-12-03 03:01:39 +00:00
'$baseurl' => z_root (),
'$webpage' => $webpage ,
'$editselect' => (( $plaintext ) ? 'none' : '/(profile-jot-text|prvmail-text)/' ),
'$pretext' => (( x ( $x , 'pretext' )) ? $x [ 'pretext' ] : '' ),
'$geotag' => $geotag ,
'$nickname' => $x [ 'nickname' ],
'$linkurl' => t ( 'Please enter a link URL:' ),
'$term' => t ( 'Tag term:' ),
2022-09-16 10:57:04 +00:00
'$whereareu' => t ( 'Where are you right now?' ) . ' ' . t ( '(Enter a dot . to use your current device coordinates.)' ),
2021-12-03 03:01:39 +00:00
'$editor_autocomplete' => (( x ( $x , 'editor_autocomplete' )) ? $x [ 'editor_autocomplete' ] : '' ),
'$bbco_autocomplete' => (( x ( $x , 'bbco_autocomplete' )) ? $x [ 'bbco_autocomplete' ] : '' ),
2023-04-04 10:24:17 +00:00
'$modalchooseimages' => t ( 'Choose files to embed' ),
'$modalchoosealbum' => t ( 'Choose a folder' ),
'$modaldiffalbum' => t ( 'Choose a different folder...' ),
'$modalerrorlist' => t ( 'Error getting folder list' ),
'$modalerrorlink' => t ( 'Error getting file link' ),
'$modalerroralbum' => t ( 'Error getting folder' ),
2021-12-03 03:01:39 +00:00
'$auto_save_draft' => $feature_auto_save_draft ,
'$confirmdelete' => t ( 'Delete this item?' ),
'$reset' => $reset
2022-09-17 23:28:33 +00:00
]);
2021-12-03 03:01:39 +00:00
2022-02-12 20:43:29 +00:00
$tpl = Theme :: get_template ( 'jot.tpl' );
2021-12-03 03:01:39 +00:00
$preview = t ( 'Preview' );
if ( x ( $x , 'hide_preview' )) {
$preview = '' ;
}
2015-02-06 03:09:42 +00:00
2021-12-03 03:01:39 +00:00
$defexpire = ((( $z = get_pconfig ( $x [ 'profile_uid' ], 'system' , 'default_post_expire' )) && ( ! $webpage )) ? $z : '' );
if ( $defexpire ) {
2024-03-10 02:40:50 +00:00
$defexpire = Time :: convert ( 'UTC' , date_default_timezone_get (), $defexpire , 'Y-m-d H:i' );
2021-12-03 03:01:39 +00:00
} else {
$defexpire = ((( $z = intval ( get_pconfig ( $x [ 'profile_uid' ], 'system' , 'selfexpiredays' ))) && ( ! $webpage )) ? $z : '' );
if ( $defexpire ) {
2024-03-10 02:40:50 +00:00
$defexpire = Time :: convert ( 'UTC' , date_default_timezone_get (), " now + $defexpire days " , 'Y-m-d H:i' );
2021-12-03 03:01:39 +00:00
}
}
2021-04-14 04:07:24 +00:00
2020-11-24 03:14:44 +00:00
2021-12-03 03:01:39 +00:00
$defclosecomm = ((( $z = get_pconfig ( $x [ 'profile_uid' ], 'system' , 'close_comments' , 0 )) && ( ! $webpage )) ? intval ( $z ) : '' );
if ( $defclosecomm ) {
$closecommdays = intval ( $defclosecomm );
} else {
$closecommdays = EMPTY_STR ;
}
2016-09-09 05:20:45 +00:00
2024-03-10 02:40:50 +00:00
$defcommuntil = (( $closecommdays ) ? Time :: convert ( 'UTC' , date_default_timezone_get (), 'now + ' . $closecommdays . ' days' ) : EMPTY_STR );
2012-02-07 04:28:50 +00:00
2021-12-03 03:01:39 +00:00
$defpublish = ((( $z = get_pconfig ( $x [ 'profile_uid' ], 'system' , 'default_post_publish' )) && ( ! $webpage )) ? $z : '' );
if ( $defpublish ) {
2024-03-10 02:40:50 +00:00
$defpublish = Time :: convert ( 'UTC' , date_default_timezone_get (), $defpublish , 'Y-m-d H:i' );
2021-12-03 03:01:39 +00:00
}
2019-04-04 05:18:13 +00:00
2021-12-03 03:01:39 +00:00
$cipher = get_pconfig ( $x [ 'profile_uid' ], 'system' , 'default_cipher' );
if ( ! $cipher ) {
$cipher = 'AES-128-CCM' ;
}
2016-08-21 13:43:03 +00:00
2021-12-03 03:01:39 +00:00
if ( array_key_exists ( 'catsenabled' , $x )) {
$catsenabled = $x [ 'catsenabled' ];
} else {
$catsenabled = (( Apps :: system_app_installed ( $x [ 'profile_uid' ], 'Categories' ) && ( ! $webpage )) ? 'categories' : '' );
}
2012-02-10 16:30:22 +00:00
2012-01-03 00:54:37 +00:00
2021-12-03 03:01:39 +00:00
// we only need the comment_perms for the editor, but this logic is complicated enough (from Settings/Channel)
// that we will just duplicate most of that code block
$global_perms = Permissions :: Perms ();
$permiss = [];
$perm_opts = [
[ t ( 'Restricted - from connections only' ), PERMS_SPECIFIC ],
[ t ( 'Semi-public - from anybody that can be identified' ), PERMS_AUTHED ],
[ t ( 'Public - from anybody on the internet' ), PERMS_PUBLIC ]
];
$limits = PermissionLimits :: Get ( local_channel ());
$anon_comments = get_config ( 'system' , 'anonymous_comments' );
foreach ( $global_perms as $k => $perm ) {
$options = [];
$can_be_public = (( strstr ( $k , 'view' ) || ( $k === 'post_comments' && $anon_comments )) ? true : false );
foreach ( $perm_opts as $opt ) {
if ( $opt [ 1 ] == PERMS_PUBLIC && ( ! $can_be_public )) {
continue ;
}
$options [ $opt [ 1 ]] = $opt [ 0 ];
}
if ( $k === 'post_comments' ) {
2022-11-11 21:23:18 +00:00
$comment_perms = [ $k , t ( 'Accept delivery of comments on this post from' ), $limits [ $k ], '' , $options ];
2021-12-03 03:01:39 +00:00
} else {
2022-09-17 23:28:33 +00:00
$permiss [] = [ $k , $perm , $limits [ $k ], '' , $options ];
2021-12-03 03:01:39 +00:00
}
}
2012-01-03 00:54:37 +00:00
2021-12-03 03:01:39 +00:00
$defcommpolicy = $limits [ 'post_comments' ];
2019-04-03 23:22:03 +00:00
2021-12-03 03:01:39 +00:00
// avoid illegal offset errors
if ( ! array_key_exists ( 'permissions' , $x )) {
$x [ 'permissions' ] = [ 'allow_cid' => '' , 'allow_gid' => '' , 'deny_cid' => '' , 'deny_gid' => '' ];
}
2019-04-03 23:22:03 +00:00
2021-12-03 03:01:39 +00:00
$jotplugins = '' ;
2022-02-12 08:50:48 +00:00
Hook :: call ( 'jot_tool' , $jotplugins );
2019-04-03 23:22:03 +00:00
2021-12-03 03:01:39 +00:00
$jotcoll = jot_collections ( $c , (( array_key_exists ( 'collections' , $x )) ? $x [ 'collections' ] : []));
if ( ! $jotcoll ) {
$jotcoll = EMPTY_STR ;
}
2019-04-05 02:14:32 +00:00
2021-12-03 03:01:39 +00:00
$jotnets = EMPTY_STR ;
if ( x ( $x , 'jotnets' )) {
2022-02-12 08:50:48 +00:00
Hook :: call ( 'jot_networks' , $jotnets );
2021-12-03 03:01:39 +00:00
}
2019-04-03 23:22:03 +00:00
2023-10-07 22:39:59 +00:00
$permanent_draft = (( intval ( $x [ 'profile_uid' ]) && intval ( $x [ 'profile_uid' ]) === local_channel () && Apps :: system_app_installed ( $x [ 'profile_uid' ], 'Drafts' )) ? t ( 'Save draft' ) : EMPTY_STR );
2021-12-03 03:01:39 +00:00
$sharebutton = ( x ( $x , 'button' ) ? $x [ 'button' ] : t ( 'Share' ));
$placeholdtext = ( x ( $x , 'content_label' ) ? $x [ 'content_label' ] : $sharebutton );
2022-11-21 21:44:58 +00:00
2022-09-17 23:28:33 +00:00
$o .= replace_macros ( $tpl , [
2021-12-03 03:01:39 +00:00
'$return_path' => (( x ( $x , 'return_path' )) ? $x [ 'return_path' ] : App :: $query_string ),
'$action' => z_root () . '/item' ,
'$share' => $sharebutton ,
'$placeholdtext' => $placeholdtext ,
'$webpage' => $webpage ,
'$placeholdpagetitle' => (( x ( $x , 'ptlabel' )) ? $x [ 'ptlabel' ] : t ( 'Page link name' )),
'$pagetitle' => ( x ( $x , 'pagetitle' ) ? $x [ 'pagetitle' ] : '' ),
'$id_select' => $id_select ,
'$id_seltext' => t ( 'Post as' ),
'$writefiles' => $writefiles ,
'$text_style' => t ( 'Text styles' ),
'$bold' => t ( 'Bold' ),
'$italic' => t ( 'Italic' ),
'$underline' => t ( 'Underline' ),
'$quote' => t ( 'Quote' ),
'$code' => t ( 'Code' ),
2023-04-06 22:21:54 +00:00
'$attach' => t ( 'Attach file from your device' ),
2021-12-03 03:01:39 +00:00
'$weblink' => $weblink ,
'$linkurl' => t ( 'Please enter a link location (URL)' ),
2022-07-06 02:13:38 +00:00
'$hidden_mentions' => (( x ( $x , 'hidden_mentions' )) ? $x [ 'hidden_mentions' ] : '' ),
2021-12-03 03:01:39 +00:00
'$weblink_style' => [ t ( 'Insert link only' ), t ( 'Embed content if possible' ) ],
2023-02-17 18:43:27 +00:00
'$embedFiles' => $embedFiles ,
2023-02-17 18:55:58 +00:00
'$insertFile' => $insertFile ,
'$fromDevice' => $fromDevice ,
'$fromCloud' => $fromCloud ,
2023-02-26 18:24:12 +00:00
'$embedFileDirModalTitle' => t ( 'Embed a file from the cloud' ),
2021-12-03 03:01:39 +00:00
'$embedPhotos' => $embedPhotos ,
'$embedPhotosModalTitle' => t ( 'Embed an image from your albums' ),
'$embedPhotosModalCancel' => t ( 'Cancel' ),
'$embedPhotosModalOK' => t ( 'OK' ),
'$setloc' => $setloc ,
2023-06-04 05:28:35 +00:00
'$locdesc' => t ( 'Location options' ),
2021-12-03 03:01:39 +00:00
'$poll' => t ( 'Toggle poll' ),
'$poll_option_label' => t ( 'Option' ),
'$poll_add_option_label' => t ( 'Add option' ),
'$poll_expire_unit_label' => [ t ( 'Minutes' ), t ( 'Hours' ), t ( 'Days' )],
'$multiple_answers' => [ 'poll_multiple_answers' , t ( " Allow multiple answers " ), '' , '' , [ t ( 'No' ), t ( 'Yes' )]],
'$feature_voting' => $feature_voting ,
'$consensus' => (( array_key_exists ( 'item' , $x )) ? $x [ 'item' ][ 'item_consensus' ] : 0 ),
'$nocommenttitle' => t ( 'Disable comments' ),
'$nocommenttitlesub' => t ( 'Toggle comments' ),
'$comments_allowed' => [ 'comments_allowed' , t ( 'Allow comments on this post' ), (( array_key_exists ( 'item' , $x )) ? 1 - $x [ 'item' ][ 'item_nocomment' ] : 1 ), '' , [ t ( 'No' ), t ( 'Yes' )]],
'$commentstate' => (( array_key_exists ( 'item' , $x )) ? 1 - $x [ 'item' ][ 'item_nocomment' ] : 1 ),
'$feature_comment_control' => $feature_comment_control ,
'$commctrl' => t ( 'Comment Control' ),
'$comments_closed' => (( isset ( $x [ 'item' ]) && isset ( $x [ 'item' ][ 'comments_closed' ]) && $x [ 'item' ][ 'comments_closed' ]) ? $x [ 'item' ][ 'comments_closed' ] : '' ),
'$commclosedate' => t ( 'Optional: disable comments after (date)' ),
'$comment_perms' => $comment_perms ,
'$defcommpolicy' => $defcommpolicy ,
'$defcommuntil' => $defcommuntil ,
'$clearloc' => $clearloc ,
2022-09-16 10:57:04 +00:00
'$lat' => $lat ,
'$lon' => $lon ,
2021-12-03 03:01:39 +00:00
'$title' => (( x ( $x , 'title' )) ? htmlspecialchars ( $x [ 'title' ], ENT_COMPAT , 'UTF-8' ) : '' ),
'$placeholdertitle' => (( x ( $x , 'placeholdertitle' )) ? $x [ 'placeholdertitle' ] : t ( 'Title (optional)' )),
'$catsenabled' => $catsenabled ,
'$category' => (( x ( $x , 'category' )) ? $x [ 'category' ] : '' ),
'$placeholdercategory' => t ( 'Categories (optional, comma-separated list)' ),
'$permset' => t ( 'Permission settings' ),
'$ptyp' => (( x ( $x , 'ptyp' )) ? $x [ 'ptyp' ] : '' ),
2022-11-15 20:58:15 +00:00
'$content' => $body ,
2021-12-03 03:01:39 +00:00
'$attachment' => (( x ( $x , 'attachment' )) ? $x [ 'attachment' ] : '' ),
'$post_id' => (( x ( $x , 'post_id' )) ? $x [ 'post_id' ] : '' ),
'$defloc' => $x [ 'default_location' ],
'$visitor' => $x [ 'visitor' ],
'$lockstate' => $x [ 'lockstate' ],
'$acl' => $x [ 'acl' ],
'$allow_cid' => acl2json ( $x [ 'permissions' ][ 'allow_cid' ]),
'$allow_gid' => acl2json ( $x [ 'permissions' ][ 'allow_gid' ]),
'$deny_cid' => acl2json ( $x [ 'permissions' ][ 'deny_cid' ]),
'$deny_gid' => acl2json ( $x [ 'permissions' ][ 'deny_gid' ]),
'$mimeselect' => $mimeselect ,
'$layoutselect' => $layoutselect ,
'$showacl' => (( array_key_exists ( 'showacl' , $x )) ? $x [ 'showacl' ] : true ),
'$bang' => $x [ 'bang' ],
'$profile_uid' => $x [ 'profile_uid' ],
'$preview' => $preview ,
'$source' => (( x ( $x , 'source' )) ? $x [ 'source' ] : '' ),
'$jotplugins' => $jotplugins ,
'$jotcoll' => $jotcoll ,
'$jotnets' => $jotnets ,
'$jotnets_label' => t ( 'Other networks and post services' ),
'$jotcoll_label' => t ( 'Collections' ),
'$defexpire' => $defexpire ,
'$feature_expire' => $feature_expire ,
2022-11-09 11:42:23 +00:00
'$feature_checkin' => $feature_checkin ,
2022-11-21 19:15:54 +00:00
'$feature_checkout' => $feature_checkout ,
2022-11-09 11:42:23 +00:00
'$checkin' => t ( 'Check In' ),
2022-11-21 19:15:54 +00:00
'$checkout' => t ( 'Check Out' ),
2021-12-03 03:01:39 +00:00
'$expires' => t ( 'Set expiration date' ),
'$save' => $permanent_draft ,
2022-12-22 07:51:22 +00:00
'$is_draft' => array_key_exists ( 'is_draft' , $x ) && intval ( $x [ 'is_draft' ]),
2021-12-03 03:01:39 +00:00
'$defpublish' => $defpublish ,
'$feature_future' => $feature_future ,
'$future_txt' => t ( 'Set publish date' ),
'$feature_markup' => $feature_markup ,
2022-12-22 07:51:22 +00:00
'$feature_encrypt' => Apps :: system_app_installed ( $x [ 'profile_uid' ], 'Secrets' ),
2021-12-03 03:01:39 +00:00
'$encrypt' => t ( 'Encrypt text' ),
'$cipher' => $cipher ,
'$expiryModalOK' => t ( 'OK' ),
'$expiryModalCANCEL' => t ( 'Cancel' ),
'$commModalOK' => t ( 'OK' ),
'$commModalCANCEL' => t ( 'Cancel' ),
'$linkModalOK' => t ( 'OK' ),
'$linkModalCANCEL' => t ( 'Cancel' ),
'$close' => t ( 'Close' ),
'$expanded' => (( x ( $x , 'expanded' )) ? $x [ 'expanded' ] : false ),
'$bbcode' => (( x ( $x , 'bbcode' )) ? $x [ 'bbcode' ] : false ),
'$parent' => (( array_key_exists ( 'parent' , $x ) && $x [ 'parent' ]) ? $x [ 'parent' ] : 0 ),
'$summaryenabled' => $summaryenabled ,
'$summary' => (( x ( $x , 'summary' )) ? htmlspecialchars ( $x [ 'summary' ], ENT_COMPAT , 'UTF-8' ) : '' ),
'$placeholdsummary' => t ( 'Summary' ),
'$discombed' => t ( 'Load remote media players' ),
'$discombed2' => t ( 'This <em>may</em> subject viewers of this post to behaviour tracking' ),
'$embedchecked' => (( get_pconfig ( $x [ 'profile_uid' ], 'system' , 'linkinfo_embed' , true )) ? ' checked ' : '' ),
2022-11-21 21:29:13 +00:00
'$disczot' => t ( 'Find shareable objects' ),
2022-11-15 20:16:26 +00:00
'$checkin_checked' => $checkin_checked ,
2022-11-21 19:15:54 +00:00
'$checkout_checked' => $checkout_checked ,
2021-12-03 03:01:39 +00:00
'$reset' => $reset
2022-09-17 23:28:33 +00:00
]);
2021-12-03 03:01:39 +00:00
if ( $popup === true ) {
$o = '<div id="jot-popup" style="display:none">' . $o . '</div>' ;
}
2019-04-03 23:22:03 +00:00
2021-12-03 03:01:39 +00:00
return $o ;
2019-04-03 23:22:03 +00:00
}
2019-09-10 04:03:33 +00:00
2021-12-03 03:01:39 +00:00
function jot_collections ( $channel , $collections )
{
2019-09-04 00:33:27 +00:00
2021-12-03 03:01:39 +00:00
$output = EMPTY_STR ;
2019-09-10 04:03:33 +00:00
2021-12-03 03:01:39 +00:00
$r = q (
" select channel_address, channel_name from channel where channel_parent = '%s' and channel_removed = 0 order by channel_name asc " ,
dbesc ( $channel [ 'channel_hash' ])
);
if ( ! $r ) {
return $output ;
}
2019-04-05 02:14:32 +00:00
2021-12-03 03:01:39 +00:00
$size = (( count ( $r ) < 4 ) ? count ( $r ) : 4 );
2019-04-03 23:22:03 +00:00
2021-12-03 03:01:39 +00:00
$output .= t ( 'Post to Collections' );
$output .= '<select size="' . $size . '" class="form-control" name="collections[]" multiple>' ;
foreach ( $r as $rv ) {
2022-01-25 01:26:12 +00:00
$selected = (( is_array ( $collections ) && in_array ( Channel :: get_webfinger ( $rv ), $collections )) ? " selected " : " " );
$output .= '<option value="' . Channel :: get_webfinger ( $rv ) . '"' . $selected . '>' . $rv [ 'channel_name' ] . '</option>' ;
2021-12-03 03:01:39 +00:00
}
$output .= '</select>' ;
2019-04-03 23:22:03 +00:00
2021-12-03 03:01:39 +00:00
return $output ;
2012-08-09 23:26:44 +00:00
}
2019-09-10 04:03:33 +00:00
2021-12-03 03:01:39 +00:00
function get_item_children ( $arr , $parent )
{
$children = [];
if ( ! $arr ) {
return $children ;
}
$thread_allow = get_config ( 'system' , 'thread_allow' , true );
2023-03-17 21:29:31 +00:00
$thread_max = intval ( get_config ( 'system' , 'thread_maxlevel' , 80 ));
2021-12-03 03:01:39 +00:00
foreach ( $arr as $item ) {
if ( intval ( $item [ 'id' ]) !== intval ( $item [ 'parent' ])) {
if ( $thread_allow ) {
$thr_parent = $item [ 'thr_parent' ];
// Fallback to parent_mid if thr_parent is not set
if ( $thr_parent === EMPTY_STR ) {
$thr_parent = $item [ 'parent_mid' ];
}
if ( $thr_parent === $parent [ 'mid' ]) {
$my_children = get_item_children ( $arr , $item );
if ( $item [ 'item_level' ] > $thread_max ) {
// Like and Dislike activities are allowed as children of the last supported level.
// After that they are ignored.
// Any other children deeper than $thread_max are flattened.
if ( in_array ( $item [ 'verb' ], [ 'Like' , 'Dislike' ])) {
if ( $item [ 'item_level' ] > ( $thread_max + 1 )) {
continue ;
}
}
$children = (( $my_children ) ? array_merge ( $children , $my_children ) : $children );
} else {
$item [ 'children' ] = $my_children ;
}
$children [] = $item ;
}
} elseif ( intval ( $item [ 'parent' ]) === intval ( $parent [ 'id' ])) {
// threads are disabled. Anything that is in this conversation gets added to children.
$children [] = $item ;
}
}
}
return $children ;
2012-08-09 23:26:44 +00:00
}
2021-12-03 03:01:39 +00:00
function sort_item_children ( $items )
{
$result = $items ;
usort ( $result , 'sort_thr_created_rev' );
foreach ( $result as $k => $i ) {
if ( $result [ $k ][ 'children' ]) {
$result [ $k ][ 'children' ] = sort_item_children ( $result [ $k ][ 'children' ]);
}
}
return $result ;
2012-08-09 23:26:44 +00:00
}
2021-12-03 03:01:39 +00:00
function add_children_to_list ( $children , & $arr )
{
foreach ( $children as $y ) {
$arr [] = $y ;
if ( $y [ 'children' ]) {
add_children_to_list ( $y [ 'children' ], $arr );
}
}
2018-12-03 04:56:23 +00:00
}
2020-09-21 02:45:41 +00:00
/*
* separate the incoming array into conversations , with the original post at index 0 ,
* and the comments following in reverse date order ( newest first ) . Likes and other hidden activities go to the end .
* This lets us choose the most recent comments in each conversation ( regardless of thread depth )
2021-12-03 03:01:39 +00:00
* to open by default - while collapsing everything else .
2020-09-21 02:45:41 +00:00
*/
2022-05-25 23:00:59 +00:00
function flatten_and_order ( $arr , $order )
2021-12-03 03:01:39 +00:00
{
$narr = [];
$ret = [];
foreach ( $arr as $a ) {
$narr [ $a [ 'parent' ]][] = $a ;
}
foreach ( $narr as $n ) {
2022-05-25 23:00:59 +00:00
usort ( $n , ( $order === 'received' ) ? 'sort_flatten_received' : 'sort_flatten' );
2021-12-03 03:01:39 +00:00
for ( $x = 0 ; $x < count ( $n ); $x ++ ) {
$n [ $x ][ 'comment_order' ] = $x ;
$ret [] = $n [ $x ];
}
}
2020-09-21 02:45:41 +00:00
2021-12-03 03:01:39 +00:00
return $ret ;
2020-09-21 02:45:41 +00:00
}
2021-12-03 03:01:39 +00:00
function conv_sort ( $arr , $order )
{
2012-01-03 00:54:37 +00:00
2021-12-03 03:01:39 +00:00
$parents = [];
$ret = [];
2012-01-03 00:54:37 +00:00
2021-12-03 03:01:39 +00:00
if ( ! ( is_array ( $arr ) && count ( $arr ))) {
return $ret ;
}
2020-03-20 04:08:50 +00:00
2021-12-03 03:01:39 +00:00
$narr = [];
foreach ( $arr as $item ) {
// perform view filtering if viewer is logged in locally
// This allows blocking and message filters to work on public stream items
// or other channel streams on this site which are not owned by the viewer
if ( local_channel ()) {
2023-08-10 21:28:47 +00:00
$m = parse_url ( $item [ 'author' ][ 'hubloc_url' ]);
2023-08-10 22:23:07 +00:00
$authorSite = $m [ 'host' ];
2023-08-10 21:28:47 +00:00
$m = parse_url ( $item [ 'owner' ][ 'hubloc_url' ]);
2023-08-10 22:23:07 +00:00
$ownerSite = $m [ 'host' ];
2023-08-10 22:27:51 +00:00
2023-08-10 20:49:23 +00:00
if ( LibBlock :: fetch_by_entity ( local_channel (), $authorSite )
|| LibBlock :: fetch_by_entity ( local_channel (), $ownerSite )) {
continue ;
}
2022-09-18 00:14:35 +00:00
if ( LibBlock :: fetch_by_entity ( local_channel (), $item [ 'author_xchan' ])
|| LibBlock :: fetch_by_entity ( local_channel (), $item [ 'owner_xchan' ])) {
2021-12-03 03:01:39 +00:00
continue ;
}
$message_filter_abook = [];
if ( App :: $contacts && array_key_exists ( $item [ 'author_xchan' ], App :: $contacts )) {
$message_filter_abook [] = App :: $contacts [ $item [ 'author_xchan' ]];
}
if ( App :: $contacts && array_key_exists ( $item [ 'owner_xchan' ], App :: $contacts )) {
$message_filter_abook [] = App :: $contacts [ $item [ 'owner_xchan' ]];
}
if ( ! post_is_importable ( local_channel (), $item , $message_filter_abook ? $message_filter_abook : false )) {
continue ;
}
$matches = null ;
$found = false ;
2022-09-17 23:28:33 +00:00
$cnt = preg_match_all ( " / \ [share(.*?)portable_id='(.*?)'(.*?)]/ism " , $item [ 'body' ], $matches , PREG_SET_ORDER );
2021-12-03 03:01:39 +00:00
if ( $cnt ) {
foreach ( $matches as $match ) {
if ( LibBlock :: fetch_by_entity ( local_channel (), $match [ 2 ])) {
$found = true ;
}
}
}
2022-11-25 23:55:41 +00:00
if ( $item [ 'obj' ]) {
$local = json_decode ( $item [ 'obj' ], true );
if ( ! empty ( $local [ 'source' ]) && ! empty ( $local [ 'source' ][ 'mediaType' ]) && ! empty ( $local [ 'source' ][ 'content' ])) {
$cnt = preg_match_all ( " / \ [share(.*?)portable_id='(.*?)'(.*?)]/ism " , $local [ 'source' ][ 'content' ], $matches , PREG_SET_ORDER );
if ( $cnt ) {
foreach ( $matches as $match ) {
if ( LibBlock :: fetch_by_entity ( local_channel (), $match [ 2 ])) {
$found = true ;
}
}
}
}
}
2021-12-03 03:01:39 +00:00
if ( $found ) {
continue ;
}
$matches = null ;
$found = false ;
2022-09-17 23:28:33 +00:00
$cnt = preg_match_all ( " / \ [share(.*?)profile='(.*?)'(.*?)]/ism " , $item [ 'body' ], $matches , PREG_SET_ORDER );
2021-12-03 03:01:39 +00:00
if ( $cnt ) {
foreach ( $matches as $match ) {
$r = q (
2022-06-17 02:46:54 +00:00
" select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_deleted = 0 " ,
2021-12-03 03:01:39 +00:00
dbesc ( $match [ 2 ])
);
if ( $r ) {
if ( LibBlock :: fetch_by_entity ( local_channel (), $r [ 0 ][ 'hubloc_hash' ])) {
$found = true ;
}
}
}
}
if ( $found ) {
continue ;
}
}
$narr [] = $item ;
}
2019-09-24 06:22:17 +00:00
2021-12-03 03:01:39 +00:00
$data = [ 'items' => $narr , 'order' => $order ];
2019-09-24 06:22:17 +00:00
2022-02-12 08:50:48 +00:00
Hook :: call ( 'conv_sort' , $data );
2019-09-24 06:22:17 +00:00
2021-12-03 03:01:39 +00:00
$arr = $data [ 'items' ];
2019-09-24 06:22:17 +00:00
2021-12-03 03:01:39 +00:00
if ( ! ( is_array ( $arr ) && count ( $arr ))) {
return $ret ;
}
2020-09-21 02:45:41 +00:00
2022-05-25 23:00:59 +00:00
$arr = flatten_and_order ( $arr , $order );
2019-09-24 06:22:17 +00:00
2012-01-03 00:54:37 +00:00
2021-12-03 03:01:39 +00:00
foreach ( $arr as $x ) {
if ( intval ( $x [ 'id' ]) === intval ( $x [ 'parent' ])) {
$parents [] = $x ;
}
}
2020-09-21 02:45:41 +00:00
2012-01-03 00:54:37 +00:00
2021-12-03 03:01:39 +00:00
if ( stristr ( $order , 'created' )) {
usort ( $parents , 'sort_thr_created' );
2022-10-02 07:41:06 +00:00
} elseif ( stristr ( $order , 'distance' )) {
usort ( $parents , 'sort_thr_distance' );
2021-12-03 03:01:39 +00:00
} elseif ( stristr ( $order , 'commented' )) {
usort ( $parents , 'sort_thr_commented' );
} elseif ( stristr ( $order , 'updated' )) {
usort ( $parents , 'sort_thr_updated' );
2022-05-25 23:00:59 +00:00
} elseif ( stristr ( $order , 'changed' )) {
usort ( $parents , 'sort_thr_received' );
2021-12-03 03:01:39 +00:00
} elseif ( stristr ( $order , 'ascending' )) {
usort ( $parents , 'sort_thr_created_rev' );
}
if ( $parents ) {
foreach ( $parents as $i => $_x ) {
$parents [ $i ][ 'children' ] = get_item_children ( $arr , $_x );
}
2012-01-03 00:54:37 +00:00
2021-12-03 03:01:39 +00:00
foreach ( $parents as $k => $v ) {
2022-09-17 23:28:33 +00:00
if ( $v [ 'children' ]) {
2021-12-03 03:01:39 +00:00
$parents [ $k ][ 'children' ] = sort_item_children ( $parents [ $k ][ 'children' ]);
}
}
}
if ( $parents ) {
foreach ( $parents as $x ) {
$ret [] = $x ;
if ( $x [ 'children' ]) {
add_children_to_list ( $x [ 'children' ], $ret );
}
}
}
2012-01-03 00:54:37 +00:00
2021-12-03 03:01:39 +00:00
return $ret ;
2012-01-03 00:54:37 +00:00
}
2020-09-21 02:45:41 +00:00
// This is a complicated sort.
// We want the original post at index 0 and all the comments (regardless of thread depth) ordered newest to oldest.
// likes and other invisible activities go to the end of the array beyond the oldest comment.
2021-12-03 03:01:39 +00:00
function sort_flatten ( $a , $b )
{
2020-09-21 02:45:41 +00:00
2021-12-03 03:01:39 +00:00
if ( $a [ 'parent' ] === $a [ 'id' ]) {
return - 1 ;
}
if ( $b [ 'parent' ] === $b [ 'id' ]) {
return 1 ;
}
2020-09-21 02:45:41 +00:00
2021-12-03 03:01:39 +00:00
if ( ! visible_activity ( $a )) {
return 1 ;
}
if ( ! visible_activity ( $b )) {
return - 1 ;
}
2020-09-21 02:45:41 +00:00
2021-12-03 03:01:39 +00:00
return strcmp ( $b [ 'created' ], $a [ 'created' ]);
2020-09-21 02:45:41 +00:00
}
2022-05-25 23:00:59 +00:00
function sort_flatten_received ( $a , $b )
{
if ( $a [ 'parent' ] === $a [ 'id' ]) {
return - 1 ;
}
if ( $b [ 'parent' ] === $b [ 'id' ]) {
return 1 ;
}
if ( ! visible_activity ( $a )) {
return 1 ;
}
if ( ! visible_activity ( $b )) {
return - 1 ;
}
return strcmp ( $b [ 'changed' ], $a [ 'changed' ]);
}
2020-09-21 02:45:41 +00:00
2021-12-03 03:01:39 +00:00
function sort_thr_created ( $a , $b )
{
return strcmp ( $b [ 'created' ], $a [ 'created' ]);
2012-01-03 00:54:37 +00:00
}
2021-12-03 03:01:39 +00:00
function sort_thr_created_rev ( $a , $b )
{
return strcmp ( $a [ 'created' ], $b [ 'created' ]);
2012-01-03 00:54:37 +00:00
}
2021-12-03 03:01:39 +00:00
function sort_thr_commented ( $a , $b )
{
return strcmp ( $b [ 'commented' ], $a [ 'commented' ]);
2012-01-03 00:54:37 +00:00
}
2022-05-25 23:00:59 +00:00
function sort_thr_received ( $a , $b )
{
return strcmp ( $b [ 'changed' ], $a [ 'changed' ]);
}
2022-09-17 23:28:33 +00:00
function sort_thr_distance ( $a , $b )
{
2022-09-18 00:14:35 +00:00
if ( ! isset ( $a [ 'distance' ])) {
$a [ 'distance' ] = 999999999 ;
}
if ( ! isset ( $b [ 'distance' ])) {
$b [ 'distance' ] = 999999999 ;
}
2022-11-10 08:56:42 +00:00
if ( $a [ 'distance' ] === $b [ 'distance' ]) {
return strcmp ( $b [ 'commented' ], $a [ 'commented' ]);
}
2022-10-02 07:41:06 +00:00
return floatval ( $a [ 'distance' ]) <=> floatval ( $b [ 'distance' ]);
2022-09-17 23:28:33 +00:00
}
2021-12-03 03:01:39 +00:00
function sort_thr_updated ( $a , $b )
{
$indexa = (( $a [ 'changed' ] > $a [ 'edited' ]) ? $a [ 'changed' ] : $a [ 'edited' ]);
$indexb = (( $b [ 'changed' ] > $b [ 'edited' ]) ? $b [ 'changed' ] : $b [ 'edited' ]);
return strcmp ( $indexb , $indexa );
2017-08-24 03:02:28 +00:00
}
2021-12-03 03:01:39 +00:00
function find_thread_parent_index ( $arr , $x )
{
foreach ( $arr as $k => $v ) {
if ( $v [ 'id' ] == $x [ 'parent' ]) {
return $k ;
}
}
2015-03-10 20:42:26 +00:00
2021-12-03 03:01:39 +00:00
return false ;
2012-01-06 08:11:25 +00:00
}
2012-02-09 23:02:59 +00:00
2021-12-03 03:01:39 +00:00
function format_location ( $item )
{
2013-02-03 00:34:00 +00:00
2022-09-17 23:28:33 +00:00
if ( str_starts_with ( $item [ 'location' ], '#' )) {
2021-12-03 03:01:39 +00:00
$location = substr ( $item [ 'location' ], 1 );
2022-09-17 23:28:33 +00:00
$location = (( str_contains ( $location , '[' )) ? zidify_links ( bbcode ( $location )) : $location );
2021-12-03 03:01:39 +00:00
} else {
2022-09-17 23:28:33 +00:00
$locate = [ 'location' => $item [ 'location' ], 'lat' => $item [ 'lat' ], 'lon' => $item [ 'lon' ], 'coord' => $item [ 'coord' ], 'html' => '' ];
2022-02-12 08:50:48 +00:00
Hook :: call ( 'render_location' , $locate );
2021-12-03 03:01:39 +00:00
$location = (( strlen ( $locate [ 'html' ])) ? $locate [ 'html' ] : render_location_default ( $locate ));
}
2022-10-02 07:41:06 +00:00
return $location . ( ! empty ( $item [ 'distance' ]) ? t ( ' distance: ' ) . sprintf ( " %05.03f km " , $item [ 'distance' ]) : '' );
2013-02-03 00:34:00 +00:00
}
2021-12-03 03:01:39 +00:00
function render_location_default ( $item )
{
2013-02-03 00:34:00 +00:00
2021-12-03 03:01:39 +00:00
$location = $item [ 'location' ];
2022-09-16 10:57:04 +00:00
$latitude = $item [ 'lat' ];
$longitude = $item [ 'lon' ];
2013-02-03 00:34:00 +00:00
2022-09-16 10:57:04 +00:00
if ( $latitude || $longitude ) {
2021-12-03 03:01:39 +00:00
if ( $location ) {
2022-09-16 10:57:04 +00:00
$location .= ' <span class="smalltext">(' . $latitude . ',' . $longitude . ')</span>' ;
2021-12-03 03:01:39 +00:00
} else {
2022-09-16 10:57:04 +00:00
$location = '<span class="smalltext">' . $latitude . ',' . $longitude . '</span>' ;
2021-12-03 03:01:39 +00:00
}
}
return $location ;
2012-02-09 23:02:59 +00:00
}
2013-01-15 09:32:11 +00:00
2021-12-03 03:01:39 +00:00
function prepare_page ( $item )
{
$naked = 1 ;
$preview = substr ( urlencode ( $item [ 'body' ]), 0 , 240 );
$link = z_root () . '/' . App :: $cmd ;
if ( array_key_exists ( 'webpage' , App :: $layout ) && array_key_exists ( 'authored' , App :: $layout [ 'webpage' ])) {
if ( App :: $layout [ 'webpage' ][ 'authored' ] === 'none' ) {
$naked = 1 ;
}
// ... other possible options
}
2016-05-25 03:49:23 +00:00
2021-12-03 03:01:39 +00:00
// prepare_body calls unobscure() as a side effect. Do it here so that
// the template will get passed an unobscured title.
2014-06-16 02:21:32 +00:00
2021-12-03 03:01:39 +00:00
$body = prepare_body ( $item , true , [ 'newwin' => false ]);
if ( App :: $page [ 'template' ] == 'none' ) {
$tpl = 'page_display_empty.tpl' ;
2014-06-16 02:25:16 +00:00
2022-09-17 23:28:33 +00:00
return replace_macros ( Theme :: get_template ( $tpl ), [
2021-12-03 03:01:39 +00:00
'$body' => $body [ 'html' ]
2022-09-17 23:28:33 +00:00
]);
2021-12-03 03:01:39 +00:00
}
2017-04-24 01:22:40 +00:00
2021-12-03 03:01:39 +00:00
$tpl = get_pconfig ( $item [ 'uid' ], 'system' , 'pagetemplate' );
if ( ! $tpl ) {
$tpl = 'page_display.tpl' ;
}
2022-09-17 23:28:33 +00:00
return replace_macros ( Theme :: get_template ( $tpl ), [
2021-12-03 03:01:39 +00:00
'$author' => (( $naked ) ? '' : $item [ 'author' ][ 'xchan_name' ]),
'$auth_url' => (( $naked ) ? '' : zid ( $item [ 'author' ][ 'xchan_url' ])),
2024-03-10 02:40:50 +00:00
'$date' => (( $naked ) ? '' : Time :: convert ( 'UTC' , date_default_timezone_get (), $item [ 'created' ], 'Y-m-d H:i' )),
2021-12-03 03:01:39 +00:00
'$title' => zidify_links ( smilies ( bbcode ( $item [ 'title' ]))),
'$body' => $body [ 'html' ],
'$preview' => $preview ,
'$link' => $link ,
2022-09-17 23:28:33 +00:00
]);
2013-01-15 09:32:11 +00:00
}
2013-12-06 05:00:14 +00:00
2021-12-03 03:01:39 +00:00
function get_responses ( $conv_responses , $response_verbs , $ob , $item )
{
2015-02-11 05:21:18 +00:00
2021-12-03 03:01:39 +00:00
$ret = [];
foreach ( $response_verbs as $v ) {
$ret [ $v ] = [];
$ret [ $v ][ 'count' ] = (( x ( $conv_responses [ $v ], $item [ 'mid' ])) ? $conv_responses [ $v ][ $item [ 'mid' ]] : '' );
$ret [ $v ][ 'list' ] = (( x ( $conv_responses [ $v ], $item [ 'mid' ])) ? $conv_responses [ $v ][ $item [ 'mid' ] . '-l' ] : '' );
$ret [ $v ][ 'button' ] = get_response_button_text ( $v , $ret [ $v ][ 'count' ]);
$ret [ $v ][ 'title' ] = $conv_responses [ $v ][ 'title' ];
if ( $ret [ $v ][ 'count' ] > MAX_LIKERS ) {
$ret [ $v ][ 'modal' ] = true ;
}
}
2015-02-11 11:09:04 +00:00
2021-12-03 03:01:39 +00:00
$count = 0 ;
foreach ( $ret as $key ) {
2022-12-22 07:51:22 +00:00
if ( $key [ 'count' ]) {
2021-12-03 03:01:39 +00:00
$count ++ ;
}
}
2015-02-11 11:09:04 +00:00
2021-12-03 03:01:39 +00:00
$ret [ 'count' ] = $count ;
2015-02-11 11:09:04 +00:00
2015-02-11 05:21:18 +00:00
//logger('ret: ' . print_r($ret,true));
2015-02-11 11:09:04 +00:00
2021-12-03 03:01:39 +00:00
return $ret ;
2015-02-10 05:18:50 +00:00
}
2021-12-03 03:01:39 +00:00
function get_response_button_text ( $v , $count )
{
switch ( $v ) {
case 'like' :
if ( get_config ( 'system' , 'show_like_counts' , true )) {
return $count . ' ' . tt ( 'Like' , 'Likes' , $count , 'noun' );
} else {
return t ( 'Likes' , 'noun' );
}
case 'dislike' :
if ( get_config ( 'system' , 'show_like_counts' , true )) {
return $count . ' ' . tt ( 'Dislike' , 'Dislikes' , $count , 'noun' );
} else {
return t ( 'Dislikes' , 'noun' );
}
2024-03-22 07:41:37 +00:00
case 'repeat' :
if ( get_config ( 'system' , 'show_like_counts' , true )) {
return $count . ' ' . tt ( 'Repeat' , 'Repeats' , $count , 'noun' );
} else {
return t ( 'Repeats' , 'noun' );
}
2021-12-03 03:01:39 +00:00
case 'attendyes' :
return $count . ' ' . tt ( 'Attending' , 'Attending' , $count , 'noun' );
case 'attendno' :
return $count . ' ' . tt ( 'Not Attending' , 'Not Attending' , $count , 'noun' );
case 'attendmaybe' :
return $count . ' ' . tt ( 'Undecided' , 'Undecided' , $count , 'noun' );
case 'agree' :
return $count . ' ' . tt ( 'Agree' , 'Agrees' , $count , 'noun' );
case 'disagree' :
return $count . ' ' . tt ( 'Disagree' , 'Disagrees' , $count , 'noun' );
case 'abstain' :
return $count . ' ' . tt ( 'Abstain' , 'Abstains' , $count , 'noun' );
default :
return '' ;
}
2015-02-10 05:18:50 +00:00
}