2016-04-19 03:38:38 +00:00
< ? php
namespace Zotlabs\Module ;
2019-04-16 04:55:59 +00:00
use App ;
use Zotlabs\Web\Controller ;
2019-02-14 23:26:37 +00:00
use Zotlabs\Lib\AccessList ;
2018-08-17 06:01:31 +00:00
use Zotlabs\Lib\Apps ;
2020-03-06 04:15:01 +00:00
use Zotlabs\Lib\PermissionDescription ;
2019-01-18 21:04:05 +00:00
2016-04-19 03:38:38 +00:00
require_once ( 'include/conversation.php' );
require_once ( 'include/acl_selectors.php' );
2020-02-13 05:36:21 +00:00
class Stream extends Controller {
2016-04-19 03:38:38 +00:00
function init () {
2019-04-16 04:55:59 +00:00
if ( ! local_channel ()) {
2016-04-19 03:38:38 +00:00
return ;
}
2018-08-21 05:02:08 +00:00
$channel = App :: get_channel ();
App :: $profile_uid = local_channel ();
2020-06-03 04:19:17 +00:00
App :: $data [ 'channel' ] = $channel ;
2019-04-16 04:55:59 +00:00
head_set_icon ( $channel [ 'xchan_photo_s' ]);
2016-04-19 03:38:38 +00:00
}
2019-04-16 04:55:59 +00:00
2016-04-19 03:38:38 +00:00
function get ( $update = 0 , $load = false ) {
2019-04-16 04:55:59 +00:00
if ( ! local_channel ()) {
2018-08-21 05:02:08 +00:00
$_SESSION [ 'return_url' ] = App :: $query_string ;
2016-04-19 03:38:38 +00:00
return login ( false );
}
2021-04-06 00:57:39 +00:00
2017-12-28 23:16:50 +00:00
$o = '' ;
2019-04-16 04:55:59 +00:00
if ( $load ) {
2016-04-19 03:38:38 +00:00
$_SESSION [ 'loadtime' ] = datetime_convert ();
2017-12-28 23:16:50 +00:00
}
2019-04-16 04:55:59 +00:00
$arr = [ 'query' => App :: $query_string ];
2020-02-13 05:36:21 +00:00
call_hooks ( 'stream_content_init' , $arr );
2016-04-19 03:38:38 +00:00
2021-03-09 01:51:41 +00:00
$channel = (( isset ( App :: $data [ 'channel' ])) ? App :: $data [ 'channel' ] : null );
2020-06-03 04:19:17 +00:00
// if called from liveUpdate() we will not have called Stream::init() on this request and $channel will not be set
2019-04-16 04:55:59 +00:00
2020-06-03 04:19:17 +00:00
if ( ! $channel ) {
$channel = App :: get_channel ();
}
2016-04-19 03:38:38 +00:00
$item_normal = item_normal ();
2017-09-03 19:33:07 +00:00
$item_normal_update = item_normal_update ();
2016-04-19 03:38:38 +00:00
$datequery = $datequery2 = '' ;
$group = 0 ;
$nouveau = false ;
$datequery = (( x ( $_GET , 'dend' ) && is_a_date_arg ( $_GET [ 'dend' ])) ? notags ( $_GET [ 'dend' ]) : '' );
$datequery2 = (( x ( $_GET , 'dbegin' ) && is_a_date_arg ( $_GET [ 'dbegin' ])) ? notags ( $_GET [ 'dbegin' ]) : '' );
2016-11-02 22:48:29 +00:00
$static = (( x ( $_GET , 'static' )) ? intval ( $_GET [ 'static' ]) : 0 );
2020-10-11 23:07:28 +00:00
$gid = (( x ( $_GET , 'gid' )) ? $_REQUEST [ 'gid' ] : 0 );
2016-04-19 03:38:38 +00:00
$category = (( x ( $_REQUEST , 'cat' )) ? $_REQUEST [ 'cat' ] : '' );
$hashtags = (( x ( $_REQUEST , 'tag' )) ? $_REQUEST [ 'tag' ] : '' );
$verb = (( x ( $_REQUEST , 'verb' )) ? $_REQUEST [ 'verb' ] : '' );
2019-06-19 02:21:31 +00:00
$dm = (( x ( $_REQUEST , 'dm' )) ? $_REQUEST [ 'dm' ] : 0 );
2018-05-30 12:02:58 +00:00
2020-10-17 03:40:27 +00:00
$c_order = get_pconfig ( local_channel (), 'mod_stream' , 'order' , 0 );
switch ( $c_order ) {
2018-05-30 12:02:58 +00:00
case 0 :
$order = 'comment' ;
break ;
case 1 :
$order = 'post' ;
break ;
case 2 :
$nouveau = true ;
break ;
}
2021-03-09 01:51:41 +00:00
$search = ( isset ( $_GET [ 'search' ]) ? $_GET [ 'search' ] : '' );
2019-04-16 04:55:59 +00:00
if ( $search ) {
2016-09-01 04:57:08 +00:00
$_GET [ 'netsearch' ] = escape_tags ( $search );
2019-04-16 04:55:59 +00:00
if ( strpos ( $search , '@' ) === 0 ) {
2016-04-19 03:38:38 +00:00
$r = q ( " select abook_id from abook left join xchan on abook_xchan = xchan_hash where xchan_name = '%s' and abook_channel = %d limit 1 " ,
dbesc ( substr ( $search , 1 )),
intval ( local_channel ())
);
2019-04-16 04:55:59 +00:00
if ( $r ) {
2016-04-19 03:38:38 +00:00
$_GET [ 'cid' ] = $r [ 0 ][ 'abook_id' ];
$search = $_GET [ 'search' ] = '' ;
}
}
2019-04-16 04:55:59 +00:00
elseif ( strpos ( $search , '#' ) === 0 ) {
2016-04-19 03:38:38 +00:00
$hashtags = substr ( $search , 1 );
$search = $_GET [ 'search' ] = '' ;
}
}
2019-04-16 04:55:59 +00:00
if ( $datequery ) {
2018-05-30 12:02:58 +00:00
$order = 'post' ;
2019-04-16 04:55:59 +00:00
}
2016-04-19 03:38:38 +00:00
// filter by collection (e.g. group)
2020-10-11 22:41:49 +00:00
$vg = false ;
2019-04-16 04:55:59 +00:00
if ( $gid ) {
2020-10-11 22:41:49 +00:00
if ( strpos ( $gid , ':' ) === 0 ) {
$g = substr ( $gid , 1 );
switch ( $g ) {
case '1' :
2021-05-21 01:01:42 +00:00
$r = [[ 'hash' => 'connections:' . $channel [ 'channel_hash' ] ]];
2020-10-11 22:41:49 +00:00
$vg = t ( 'Connections' );
break ;
case '2' :
2021-05-21 01:01:42 +00:00
$r = [[ 'hash' => 'zot:' . $channel [ 'channel_hash' ] ]];
$vg = t ( 'Nomad' );
2020-10-11 22:41:49 +00:00
break ;
case '3' :
2021-05-21 01:01:42 +00:00
$r = [[ 'hash' => 'activitypub:' . $channel [ 'channel_hash' ] ]];
2020-10-11 22:41:49 +00:00
$vg = t ( 'ActivityPub' );
break ;
default :
break ;
}
}
else {
$r = q ( " SELECT * FROM pgrp WHERE id = %d AND uid = %d LIMIT 1 " ,
intval ( $gid ),
intval ( local_channel ())
);
if ( ! $r ) {
if ( $update ) {
killme ();
}
notice ( t ( 'Access list not found' ) . EOL );
goaway ( z_root () . '/stream' );
2019-04-16 04:55:59 +00:00
}
2016-04-19 03:38:38 +00:00
}
2021-05-21 01:01:42 +00:00
2016-04-19 03:38:38 +00:00
$group = $gid ;
$group_hash = $r [ 0 ][ 'hash' ];
2021-05-21 01:01:42 +00:00
2016-04-19 03:38:38 +00:00
}
2019-07-30 02:33:36 +00:00
$default_cmin = (( Apps :: system_app_installed ( local_channel (), 'Friend Zoom' )) ? get_pconfig ( local_channel (), 'affinity' , 'cmin' , 0 ) : ( - 1 ));
$default_cmax = (( Apps :: system_app_installed ( local_channel (), 'Friend Zoom' )) ? get_pconfig ( local_channel (), 'affinity' , 'cmax' , 99 ) : ( - 1 ));
2017-12-31 06:48:06 +00:00
2016-04-19 03:38:38 +00:00
$cid = (( x ( $_GET , 'cid' )) ? intval ( $_GET [ 'cid' ]) : 0 );
2020-11-30 00:38:45 +00:00
$draft = (( x ( $_GET , 'draft' )) ? intval ( $_GET [ 'draft' ]) : 0 );
2016-04-19 03:38:38 +00:00
$star = (( x ( $_GET , 'star' )) ? intval ( $_GET [ 'star' ]) : 0 );
$liked = (( x ( $_GET , 'liked' )) ? intval ( $_GET [ 'liked' ]) : 0 );
$conv = (( x ( $_GET , 'conv' )) ? intval ( $_GET [ 'conv' ]) : 0 );
$spam = (( x ( $_GET , 'spam' )) ? intval ( $_GET [ 'spam' ]) : 0 );
2017-12-31 06:48:06 +00:00
$cmin = (( array_key_exists ( 'cmin' , $_GET )) ? intval ( $_GET [ 'cmin' ]) : $default_cmin );
$cmax = (( array_key_exists ( 'cmax' , $_GET )) ? intval ( $_GET [ 'cmax' ]) : $default_cmax );
2016-04-19 03:38:38 +00:00
$file = (( x ( $_GET , 'file' )) ? $_GET [ 'file' ] : '' );
2017-03-03 01:32:43 +00:00
$xchan = (( x ( $_GET , 'xchan' )) ? $_GET [ 'xchan' ] : '' );
2017-11-01 09:53:12 +00:00
$net = (( x ( $_GET , 'net' )) ? $_GET [ 'net' ] : '' );
2018-06-05 09:56:30 +00:00
$pf = (( x ( $_GET , 'pf' )) ? $_GET [ 'pf' ] : '' );
2017-03-03 01:32:43 +00:00
2016-04-19 03:38:38 +00:00
$deftag = '' ;
2018-06-15 09:02:03 +00:00
2020-11-30 00:38:45 +00:00
2019-04-16 04:55:59 +00:00
if ( x ( $_GET , 'search' ) || $file || ( ! $pf && $cid )) {
2016-04-19 03:38:38 +00:00
$nouveau = true ;
2019-04-16 04:55:59 +00:00
}
2018-05-30 20:40:22 +00:00
2019-04-16 04:55:59 +00:00
if ( $cid ) {
2019-03-06 01:27:16 +00:00
$cid_r = q ( " SELECT abook.abook_xchan, xchan.xchan_addr, xchan.xchan_name, xchan.xchan_url, xchan.xchan_photo_s, xchan.xchan_type from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and abook_blocked = 0 limit 1 " ,
2016-04-19 03:38:38 +00:00
intval ( $cid ),
intval ( local_channel ())
);
2018-06-03 21:03:30 +00:00
2019-04-16 04:55:59 +00:00
if ( ! $cid_r ) {
if ( $update ) {
2016-04-19 03:38:38 +00:00
killme ();
}
notice ( t ( 'No such channel' ) . EOL );
2020-02-13 05:36:21 +00:00
goaway ( z_root () . '/stream' );
2016-04-19 03:38:38 +00:00
}
2021-05-21 01:01:42 +00:00
2016-04-19 03:38:38 +00:00
}
2019-04-16 04:55:59 +00:00
if ( ! $update ) {
2016-04-19 03:38:38 +00:00
// search terms header
2019-04-16 04:55:59 +00:00
if ( $search ) {
$o .= replace_macros ( get_markup_template ( " section_title.tpl " ),
[ '$title' => t ( 'Search Results For:' ) . ' ' . htmlspecialchars ( $search , ENT_COMPAT , 'UTF-8' ) ]
);
2016-04-19 03:38:38 +00:00
}
2020-03-19 23:56:48 +00:00
$body = EMPTY_STR ;
2018-09-17 01:35:43 +00:00
nav_set_selected ( 'Stream' );
2016-05-04 13:55:32 +00:00
2019-04-16 04:55:59 +00:00
$channel_acl = [
2016-04-19 03:38:38 +00:00
'allow_cid' => $channel [ 'channel_allow_cid' ],
'allow_gid' => $channel [ 'channel_allow_gid' ],
'deny_cid' => $channel [ 'channel_deny_cid' ],
'deny_gid' => $channel [ 'channel_deny_gid' ]
2019-04-16 04:55:59 +00:00
];
2016-05-04 13:55:32 +00:00
2019-04-16 04:55:59 +00:00
$x = [
'is_owner' => true ,
'allow_location' => (( intval ( get_pconfig ( $channel [ 'channel_id' ], 'system' , 'use_browser_location' ))) ? '1' : '' ),
'default_location' => $channel [ 'channel_location' ],
'nickname' => $channel [ 'channel_address' ],
2020-03-06 04:15:01 +00:00
'lockstate' => (( $channel [ 'channel_allow_cid' ] || $channel [ 'channel_allow_gid' ] || $channel [ 'channel_deny_cid' ] || $channel [ 'channel_deny_gid' ]) ? 'lock' : 'unlock' ),
'acl' => populate_acl ( $channel_acl , true , PermissionDescription :: fromGlobalPermission ( 'view_stream' ), get_post_aclDialogDescription (), 'acl_dialog_post' ),
'permissions' => $channel_acl ,
'bang' => EMPTY_STR ,
2020-03-19 23:56:48 +00:00
'body' => $body ,
2019-04-16 04:55:59 +00:00
'visitor' => true ,
'profile_uid' => local_channel (),
2016-04-19 03:38:38 +00:00
'editor_autocomplete' => true ,
2019-04-16 04:55:59 +00:00
'bbco_autocomplete' => 'bbcode' ,
'bbcode' => true ,
'jotnets' => true ,
'reset' => t ( 'Reset form' )
];
if ( $deftag ) {
2016-04-19 03:38:38 +00:00
$x [ 'pretext' ] = $deftag ;
2019-04-16 04:55:59 +00:00
}
2016-04-19 03:38:38 +00:00
2021-03-11 03:30:25 +00:00
$status_editor = status_editor ( $x );
2016-04-19 03:38:38 +00:00
$o .= $status_editor ;
2016-11-02 22:48:29 +00:00
2016-11-03 01:40:50 +00:00
$static = channel_manual_conv_update ( local_channel ());
2016-04-19 03:38:38 +00:00
}
// We don't have to deal with ACL's on this page. You're looking at everything
// that belongs to you, hence you can see all of it. We will filter by group if
// desired.
$sql_options = (( $star )
? " and item_starred = 1 "
: '' );
$sql_nets = '' ;
2018-02-04 19:42:40 +00:00
$item_thread_top = ' AND item_thread_top = 1 ' ;
2016-04-19 03:38:38 +00:00
2018-04-15 08:15:49 +00:00
$sql_extra = '' ;
2021-04-06 00:57:39 +00:00
if ( $draft ) {
$item_normal = item_normal_draft ();
2021-04-06 01:02:19 +00:00
$sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE item_unpublished = 1 and item_deleted = 0 ) " ;
2021-04-06 00:57:39 +00:00
}
2019-04-16 04:55:59 +00:00
if ( $group ) {
2016-04-19 03:38:38 +00:00
$contact_str = '' ;
2019-10-02 01:29:39 +00:00
$contacts = AccessList :: members ( local_channel (), $group );
2019-04-16 04:55:59 +00:00
if ( $contacts ) {
2018-04-26 05:53:20 +00:00
$contact_str = ids_to_querystr ( $contacts , 'xchan' , true );
2016-04-19 03:38:38 +00:00
}
else {
2018-04-26 05:53:20 +00:00
$contact_str = " '0' " ;
2020-10-14 05:02:22 +00:00
if ( ! $update ) {
2019-02-14 23:26:37 +00:00
info ( t ( 'Access list is empty' ));
2018-04-26 05:53:20 +00:00
}
2016-04-19 03:38:38 +00:00
}
2018-02-04 19:42:40 +00:00
$item_thread_top = '' ;
2018-06-03 21:03:30 +00:00
2016-04-19 03:38:38 +00:00
$sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str )) or allow_gid like ' " . protect_sprintf ( '%<' . dbesc ( $group_hash ) . '>%' ) . " ' ) and id = parent $item_normal ) " ;
2020-10-11 22:41:49 +00:00
if ( ! $vg ) {
$x = AccessList :: rec_byhash ( local_channel (), $group_hash );
}
2016-04-19 03:38:38 +00:00
2020-10-11 22:41:49 +00:00
if ( $x || $vg ) {
2016-04-19 03:38:38 +00:00
$title = replace_macros ( get_markup_template ( " section_title.tpl " ), array (
2020-10-11 22:41:49 +00:00
'$title' => sprintf ( t ( 'Access list: %s' ), (( $vg ) ? $vg : $x [ 'gname' ]))
2016-04-19 03:38:38 +00:00
));
}
2019-05-23 23:37:56 +00:00
$o = $title . $status_editor ;
2016-04-19 03:38:38 +00:00
}
2021-03-09 01:51:41 +00:00
elseif ( isset ( $cid_r ) && $cid_r ) {
2019-05-23 23:37:56 +00:00
$item_thread_top = EMPTY_STR ;
2018-06-03 21:03:30 +00:00
2019-04-16 04:55:59 +00:00
if ( $load || $update ) {
if ( ! $pf && $nouveau ) {
2018-06-08 21:19:30 +00:00
$sql_extra = " AND author_xchan = ' " . dbesc ( $cid_r [ 0 ][ 'abook_xchan' ]) . " ' " ;
}
else {
$ttype = (( $pf ) ? TERM_FORUM : TERM_MENTION );
2018-06-04 13:54:18 +00:00
2018-06-08 21:19:30 +00:00
$p1 = q ( " SELECT DISTINCT parent FROM item WHERE uid = " . intval ( local_channel ()) . " AND ( author_xchan = ' " . dbesc ( $cid_r [ 0 ][ 'abook_xchan' ]) . " ' OR owner_xchan = ' " . dbesc ( $cid_r [ 0 ][ 'abook_xchan' ]) . " ' ) $item_normal " );
$p2 = q ( " SELECT oid AS parent FROM term WHERE uid = " . intval ( local_channel ()) . " AND ttype = $ttype AND term = ' " . dbesc ( $cid_r [ 0 ][ 'xchan_name' ]) . " ' " );
2018-06-04 13:54:18 +00:00
2018-06-08 21:19:30 +00:00
$p_str = ids_to_querystr ( array_merge ( $p1 , $p2 ), 'parent' );
$sql_extra = " AND item.parent IN ( $p_str ) " ;
}
2016-04-19 03:38:38 +00:00
}
2018-06-03 21:03:30 +00:00
2020-10-14 05:02:22 +00:00
$title = replace_macros ( get_markup_template ( 'section_title.tpl' ), [
2018-06-03 21:03:30 +00:00
'$title' => '<a href="' . zid ( $cid_r [ 0 ][ 'xchan_url' ]) . '" ><img src="' . zid ( $cid_r [ 0 ][ 'xchan_photo_s' ]) . '" alt="' . urlencode ( $cid_r [ 0 ][ 'xchan_name' ]) . '" /></a> <a href="' . zid ( $cid_r [ 0 ][ 'xchan_url' ]) . '" >' . $cid_r [ 0 ][ 'xchan_name' ] . '</a>'
2020-10-14 05:02:22 +00:00
]);
2018-06-03 21:03:30 +00:00
2018-09-13 09:53:59 +00:00
$o = $title ;
2018-06-03 21:03:30 +00:00
$o .= $status_editor ;
2016-04-19 03:38:38 +00:00
}
2019-04-16 04:55:59 +00:00
elseif ( $xchan ) {
2018-02-04 19:42:40 +00:00
$r = q ( " select * from xchan where xchan_hash = '%s' " ,
dbesc ( $xchan )
);
2019-04-16 04:55:59 +00:00
if ( $r ) {
2018-02-04 19:42:40 +00:00
$item_thread_top = '' ;
$sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval ( local_channel ()) . " AND ( author_xchan = ' " . dbesc ( $xchan ) . " ' or owner_xchan = ' " . dbesc ( $xchan ) . " ' ) $item_normal ) " ;
2020-10-14 05:02:22 +00:00
$title = replace_macros ( get_markup_template ( 'section_title.tpl' ), [
2018-02-04 19:42:40 +00:00
'$title' => '<a href="' . zid ( $r [ 0 ][ 'xchan_url' ]) . '" ><img src="' . zid ( $r [ 0 ][ 'xchan_photo_s' ]) . '" alt="' . urlencode ( $r [ 0 ][ 'xchan_name' ]) . '" /></a> <a href="' . zid ( $r [ 0 ][ 'xchan_url' ]) . '" >' . $r [ 0 ][ 'xchan_name' ] . '</a>'
2020-10-14 05:02:22 +00:00
]);
2018-09-13 09:53:59 +00:00
$o = $title ;
2017-03-03 01:32:43 +00:00
$o .= $status_editor ;
}
else {
notice ( t ( 'Invalid channel.' ) . EOL );
2020-02-13 05:36:21 +00:00
goaway ( z_root () . '/stream' );
2017-03-03 01:32:43 +00:00
}
}
2016-04-19 03:38:38 +00:00
2019-04-16 04:55:59 +00:00
if ( x ( $category )) {
2016-04-19 03:38:38 +00:00
$sql_extra .= protect_sprintf ( term_query ( 'item' , $category , TERM_CATEGORY ));
}
2019-04-16 04:55:59 +00:00
if ( x ( $hashtags )) {
2016-04-19 03:38:38 +00:00
$sql_extra .= protect_sprintf ( term_query ( 'item' , $hashtags , TERM_HASHTAG , TERM_COMMUNITYTAG ));
}
2019-04-16 04:55:59 +00:00
if ( ! $update ) {
2016-04-19 03:38:38 +00:00
// 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
// way and also you aren't writing a comment (discovered in javascript).
2020-02-13 05:36:21 +00:00
$maxheight = get_pconfig ( local_channel (), 'system' , 'stream_divmore_height' );
2016-04-19 03:38:38 +00:00
if ( ! $maxheight )
$maxheight = 400 ;
2020-02-13 05:36:21 +00:00
$o .= '<div id="live-stream"></div>' . " \r \n " ;
2016-04-19 03:38:38 +00:00
$o .= " <script> var profile_uid = " . local_channel ()
2018-08-21 05:02:08 +00:00
. " ; var profile_page = " . App :: $pager [ 'page' ]
2016-04-19 03:38:38 +00:00
. " ; divmore_height = " . intval ( $maxheight ) . " ; </script> \r \n " ;
2019-04-16 04:55:59 +00:00
App :: $page [ 'htmlhead' ] .= replace_macros ( get_markup_template ( 'build_query.tpl' ), [
2016-04-19 03:38:38 +00:00
'$baseurl' => z_root (),
2020-02-13 05:36:21 +00:00
'$pgtype' => 'stream' ,
2016-04-19 03:38:38 +00:00
'$uid' => (( local_channel ()) ? local_channel () : '0' ),
'$gid' => (( $gid ) ? $gid : '0' ),
'$cid' => (( $cid ) ? $cid : '0' ),
2018-06-15 22:21:19 +00:00
'$cmin' => (( $cmin ) ? $cmin : '(-1)' ),
'$cmax' => (( $cmax ) ? $cmax : '(-1)' ),
2016-04-19 03:38:38 +00:00
'$star' => (( $star ) ? $star : '0' ),
'$liked' => (( $liked ) ? $liked : '0' ),
'$conv' => (( $conv ) ? $conv : '0' ),
'$spam' => (( $spam ) ? $spam : '0' ),
2017-08-24 19:47:01 +00:00
'$fh' => '0' ,
2019-06-19 02:21:31 +00:00
'$dm' => (( $dm ) ? $dm : '0' ),
2016-04-19 03:38:38 +00:00
'$nouveau' => (( $nouveau ) ? $nouveau : '0' ),
'$wall' => '0' ,
2020-11-30 00:38:45 +00:00
'$draft' => (( $draft ) ? $draft : '0' ),
2016-11-02 22:48:29 +00:00
'$static' => $static ,
2016-04-19 03:38:38 +00:00
'$list' => (( x ( $_REQUEST , 'list' )) ? intval ( $_REQUEST [ 'list' ]) : 0 ),
2018-08-21 05:02:08 +00:00
'$page' => (( App :: $pager [ 'page' ] != 1 ) ? App :: $pager [ 'page' ] : 1 ),
2019-03-19 02:19:04 +00:00
'$search' => (( $search ) ? urlencode ( $search ) : '' ),
'$xchan' => (( $xchan ) ? urlencode ( $xchan ) : '' ),
'$order' => (( $order ) ? urlencode ( $order ) : '' ),
'$file' => (( $file ) ? urlencode ( $file ) : '' ),
'$cats' => (( $category ) ? urlencode ( $category ) : '' ),
'$tags' => (( $hashtags ) ? urlencode ( $hashtags ) : '' ),
2016-04-19 03:38:38 +00:00
'$dend' => $datequery ,
'$mid' => '' ,
2019-03-19 02:19:04 +00:00
'$verb' => (( $verb ) ? urlencode ( $verb ) : '' ),
'$net' => (( $net ) ? urlencode ( $net ) : '' ),
2018-06-05 09:56:30 +00:00
'$dbegin' => $datequery2 ,
2019-03-19 02:19:04 +00:00
'$pf' => (( $pf ) ? intval ( $pf ) : '0' ),
2019-04-16 04:55:59 +00:00
]);
2016-04-19 03:38:38 +00:00
}
$sql_extra3 = '' ;
2019-04-16 04:55:59 +00:00
if ( $datequery ) {
2016-04-19 03:38:38 +00:00
$sql_extra3 .= protect_sprintf ( sprintf ( " AND item.created <= '%s' " , dbesc ( datetime_convert ( date_default_timezone_get (), '' , $datequery ))));
}
2019-04-16 04:55:59 +00:00
if ( $datequery2 ) {
2016-04-19 03:38:38 +00:00
$sql_extra3 .= protect_sprintf ( sprintf ( " AND item.created >= '%s' " , dbesc ( datetime_convert ( date_default_timezone_get (), '' , $datequery2 ))));
}
$sql_extra2 = (( $nouveau ) ? '' : " AND item.parent = item.id " );
$sql_extra3 = (( $nouveau ) ? '' : $sql_extra3 );
2019-04-16 04:55:59 +00:00
if ( x ( $_GET , 'search' )) {
2016-04-19 03:38:38 +00:00
$search = escape_tags ( $_GET [ 'search' ]);
2019-04-16 04:55:59 +00:00
if ( strpos ( $search , '#' ) === 0 ) {
2016-04-19 03:38:38 +00:00
$sql_extra .= term_query ( 'item' , substr ( $search , 1 ), TERM_HASHTAG , TERM_COMMUNITYTAG );
}
else {
2018-09-11 09:16:58 +00:00
$sql_extra .= sprintf ( " AND (item.body like '%s' OR item.title like '%s') " ,
dbesc ( protect_sprintf ( '%' . $search . '%' )),
2016-04-19 03:38:38 +00:00
dbesc ( protect_sprintf ( '%' . $search . '%' ))
);
}
}
2019-04-16 04:55:59 +00:00
if ( $verb ) {
2019-11-25 23:48:14 +00:00
// the presence of a leading dot in the verb determines
// whether to match the type of activity or the child object.
// The name 'verb' is a holdover from the earlier XML
// ActivityStreams specification.
2019-06-12 05:12:25 +00:00
if ( substr ( $verb , 0 , 1 ) === '.' ) {
$verb = substr ( $verb , 1 );
$sql_extra .= sprintf ( " AND item.obj_type like '%s' " ,
dbesc ( protect_sprintf ( '%' . $verb . '%' ))
);
}
else {
$sql_extra .= sprintf ( " AND item.verb like '%s' " ,
dbesc ( protect_sprintf ( '%' . $verb . '%' ))
);
}
2016-04-19 03:38:38 +00:00
}
2019-04-16 04:55:59 +00:00
if ( strlen ( $file )) {
2016-04-19 03:38:38 +00:00
$sql_extra .= term_query ( 'item' , $file , TERM_FILE );
}
2019-06-19 02:21:31 +00:00
if ( $dm ) {
$sql_extra .= " and item_private = 2 " ;
}
2019-04-16 04:55:59 +00:00
if ( $conv ) {
2020-06-03 04:19:17 +00:00
2018-02-04 19:42:40 +00:00
$item_thread_top = '' ;
2018-06-07 19:58:09 +00:00
2019-04-16 04:55:59 +00:00
if ( $nouveau ) {
2018-06-07 19:58:09 +00:00
$sql_extra .= " AND author_xchan = ' " . dbesc ( $channel [ 'channel_hash' ]) . " ' " ;
}
else {
2020-11-18 00:34:48 +00:00
$sql_extra .= sprintf ( " AND parent IN (SELECT distinct(parent) from item where ( author_xchan = '%s' or item_mentionsme = 1 ) and item_deleted = 0 ) " ,
2018-06-07 19:58:09 +00:00
dbesc ( protect_sprintf ( $channel [ 'channel_hash' ]))
);
}
2016-04-19 03:38:38 +00:00
}
2019-04-16 04:55:59 +00:00
if ( $update && ! $load ) {
2016-04-19 03:38:38 +00:00
// only setup pagination on initial page view
$pager_sql = '' ;
}
else {
$itemspage = get_pconfig ( local_channel (), 'system' , 'itemspage' );
2018-08-21 05:02:08 +00:00
App :: set_pager_itemspage ((( intval ( $itemspage )) ? $itemspage : 20 ));
$pager_sql = sprintf ( " LIMIT %d OFFSET %d " , intval ( App :: $pager [ 'itemspage' ]), intval ( App :: $pager [ 'start' ]));
2016-04-19 03:38:38 +00:00
}
2018-06-15 09:02:03 +00:00
// cmin and cmax are both -1 when the affinity tool is disabled
2019-04-16 04:55:59 +00:00
if (( $cmin != ( - 1 )) || ( $cmax != ( - 1 ))) {
2016-04-19 03:38:38 +00:00
// Not everybody who shows up in the network stream will be in your address book.
// By default those that aren't are assumed to have closeness = 99; but this isn't
// recorded anywhere. So if cmax is 99, we'll open the search up to anybody in
// the stream with a NULL address book entry.
$sql_nets .= " AND " ;
2019-04-16 04:55:59 +00:00
if ( $cmax == 99 )
2016-04-19 03:38:38 +00:00
$sql_nets .= " ( " ;
$sql_nets .= " ( abook.abook_closeness >= " . intval ( $cmin ) . " " ;
$sql_nets .= " AND abook.abook_closeness <= " . intval ( $cmax ) . " ) " ;
2019-04-16 04:55:59 +00:00
if ( $cmax == 99 )
2016-04-19 03:38:38 +00:00
$sql_nets .= " OR abook.abook_closeness IS NULL ) " ;
}
2017-11-01 09:53:12 +00:00
$net_query = (( $net ) ? " left join xchan on xchan_hash = author_xchan " : '' );
$net_query2 = (( $net ) ? " and xchan_network = ' " . protect_sprintf ( dbesc ( $net )) . " ' " : '' );
2016-04-19 03:38:38 +00:00
$abook_uids = " and abook.abook_channel = " . local_channel () . " " ;
2017-08-24 19:47:01 +00:00
$uids = " and item.uid = " . local_channel () . " " ;
2016-04-19 03:38:38 +00:00
2020-02-13 05:36:21 +00:00
if ( get_pconfig ( local_channel (), 'system' , 'stream_list_mode' ))
2016-04-19 03:38:38 +00:00
$page_mode = 'list' ;
else
$page_mode = 'client' ;
$simple_update = (( $update ) ? " and item_unseen = 1 " : '' );
2016-11-02 22:48:29 +00:00
2021-03-11 05:31:13 +00:00
$parents_str = '' ;
$update_unseen = '' ;
$items = [];
2016-04-19 03:38:38 +00:00
// This fixes a very subtle bug so I'd better explain it. You wake up in the morning or return after a day
2021-05-21 01:01:42 +00:00
// or three and look at your stream page - after opening up your browser. The first page loads just as it
2016-04-19 03:38:38 +00:00
// should. All of a sudden a few seconds later, page 2 will get inserted at the beginning of the page
// (before the page 1 content). The update code is actually doing just what it's supposed
// to, it's fetching posts that have the ITEM_UNSEEN bit set. But the reason that page 2 content is being
// returned in an UPDATE is because you hadn't gotten that far yet - you're still on page 1 and everything
// that we loaded for page 1 is now marked as seen. But the stuff on page 2 hasn't been. So... it's being
// treated as "new fresh" content because it is unseen. We need to distinguish it somehow from content
// which "arrived as you were reading page 1". We're going to do this
// by storing in your session the current UTC time whenever you LOAD a network page, and only UPDATE items
// which are both ITEM_UNSEEN and have "changed" since that time. Cross fingers...
2019-04-16 04:55:59 +00:00
if ( $update && $_SESSION [ 'loadtime' ])
2016-04-19 03:38:38 +00:00
$simple_update = " AND (( item_unseen = 1 AND item.changed > ' " . datetime_convert ( 'UTC' , 'UTC' , $_SESSION [ 'loadtime' ]) . " ' ) OR item.changed > ' " . datetime_convert ( 'UTC' , 'UTC' , $_SESSION [ 'loadtime' ]) . " ' ) " ;
2019-04-16 04:55:59 +00:00
if ( $load )
2016-04-19 03:38:38 +00:00
$simple_update = '' ;
2016-11-02 22:48:29 +00:00
2019-04-16 04:55:59 +00:00
if ( $static && $simple_update )
2016-11-02 22:48:29 +00:00
$simple_update .= " and item_thread_top = 0 and author_xchan = ' " . protect_sprintf ( get_observer_hash ()) . " ' " ;
2016-04-19 03:38:38 +00:00
2019-04-16 04:55:59 +00:00
if ( $nouveau && $load ) {
2016-04-19 03:38:38 +00:00
// "New Item View" - show all items unthreaded in reverse created date order
2018-07-04 08:55:38 +00:00
$items = q ( " SELECT item.*, item.id AS item_id, created FROM item
2016-04-19 03:38:38 +00:00
left join abook on ( item . owner_xchan = abook . abook_xchan $abook_uids )
2017-11-01 09:53:12 +00:00
$net_query
2016-04-19 03:38:38 +00:00
WHERE true $uids $item_normal
and ( abook . abook_blocked = 0 or abook . abook_flags is null )
$simple_update
2018-04-15 08:15:49 +00:00
$sql_extra $sql_options $sql_nets
2017-11-01 09:53:12 +00:00
$net_query2
2018-07-04 08:55:38 +00:00
ORDER BY item . created DESC $pager_sql "
2016-04-19 03:38:38 +00:00
);
2018-06-01 04:05:09 +00:00
2016-04-19 03:38:38 +00:00
xchan_query ( $items );
$items = fetch_post_tags ( $items , true );
}
2019-04-16 04:55:59 +00:00
elseif ( $update ) {
2016-04-19 03:38:38 +00:00
// Normal conversation view
2020-06-03 03:36:21 +00:00
2016-04-19 03:38:38 +00:00
if ( $order === 'post' )
2018-06-07 19:58:09 +00:00
$ordering = " created " ;
2016-04-19 03:38:38 +00:00
else
2021-05-21 01:17:28 +00:00
$ordering = " changed " ;
2021-04-06 00:57:39 +00:00
2019-04-16 04:55:59 +00:00
if ( $load ) {
2016-04-19 03:38:38 +00:00
// Fetch a page full of parent items for this page
2018-04-16 09:42:13 +00:00
$r = q ( " SELECT item.parent AS item_id FROM item
2016-04-19 03:38:38 +00:00
left join abook on ( item . owner_xchan = abook . abook_xchan $abook_uids )
2017-11-01 09:53:12 +00:00
$net_query
2018-02-04 19:42:40 +00:00
WHERE true $uids $item_thread_top $item_normal
AND item . mid = item . parent_mid
2016-04-19 03:38:38 +00:00
and ( abook . abook_blocked = 0 or abook . abook_flags is null )
2018-04-15 08:15:49 +00:00
$sql_extra3 $sql_extra $sql_options $sql_nets
2017-11-01 09:53:12 +00:00
$net_query2
2016-04-19 03:38:38 +00:00
ORDER BY $ordering DESC $pager_sql "
);
}
else {
2017-09-10 23:10:56 +00:00
2016-04-19 03:38:38 +00:00
// this is an update
$r = q ( " SELECT item.parent AS item_id FROM item
left join abook on ( item . owner_xchan = abook . abook_xchan $abook_uids )
2017-11-01 09:53:12 +00:00
$net_query
2017-09-03 19:33:07 +00:00
WHERE true $uids $item_normal_update $simple_update
2016-04-19 03:38:38 +00:00
and ( abook . abook_blocked = 0 or abook . abook_flags is null )
2018-04-15 08:15:49 +00:00
$sql_extra3 $sql_extra $sql_options $sql_nets $net_query2 "
2016-04-19 03:38:38 +00:00
);
$_SESSION [ 'loadtime' ] = datetime_convert ();
}
2016-05-09 08:12:24 +00:00
2019-04-16 04:55:59 +00:00
if ( $r ) {
2016-04-19 03:38:38 +00:00
$parents_str = ids_to_querystr ( $r , 'item_id' );
$items = q ( " SELECT item.*, item.id AS item_id FROM item
WHERE true $uids $item_normal
AND item . parent IN ( % s )
$sql_extra " ,
dbesc ( $parents_str )
);
2017-08-24 19:47:01 +00:00
xchan_query ( $items , true );
2016-04-19 03:38:38 +00:00
$items = fetch_post_tags ( $items , true );
$items = conv_sort ( $items , $ordering );
2018-05-30 04:08:52 +00:00
2016-04-19 03:38:38 +00:00
}
2017-09-10 23:10:56 +00:00
2019-04-16 04:55:59 +00:00
if ( $page_mode === 'list' ) {
2016-04-19 03:38:38 +00:00
/**
* in " list mode " , only mark the parent item and any like activities as " seen " .
* We won ' t distinguish between comment likes and post likes . The important thing
* is that the number of unseen comments will be accurate . The SQL to separate the
* comment likes could also get somewhat hairy .
*/
2019-04-16 04:55:59 +00:00
if ( $parents_str ) {
2016-04-19 03:38:38 +00:00
$update_unseen = " AND ( id IN ( " . dbesc ( $parents_str ) . " ) " ;
$update_unseen .= " OR ( parent IN ( " . dbesc ( $parents_str ) . " ) AND verb in ( ' " . dbesc ( ACTIVITY_LIKE ) . " ',' " . dbesc ( ACTIVITY_DISLIKE ) . " ' ))) " ;
}
}
else {
2019-04-16 04:55:59 +00:00
if ( $parents_str ) {
2017-11-03 12:49:58 +00:00
$update_unseen = " AND parent IN ( " . dbesc ( $parents_str ) . " ) " ;
2016-04-19 03:38:38 +00:00
}
}
}
2021-03-12 00:03:45 +00:00
if ( $update_unseen && ( ! ( isset ( $_SESSION [ 'sudo' ]) && $_SESSION [ 'sudo' ]))) {
2017-08-02 05:25:55 +00:00
$x = [ 'channel_id' => local_channel (), 'update' => 'unset' ];
call_hooks ( 'update_unseen' , $x );
2019-04-16 04:55:59 +00:00
if ( $x [ 'update' ] === 'unset' || intval ( $x [ 'update' ])) {
2017-08-02 05:25:55 +00:00
$r = q ( " UPDATE item SET item_unseen = 0 WHERE item_unseen = 1 AND uid = %d $update_unseen " ,
intval ( local_channel ())
);
}
}
2016-04-19 03:38:38 +00:00
2020-02-13 05:36:21 +00:00
$mode = (( $nouveau ) ? 'stream-new' : 'stream' );
2018-05-30 20:40:22 +00:00
2019-04-16 04:55:59 +00:00
if ( $search ) {
2018-05-30 20:40:22 +00:00
$mode = 'search' ;
2019-04-16 04:55:59 +00:00
}
2017-06-20 22:53:01 +00:00
$o .= conversation ( $items , $mode , $update , $page_mode );
2016-04-19 03:38:38 +00:00
2019-04-16 04:55:59 +00:00
if (( $items ) && ( ! $update )) {
2018-04-18 06:36:35 +00:00
$o .= alt_pager ( count ( $items ));
2019-04-16 04:55:59 +00:00
}
2016-04-19 03:38:38 +00:00
return $o ;
}
}