2012-10-30 00:14:02 +00:00
< ? php
2016-04-16 05:36:07 +00:00
2016-10-01 22:41:25 +00:00
namespace Zotlabs\Module ;
2012-10-30 00:14:02 +00:00
2018-06-01 02:42:13 +00:00
use Zotlabs\Lib\Libzot ;
2018-06-26 03:55:53 +00:00
use Zotlabs\Lib\Activity ;
2019-04-17 23:54:06 +00:00
use Zotlabs\Lib\Libprofile ;
2018-06-26 03:55:53 +00:00
use Zotlabs\Lib\ActivityStreams ;
2018-08-23 06:04:37 +00:00
use Zotlabs\Lib\LDSignatures ;
2018-12-17 04:37:43 +00:00
use Zotlabs\Lib\Crypto ;
2018-06-20 02:33:50 +00:00
use Zotlabs\Web\HTTPSig ;
2018-06-01 02:42:13 +00:00
2018-08-21 05:02:08 +00:00
use App ;
use Zotlabs\Web\Controller ;
use Zotlabs\Lib\PermissionDescription ;
2013-12-04 08:19:29 +00:00
require_once ( 'include/items.php' );
require_once ( 'include/security.php' );
require_once ( 'include/conversation.php' );
require_once ( 'include/acl_selectors.php' );
2018-08-21 05:02:08 +00:00
2013-12-04 08:19:29 +00:00
2016-10-01 22:41:25 +00:00
/**
* @ brief Channel Controller
*
*/
2018-08-21 05:02:08 +00:00
class Channel extends Controller {
2013-12-04 08:19:29 +00:00
2016-05-23 00:52:30 +00:00
function init () {
2019-12-24 20:26:50 +00:00
if ( in_array ( substr ( $_GET [ 'search' ], 0 , 1 ),[ '@' , '!' , '?' ])) {
2018-05-30 20:55:28 +00:00
goaway ( 'search' . '?f=&search=' . $_GET [ 'search' ]);
2019-12-24 20:26:50 +00:00
}
2018-05-30 20:55:28 +00:00
2016-05-23 00:52:30 +00:00
$which = null ;
2019-05-23 23:37:56 +00:00
if ( argc () > 1 ) {
2016-05-23 00:52:30 +00:00
$which = argv ( 1 );
2019-05-23 23:37:56 +00:00
}
if ( ! $which ) {
if ( local_channel ()) {
2018-08-21 00:22:49 +00:00
$channel = App :: get_channel ();
2019-05-23 23:37:56 +00:00
if ( $channel && $channel [ 'channel_address' ]) {
2018-09-14 09:16:42 +00:00
$which = $channel [ 'channel_address' ];
}
2016-05-23 00:52:30 +00:00
}
}
2019-05-23 23:37:56 +00:00
if ( ! $which ) {
2016-05-23 00:52:30 +00:00
notice ( t ( 'You must be logged in to see this page.' ) . EOL );
return ;
2013-08-04 08:04:05 +00:00
}
2012-10-30 00:14:02 +00:00
2016-05-23 00:52:30 +00:00
$profile = 0 ;
2018-08-21 00:22:49 +00:00
$channel = App :: get_channel ();
2012-10-30 00:14:02 +00:00
2019-05-23 23:37:56 +00:00
if (( local_channel ()) && ( argc () > 2 ) && ( argv ( 2 ) === 'view' )) {
2016-05-23 00:52:30 +00:00
$which = $channel [ 'channel_address' ];
2016-10-01 22:41:25 +00:00
$profile = argv ( 1 );
2016-05-23 00:52:30 +00:00
}
2012-10-30 00:14:02 +00:00
2018-06-26 03:55:53 +00:00
$channel = channelx_by_nick ( $which );
2019-05-23 23:37:56 +00:00
if ( ! $channel ) {
2018-06-26 03:55:53 +00:00
http_status_exit ( 404 , 'Not found' );
}
2017-02-22 02:58:51 +00:00
head_add_link ( [
'rel' => 'alternate' ,
'type' => 'application/atom+xml' ,
'title' => t ( 'Posts and comments' ),
'href' => z_root () . '/feed/' . $which
]);
head_add_link ( [
'rel' => 'alternate' ,
'type' => 'application/atom+xml' ,
'title' => t ( 'Only posts' ),
'href' => z_root () . '/feed/' . $which . '?f=&top=1'
]);
2015-03-15 23:48:45 +00:00
2019-06-29 23:37:30 +00:00
2018-04-23 01:51:46 +00:00
// handle zot6 channel discovery
2018-06-01 02:42:13 +00:00
if ( Libzot :: is_zot_request ()) {
2018-06-26 03:55:53 +00:00
2018-10-10 04:08:57 +00:00
$sigdata = HTTPSig :: verify ( file_get_contents ( 'php://input' ));
2018-04-23 01:51:46 +00:00
2018-05-24 04:48:19 +00:00
if ( $sigdata && $sigdata [ 'signer' ] && $sigdata [ 'header_valid' ]) {
2018-06-04 04:23:34 +00:00
$data = json_encode ( Libzot :: zotinfo ([ 'address' => $channel [ 'channel_address' ], 'target_url' => $sigdata [ 'signer' ] ]));
2018-05-24 04:48:19 +00:00
$s = q ( " select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1 " ,
dbesc ( $sigdata [ 'signer' ])
);
2018-05-29 02:42:40 +00:00
2019-12-23 19:54:55 +00:00
if ( $s && $s [ 0 ][ 'hubloc_sitekey' ] && $s [ 0 ][ 'site_crypto' ]) {
2018-12-17 04:37:43 +00:00
$data = json_encode ( Crypto :: encapsulate ( $data , $s [ 0 ][ 'hubloc_sitekey' ], Libzot :: best_algorithm ( $s [ 0 ][ 'site_crypto' ])));
2018-05-24 04:48:19 +00:00
}
}
else {
2018-06-01 02:42:13 +00:00
$data = json_encode ( Libzot :: zotinfo ([ 'address' => $channel [ 'channel_address' ] ]));
2018-05-24 04:48:19 +00:00
}
2018-04-23 01:51:46 +00:00
2018-10-11 00:58:51 +00:00
$headers = [
'Content-Type' => 'application/x-zot+json' ,
'Digest' => HTTPSig :: generate_digest_header ( $data ),
'(request-target)' => strtolower ( $_SERVER [ 'REQUEST_METHOD' ]) . ' ' . $_SERVER [ 'REQUEST_URI' ]
2018-11-07 23:31:11 +00:00
];
2018-06-20 02:33:50 +00:00
$h = HTTPSig :: create_sig ( $headers , $channel [ 'channel_prvkey' ], channel_url ( $channel ));
HTTPSig :: set_headers ( $h );
2018-05-29 02:42:40 +00:00
echo $data ;
2018-04-23 01:51:46 +00:00
killme ();
}
2018-08-06 04:31:25 +00:00
if ( ActivityStreams :: is_as_request ()) {
2018-06-26 03:55:53 +00:00
$x = array_merge ([ '@context' => [
ACTIVITYSTREAMS_JSONLD_REV ,
2019-05-13 05:29:16 +00:00
'https://w3id.org/security/v1' ,
z_root () . ZOT_APSCHEMA_REV
2019-09-10 04:03:33 +00:00
]], Activity :: encode_person ( $channel , true , true ));
2018-06-26 03:55:53 +00:00
2018-08-23 06:04:37 +00:00
$headers = [];
$headers [ 'Content-Type' ] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ;
2018-09-26 03:41:06 +00:00
$x [ 'signature' ] = LDSignatures :: sign ( $x , $channel );
2018-08-23 06:04:37 +00:00
$ret = json_encode ( $x , JSON_UNESCAPED_SLASHES );
2019-11-08 20:16:29 +00:00
$headers [ 'Date' ] = datetime_convert ( 'UTC' , 'UTC' , 'now' , 'D, d M Y H:i:s \\G\\M\\T' );
2018-08-23 06:04:37 +00:00
$headers [ 'Digest' ] = HTTPSig :: generate_digest_header ( $ret );
2018-10-11 00:58:51 +00:00
$headers [ '(request-target)' ] = strtolower ( $_SERVER [ 'REQUEST_METHOD' ]) . ' ' . $_SERVER [ 'REQUEST_URI' ];
2018-09-26 03:41:06 +00:00
$h = HTTPSig :: create_sig ( $headers , $channel [ 'channel_prvkey' ], channel_url ( $channel ));
2018-08-23 06:04:37 +00:00
HTTPSig :: set_headers ( $h );
echo $ret ;
killme ();
2018-06-26 03:55:53 +00:00
2018-08-06 00:25:43 +00:00
}
2018-06-26 03:55:53 +00:00
2019-04-17 23:54:06 +00:00
// Run Libprofile::load() here to make sure the theme is set before
2018-05-24 04:48:19 +00:00
// we start loading content
2019-04-17 23:54:06 +00:00
Libprofile :: load ( $which , $profile );
2018-05-24 04:48:19 +00:00
2019-06-30 00:54:48 +00:00
App :: $meta -> set ( 'og:title' , $channel [ 'channel_name' ]);
App :: $meta -> set ( 'og:image' , $channel [ 'xchan_photo_l' ]);
App :: $meta -> set ( 'og:type' , 'webpage' );
App :: $meta -> set ( 'og:url' , channel_url ( $channel ));
2019-06-29 23:37:30 +00:00
if ( App :: $profile [ 'about' ] && perm_is_allowed ( $channel [ 'channel_id' ], get_observer_hash (), 'view_profile' )) {
2019-06-30 00:54:48 +00:00
App :: $meta -> set ( 'og:description' , App :: $profile [ 'about' ]);
2019-06-29 23:37:30 +00:00
}
else {
2019-06-30 00:54:48 +00:00
App :: $meta -> set ( 'og:description' , sprintf ( t ( 'This is the home page of %s.' ), $channel [ 'channel_name' ]));
2019-06-29 23:37:30 +00:00
}
2016-05-23 00:52:30 +00:00
}
2013-01-06 21:42:51 +00:00
2016-05-23 00:52:30 +00:00
function get ( $update = 0 , $load = false ) {
2012-10-30 00:14:02 +00:00
2020-07-22 03:01:37 +00:00
2018-09-07 12:23:16 +00:00
$noscript_content = get_config ( 'system' , 'noscript_content' , '1' );
2016-05-23 00:52:30 +00:00
if ( $load )
$_SESSION [ 'loadtime' ] = datetime_convert ();
2015-03-21 23:46:28 +00:00
2016-05-23 00:52:30 +00:00
$category = $datequery = $datequery2 = '' ;
2012-10-30 00:14:02 +00:00
2016-05-23 00:52:30 +00:00
$mid = (( x ( $_REQUEST , 'mid' )) ? $_REQUEST [ 'mid' ] : '' );
2018-05-24 04:48:19 +00:00
if ( $mid && strpos ( $mid , 'b64.' ) === 0 ) {
$decoded = @ base64url_decode ( substr ( $mid , 4 ));
if ( $decoded ) {
$mid = $decoded ;
}
}
2014-01-08 15:03:59 +00:00
2016-05-23 00:52:30 +00:00
$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' ]) : '' );
2012-12-10 02:07:36 +00:00
2016-10-01 22:41:25 +00:00
if ( observer_prohibited ( true )) {
2012-10-30 00:14:02 +00:00
return login ();
2016-05-23 00:52:30 +00:00
}
2012-10-30 00:14:02 +00:00
2016-05-23 00:52:30 +00:00
$category = (( x ( $_REQUEST , 'cat' )) ? $_REQUEST [ 'cat' ] : '' );
$hashtags = (( x ( $_REQUEST , 'tag' )) ? $_REQUEST [ 'tag' ] : '' );
2018-05-30 00:35:44 +00:00
$order = (( x ( $_GET , 'order' )) ? notags ( $_GET [ 'order' ]) : 'post' );
2016-11-02 22:48:29 +00:00
$static = (( array_key_exists ( 'static' , $_REQUEST )) ? intval ( $_REQUEST [ 'static' ]) : 0 );
2018-05-30 20:40:22 +00:00
$search = (( x ( $_GET , 'search' )) ? $_GET [ 'search' ] : EMPTY_STR );
2013-09-04 03:58:46 +00:00
2016-05-23 00:52:30 +00:00
$groups = array ();
2012-10-30 00:14:02 +00:00
2016-05-23 00:52:30 +00:00
$o = '' ;
2012-10-30 00:14:02 +00:00
2016-05-23 00:52:30 +00:00
if ( $update ) {
// Ensure we've got a profile owner if updating.
2018-08-21 00:22:49 +00:00
App :: $profile [ 'profile_uid' ] = App :: $profile_uid = $update ;
2016-05-23 00:52:30 +00:00
}
2012-10-30 00:14:02 +00:00
2018-08-21 00:22:49 +00:00
$is_owner = ((( local_channel ()) && ( App :: $profile [ 'profile_uid' ] == local_channel ())) ? true : false );
2013-01-06 00:37:32 +00:00
2018-08-21 00:22:49 +00:00
$channel = App :: get_channel ();
$observer = App :: get_observer ();
2016-05-23 00:52:30 +00:00
$ob_hash = (( $observer ) ? $observer [ 'xchan_hash' ] : '' );
2012-10-30 00:14:02 +00:00
2018-08-21 00:22:49 +00:00
$perms = get_all_perms ( App :: $profile [ 'profile_uid' ], $ob_hash );
2012-10-30 00:14:02 +00:00
2020-07-22 03:01:37 +00:00
2016-05-23 00:52:30 +00:00
if ( ! $perms [ 'view_stream' ]) {
2013-10-04 14:57:48 +00:00
// We may want to make the target of this redirect configurable
if ( $perms [ 'view_profile' ]) {
notice ( t ( 'Insufficient permissions. Request redirected to profile page.' ) . EOL );
2018-08-21 00:22:49 +00:00
goaway ( z_root () . " /profile/ " . App :: $profile [ 'channel_address' ]);
2013-10-04 14:57:48 +00:00
}
2016-05-23 00:52:30 +00:00
notice ( t ( 'Permission denied.' ) . EOL );
return ;
}
2012-10-30 00:14:02 +00:00
2012-12-10 02:07:36 +00:00
2016-05-23 00:52:30 +00:00
if ( ! $update ) {
2012-10-30 00:14:02 +00:00
2017-10-10 14:51:35 +00:00
nav_set_selected ( 'Channel Home' );
2018-08-21 00:22:49 +00:00
$static = channel_manual_conv_update ( App :: $profile [ 'profile_uid' ]);
2016-11-02 22:48:29 +00:00
2018-05-30 20:40:22 +00:00
// search terms header
if ( $search ) {
$o .= replace_macros ( get_markup_template ( " section_title.tpl " ), array (
'$title' => t ( 'Search Results For:' ) . ' ' . htmlspecialchars ( $search , ENT_COMPAT , 'UTF-8' )
));
}
2012-10-30 00:14:02 +00:00
2020-07-22 11:57:26 +00:00
$role = get_pconfig ( App :: $profile [ 'profile_uid' ], 'system' , 'permissions_role' );
if ( $role === 'social_restricted' && ( ! $ob_hash )) {
// provide warning that content is probably hidden ?
}
2016-05-23 00:52:30 +00:00
if ( $channel && $is_owner ) {
$channel_acl = array (
2016-10-01 22:41:25 +00:00
'allow_cid' => $channel [ 'channel_allow_cid' ],
'allow_gid' => $channel [ 'channel_allow_gid' ],
'deny_cid' => $channel [ 'channel_deny_cid' ],
2016-05-23 00:52:30 +00:00
'deny_gid' => $channel [ 'channel_deny_gid' ]
);
}
2016-09-09 05:33:39 +00:00
else {
$channel_acl = [ 'allow_cid' => '' , 'allow_gid' => '' , 'deny_cid' => '' , 'deny_gid' => '' ];
}
2016-05-23 00:52:30 +00:00
if ( $perms [ 'post_wall' ]) {
$x = array (
'is_owner' => $is_owner ,
2018-08-21 00:22:49 +00:00
'allow_location' => ((( $is_owner || $observer ) && ( intval ( get_pconfig ( App :: $profile [ 'profile_uid' ], 'system' , 'use_browser_location' )))) ? true : false ),
'default_location' => (( $is_owner ) ? App :: $profile [ 'channel_location' ] : '' ),
'nickname' => App :: $profile [ 'channel_address' ],
'lockstate' => ((( strlen ( App :: $profile [ 'channel_allow_cid' ])) || ( strlen ( App :: $profile [ 'channel_allow_gid' ])) || ( strlen ( App :: $profile [ 'channel_deny_cid' ])) || ( strlen ( App :: $profile [ 'channel_deny_gid' ]))) ? 'lock' : 'unlock' ),
2018-08-21 05:02:08 +00:00
'acl' => (( $is_owner ) ? populate_acl ( $channel_acl , true , PermissionDescription :: fromGlobalPermission ( 'view_stream' ), get_post_aclDialogDescription (), 'acl_dialog_post' ) : '' ),
2016-09-09 05:33:39 +00:00
'permissions' => $channel_acl ,
2016-05-23 00:52:30 +00:00
'showacl' => (( $is_owner ) ? 'yes' : '' ),
'bang' => '' ,
'visitor' => (( $is_owner || $observer ) ? true : false ),
2018-08-21 00:22:49 +00:00
'profile_uid' => App :: $profile [ 'profile_uid' ],
2016-05-23 00:52:30 +00:00
'editor_autocomplete' => true ,
'bbco_autocomplete' => 'bbcode' ,
2016-08-21 13:43:03 +00:00
'bbcode' => true ,
2018-05-21 07:13:14 +00:00
'jotnets' => true ,
'reset' => t ( 'Reset form' )
2016-10-01 22:41:25 +00:00
);
2016-05-23 00:52:30 +00:00
2016-10-01 22:41:25 +00:00
$o .= status_editor ( $a , $x );
2016-05-23 00:52:30 +00:00
}
2012-10-30 00:14:02 +00:00
2019-12-03 05:08:06 +00:00
if ( ! $mid && ! $search ) {
$obj = new \Zotlabs\Widget\Pinned ;
$o .= $obj -> widget ([]);
}
2016-05-23 00:52:30 +00:00
}
2012-10-30 00:14:02 +00:00
2016-05-23 00:52:30 +00:00
/**
2019-05-23 23:37:56 +00:00
* Get permissions SQL
2016-05-23 00:52:30 +00:00
*/
2020-05-03 22:22:37 +00:00
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0
and item . item_unpublished = 0 and item . item_pending_remove = 0
and item . item_blocked = 0 " ;
if ( ! $is_owner )
$item_normal .= " and item.item_delayed = 0 " ;
2017-09-03 19:33:07 +00:00
$item_normal_update = item_normal_update ();
2018-08-21 00:22:49 +00:00
$sql_extra = item_permissions_sql ( App :: $profile [ 'profile_uid' ]);
2012-10-30 00:14:02 +00:00
2019-05-23 23:37:56 +00:00
if ( get_pconfig ( App :: $profile [ 'profile_uid' ], 'system' , 'channel_list_mode' ) && ( ! $mid )) {
2016-05-23 00:52:30 +00:00
$page_mode = 'list' ;
2019-05-23 23:37:56 +00:00
}
else {
2016-05-23 00:52:30 +00:00
$page_mode = 'client' ;
2019-05-23 23:37:56 +00:00
}
2018-08-21 00:22:49 +00:00
$abook_uids = " and abook.abook_channel = " . intval ( App :: $profile [ 'profile_uid' ]) . " " ;
2015-03-19 02:06:05 +00:00
2016-05-23 00:52:30 +00:00
$simple_update = (( $update ) ? " AND item_unseen = 1 " : '' );
2016-02-01 22:52:08 +00:00
2019-05-23 23:37:56 +00:00
if ( $search ) {
2018-05-30 20:40:22 +00:00
$search = escape_tags ( $search );
2018-05-09 03:12:49 +00:00
if ( strpos ( $search , '#' ) === 0 ) {
2018-05-30 20:40:22 +00:00
$sql_extra .= term_query ( 'item' , substr ( $search , 1 ), TERM_HASHTAG , TERM_COMMUNITYTAG );
2018-05-09 03:12:49 +00:00
}
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 . '%' )),
2018-05-09 03:12:49 +00:00
dbesc ( protect_sprintf ( '%' . $search . '%' ))
);
}
}
2017-08-24 03:47:08 +00:00
head_add_link ([
'rel' => 'alternate' ,
'type' => 'application/json+oembed' ,
2018-08-21 00:22:49 +00:00
'href' => z_root () . '/oep?f=&url=' . urlencode ( z_root () . '/' . App :: $query_string ),
2017-08-24 03:47:08 +00:00
'title' => 'oembed'
]);
2016-10-01 22:41:25 +00:00
2019-05-23 23:37:56 +00:00
if ( $update && $_SESSION [ 'loadtime' ]) {
2016-05-23 00:52:30 +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-05-23 23:37:56 +00:00
}
if ( $load ) {
2016-05-23 00:52:30 +00:00
$simple_update = '' ;
2019-05-23 23:37:56 +00:00
}
if ( $static && $simple_update ) {
2017-09-10 23:10:56 +00:00
$simple_update .= " and author_xchan = ' " . protect_sprintf ( get_observer_hash ()) . " ' " ;
2019-05-23 23:37:56 +00:00
}
if (( $update ) && ( ! $load )) {
2016-11-02 22:48:29 +00:00
2019-05-23 23:37:56 +00:00
if ( $mid ) {
2017-09-03 19:33:07 +00:00
$r = q ( " SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal_update
2016-09-28 09:04:02 +00:00
AND item_wall = 1 $simple_update $sql_extra limit 1 " ,
2016-05-23 00:52:30 +00:00
dbesc ( $mid . '%' ),
2018-08-21 00:22:49 +00:00
intval ( App :: $profile [ 'profile_uid' ])
2014-01-08 15:03:59 +00:00
);
2016-09-28 09:04:02 +00:00
$_SESSION [ 'loadtime' ] = datetime_convert ();
2016-10-01 22:41:25 +00:00
}
2016-05-23 00:52:30 +00:00
else {
2018-04-07 23:54:49 +00:00
$r = q ( " SELECT parent AS item_id from item
2016-05-23 00:52:30 +00:00
left join abook on ( item . owner_xchan = abook . abook_xchan $abook_uids )
2017-09-03 19:33:07 +00:00
WHERE uid = % d $item_normal_update
2016-05-23 00:52:30 +00:00
AND item_wall = 1 $simple_update
AND ( abook . abook_blocked = 0 or abook . abook_flags is null )
$sql_extra
ORDER BY created DESC " ,
2018-08-21 00:22:49 +00:00
intval ( App :: $profile [ 'profile_uid' ])
2014-01-08 15:03:59 +00:00
);
2016-05-23 00:52:30 +00:00
$_SESSION [ 'loadtime' ] = datetime_convert ();
2014-01-08 15:03:59 +00:00
}
2016-05-23 00:52:30 +00:00
2012-12-16 08:44:38 +00:00
}
else {
2012-10-30 00:14:02 +00:00
2019-05-23 23:37:56 +00:00
if ( x ( $category )) {
2018-08-21 00:22:49 +00:00
$sql_extra2 .= protect_sprintf ( term_item_parent_query ( App :: $profile [ 'profile_uid' ], 'item' , $category , TERM_CATEGORY ));
2016-05-23 00:52:30 +00:00
}
2019-05-23 23:37:56 +00:00
if ( x ( $hashtags )) {
2018-08-21 00:22:49 +00:00
$sql_extra2 .= protect_sprintf ( term_item_parent_query ( App :: $profile [ 'profile_uid' ], 'item' , $hashtags , TERM_HASHTAG , TERM_COMMUNITYTAG ));
2016-05-23 00:52:30 +00:00
}
2012-10-30 00:14:02 +00:00
2019-05-23 23:37:56 +00:00
if ( $datequery ) {
2016-05-23 00:52:30 +00:00
$sql_extra2 .= protect_sprintf ( sprintf ( " AND item.created <= '%s' " , dbesc ( datetime_convert ( date_default_timezone_get (), '' , $datequery ))));
2018-05-30 00:35:44 +00:00
$order = 'post' ;
2016-05-23 00:52:30 +00:00
}
2019-05-23 23:37:56 +00:00
if ( $datequery2 ) {
2016-05-23 00:52:30 +00:00
$sql_extra2 .= protect_sprintf ( sprintf ( " AND item.created >= '%s' " , dbesc ( datetime_convert ( date_default_timezone_get (), '' , $datequery2 ))));
}
2019-05-23 23:37:56 +00:00
if ( $datequery || $datequery2 ) {
2018-05-10 01:20:28 +00:00
$sql_extra2 .= " and item.item_thread_top != 0 " ;
}
2018-05-09 03:12:49 +00:00
2019-05-23 23:37:56 +00:00
if ( $order === 'post' ) {
2018-05-30 00:35:44 +00:00
$ordering = " created " ;
2019-05-23 23:37:56 +00:00
}
else {
2018-05-30 00:35:44 +00:00
$ordering = " commented " ;
2019-05-23 23:37:56 +00:00
}
2018-05-30 00:35:44 +00:00
2016-05-23 00:52:30 +00:00
$itemspage = get_pconfig ( local_channel (), 'system' , 'itemspage' );
2018-08-21 00:22:49 +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-05-23 00:52:30 +00:00
2019-05-23 23:37:56 +00:00
if ( $noscript_content || $load ) {
if ( $mid ) {
2018-02-04 19:42:40 +00:00
$r = q ( " SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
2016-05-23 00:52:30 +00:00
AND item_wall = 1 $sql_extra limit 1 " ,
2017-07-19 00:02:50 +00:00
dbesc ( $mid . '%' ),
2018-08-21 00:22:49 +00:00
intval ( App :: $profile [ 'profile_uid' ])
2016-05-23 00:52:30 +00:00
);
if ( ! $r ) {
notice ( t ( 'Permission denied.' ) . EOL );
}
2016-10-01 22:41:25 +00:00
}
2016-05-23 00:52:30 +00:00
else {
2018-06-03 15:31:50 +00:00
$r = q ( " SELECT DISTINCT item.parent AS item_id, $ordering FROM item
2018-02-09 19:36:14 +00:00
left join abook on ( item . author_xchan = abook . abook_xchan $abook_uids )
2018-05-09 03:12:49 +00:00
WHERE true and item . uid = % d $item_normal
2018-02-09 13:06:59 +00:00
AND ( abook . abook_blocked = 0 or abook . abook_flags is null )
2018-06-03 15:31:50 +00:00
AND item . item_wall = 1 AND item . item_thread_top = 1
2018-05-30 20:40:22 +00:00
$sql_extra $sql_extra2
2018-06-03 15:31:50 +00:00
ORDER BY $ordering DESC $pager_sql " ,
2018-08-21 00:22:49 +00:00
intval ( App :: $profile [ 'profile_uid' ])
2016-05-23 00:52:30 +00:00
);
}
}
else {
2019-05-23 23:37:56 +00:00
$r = [];
2016-05-23 00:52:30 +00:00
}
2014-01-08 15:03:59 +00:00
}
2019-05-23 23:37:56 +00:00
if ( $r ) {
2012-10-30 00:14:02 +00:00
2016-05-23 00:52:30 +00:00
$parents_str = ids_to_querystr ( $r , 'item_id' );
2016-10-01 22:41:25 +00:00
$items = q ( " SELECT item.*, item.id AS item_id
2016-10-04 04:48:53 +00:00
FROM item
WHERE item . uid = % d $item_normal
AND item . parent IN ( % s )
2016-05-23 00:52:30 +00:00
$sql_extra " ,
2018-08-21 00:22:49 +00:00
intval ( App :: $profile [ 'profile_uid' ]),
2016-05-23 00:52:30 +00:00
dbesc ( $parents_str )
);
2012-12-16 08:44:38 +00:00
2016-05-23 00:52:30 +00:00
xchan_query ( $items );
$items = fetch_post_tags ( $items , true );
2018-05-30 00:35:44 +00:00
$items = conv_sort ( $items , $ordering );
2012-12-16 08:44:38 +00:00
2019-05-23 23:37:56 +00:00
if ( $load && $mid && ( ! count ( $items ))) {
2016-05-23 00:52:30 +00:00
// This will happen if we don't have sufficient permissions
// to view the parent item (or the item itself if it is toplevel)
notice ( t ( 'Permission denied.' ) . EOL );
}
2012-10-30 00:14:02 +00:00
2019-05-23 23:37:56 +00:00
}
else {
$items = [];
2016-05-23 00:52:30 +00:00
}
2012-10-30 00:14:02 +00:00
2019-05-23 23:37:56 +00:00
if (( ! $update ) && ( ! $load )) {
2016-05-23 00:52:30 +00:00
// 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.
2018-08-21 00:22:49 +00:00
$maxheight = get_pconfig ( App :: $profile [ 'profile_uid' ], 'system' , 'channel_divmore_height' );
2016-05-23 00:52:30 +00:00
if ( ! $maxheight )
$maxheight = 400 ;
$o .= '<div id="live-channel"></div>' . " \r \n " ;
2018-08-21 00:22:49 +00:00
$o .= " <script> var profile_uid = " . App :: $profile [ 'profile_uid' ]
. " ; var netargs = '?f='; var profile_page = " . App :: $pager [ 'page' ]
2016-05-23 00:52:30 +00:00
. " ; divmore_height = " . intval ( $maxheight ) . " ; </script> \r \n " ;
2018-08-21 00:22:49 +00:00
App :: $page [ 'htmlhead' ] .= replace_macros ( get_markup_template ( " build_query.tpl " ), array (
2016-05-23 00:52:30 +00:00
'$baseurl' => z_root (),
'$pgtype' => 'channel' ,
2018-08-21 00:22:49 +00:00
'$uid' => (( App :: $profile [ 'profile_uid' ]) ? App :: $profile [ 'profile_uid' ] : '0' ),
2016-05-23 00:52:30 +00:00
'$gid' => '0' ,
'$cid' => '0' ,
2018-06-15 22:21:19 +00:00
'$cmin' => '(-1)' ,
'$cmax' => '(-1)' ,
2016-05-23 00:52:30 +00:00
'$star' => '0' ,
'$liked' => '0' ,
'$conv' => '0' ,
'$spam' => '0' ,
'$nouveau' => '0' ,
'$wall' => '1' ,
'$fh' => '0' ,
2019-06-19 02:21:31 +00:00
'$dm' => '0' ,
2016-11-02 22:48:29 +00:00
'$static' => $static ,
2018-08-21 00:22:49 +00:00
'$page' => (( App :: $pager [ 'page' ] != 1 ) ? App :: $pager [ 'page' ] : 1 ),
2018-05-09 03:12:49 +00:00
'$search' => $search ,
2017-03-03 01:32:43 +00:00
'$xchan' => '' ,
2019-03-19 02:19:04 +00:00
'$order' => (( $order ) ? urlencode ( $order ) : '' ),
2016-05-23 00:52:30 +00:00
'$list' => (( x ( $_REQUEST , 'list' )) ? intval ( $_REQUEST [ 'list' ]) : 0 ),
'$file' => '' ,
2017-07-21 01:11:47 +00:00
'$cats' => (( $category ) ? urlencode ( $category ) : '' ),
'$tags' => (( $hashtags ) ? urlencode ( $hashtags ) : '' ),
2019-03-19 02:19:04 +00:00
'$mid' => (( $mid ) ? urlencode ( $mid ) : '' ),
2016-05-23 00:52:30 +00:00
'$verb' => '' ,
2017-11-01 09:53:12 +00:00
'$net' => '' ,
2016-05-23 00:52:30 +00:00
'$dend' => $datequery ,
'$dbegin' => $datequery2
));
2012-10-30 00:14:02 +00:00
2014-11-17 23:43:03 +00:00
}
2016-05-23 00:52:30 +00:00
$update_unseen = '' ;
2013-01-06 00:40:45 +00:00
2019-05-23 23:37:56 +00:00
if ( $page_mode === 'list' ) {
2012-10-30 00:14:02 +00:00
2016-05-23 00:52:30 +00:00
/**
2016-10-01 22:41:25 +00:00
* in " list mode " , only mark the parent item and any like activities as " seen " .
2016-05-23 00:52:30 +00:00
* 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
2016-10-01 22:41:25 +00:00
* comment likes could also get somewhat hairy .
2016-05-23 00:52:30 +00:00
*/
2012-10-30 00:14:02 +00:00
2019-05-23 23:37:56 +00:00
if ( $parents_str ) {
2016-05-23 00:52:30 +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-05-23 23:37:56 +00:00
if ( $parents_str ) {
2016-05-23 00:52:30 +00:00
$update_unseen = " AND parent IN ( " . dbesc ( $parents_str ) . " ) " ;
}
}
2020-02-24 23:40:20 +00:00
if ( $is_owner && $update_unseen && ( ! $_SESSION [ 'sudo' ])) {
2017-08-02 05:25:55 +00:00
$x = [ 'channel_id' => local_channel (), 'update' => 'unset' ];
call_hooks ( 'update_unseen' , $x );
2019-05-23 23:37:56 +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 item_wall = 1 AND uid = %d $update_unseen " ,
intval ( local_channel ())
);
}
2016-05-23 00:52:30 +00:00
}
2012-10-30 00:14:02 +00:00
2018-05-30 20:40:22 +00:00
$mode = (( $search ) ? 'search' : 'channel' );
2014-01-21 01:45:02 +00:00
2018-08-21 00:22:49 +00:00
if ( $update ) {
$o .= conversation ( $items , $mode , $update , $page_mode );
2016-10-01 22:41:25 +00:00
}
2016-05-23 00:52:30 +00:00
else {
2018-09-07 12:23:16 +00:00
2018-08-21 00:22:49 +00:00
$o .= '<noscript>' ;
2019-05-23 23:37:56 +00:00
if ( $noscript_content ) {
2018-09-07 12:23:16 +00:00
$o .= conversation ( $items , $mode , $update , 'traditional' );
$o .= alt_pager ( count ( $items ));
}
else {
2018-09-07 12:58:16 +00:00
$o .= '<div class="section-content-warning-wrapper">' . t ( 'You must enable javascript for your browser to be able to view this content.' ) . '</div>' ;
2018-09-07 12:23:16 +00:00
}
2018-08-21 00:22:49 +00:00
$o .= '</noscript>' ;
2018-09-07 12:23:16 +00:00
2018-05-30 20:40:22 +00:00
$o .= conversation ( $items , $mode , $update , $page_mode );
2016-04-16 05:36:07 +00:00
2016-05-23 00:52:30 +00:00
if ( $mid && $items [ 0 ][ 'title' ])
2018-08-21 00:22:49 +00:00
App :: $page [ 'title' ] = $items [ 0 ][ 'title' ] . " - " . App :: $page [ 'title' ];
2016-05-23 00:52:30 +00:00
}
2016-04-16 05:36:07 +00:00
2016-10-01 22:41:25 +00:00
if ( $mid )
2016-05-23 00:52:30 +00:00
$o .= '<div id="content-complete"></div>' ;
return $o ;
}
2016-08-03 19:16:57 +00:00
}