2012-06-15 00:46:58 +00:00
< ? php
2017-11-21 12:20:22 +00:00
/**
2020-02-09 15:18:46 +00:00
* @ copyright Copyright ( C ) 2020 , Friendica
*
* @ license GNU AGPL version 3 or any later version
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation , either version 3 of the
* License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*
2017-11-21 12:20:22 +00:00
*/
2018-01-25 02:08:45 +00:00
2017-04-30 04:07:00 +00:00
use Friendica\App ;
2017-12-04 14:04:36 +00:00
use Friendica\Content\Feature ;
2017-11-21 12:20:22 +00:00
use Friendica\Content\ForumManager ;
2018-01-15 19:51:56 +00:00
use Friendica\Content\Nav ;
2018-10-24 06:15:24 +00:00
use Friendica\Content\Pager ;
2018-01-15 14:50:06 +00:00
use Friendica\Content\Widget ;
2018-11-06 02:06:26 +00:00
use Friendica\Content\Text\HTML ;
2018-03-02 23:41:24 +00:00
use Friendica\Core\ACL ;
2018-10-24 06:15:24 +00:00
use Friendica\Core\Hook ;
2018-10-29 21:20:46 +00:00
use Friendica\Core\Logger ;
2018-08-11 20:40:44 +00:00
use Friendica\Core\Protocol ;
2018-10-31 14:35:50 +00:00
use Friendica\Core\Renderer ;
2019-05-26 20:15:38 +00:00
use Friendica\Core\Session ;
2018-07-20 12:19:26 +00:00
use Friendica\Database\DBA ;
2019-12-15 22:28:01 +00:00
use Friendica\DI ;
2017-12-07 14:04:24 +00:00
use Friendica\Model\Contact ;
2017-12-09 18:45:17 +00:00
use Friendica\Model\Group ;
2018-02-06 12:40:22 +00:00
use Friendica\Model\Item ;
2018-01-15 02:22:39 +00:00
use Friendica\Model\Profile ;
2019-03-09 23:36:11 +00:00
use Friendica\Model\Term ;
2019-12-27 21:19:28 +00:00
use Friendica\Module\Security\Login ;
2018-01-27 02:38:34 +00:00
use Friendica\Util\DateTimeFormat ;
2018-07-31 02:06:22 +00:00
use Friendica\Util\Proxy as ProxyUtils ;
2018-11-08 15:14:37 +00:00
use Friendica\Util\Strings ;
2017-09-13 06:43:43 +00:00
2018-01-21 15:26:05 +00:00
function network_init ( App $a )
{
2017-09-13 06:43:43 +00:00
if ( ! local_user ()) {
2020-01-18 19:52:34 +00:00
notice ( DI :: l10n () -> t ( 'Permission denied.' ) . EOL );
2012-06-15 00:46:58 +00:00
return ;
}
2013-01-13 16:13:01 +00:00
2018-10-24 06:15:24 +00:00
Hook :: add ( 'head' , __FILE__ , 'network_infinite_scroll_head' );
2012-06-15 00:46:58 +00:00
$is_a_date_query = false ;
2017-11-26 16:17:32 +00:00
$group_id = (( $a -> argc > 1 && is_numeric ( $a -> argv [ 1 ])) ? intval ( $a -> argv [ 1 ]) : 0 );
2017-12-01 13:32:21 +00:00
$cid = 0 ;
2018-11-30 14:06:22 +00:00
if ( ! empty ( $_GET [ 'cid' ])) {
2015-11-28 22:52:12 +00:00
$cid = $_GET [ 'cid' ];
2018-11-30 10:43:07 +00:00
$_GET [ 'nets' ] = '' ;
2017-11-26 16:17:32 +00:00
$group_id = 0 ;
2016-12-22 10:37:23 +00:00
}
2012-06-15 00:46:58 +00:00
2016-12-22 10:37:23 +00:00
if ( $a -> argc > 1 ) {
for ( $x = 1 ; $x < $a -> argc ; $x ++ ) {
2020-01-15 04:06:30 +00:00
if ( DI :: dtFormat () -> isYearMonthDay ( $a -> argv [ $x ])) {
2012-06-15 00:46:58 +00:00
$is_a_date_query = true ;
break ;
}
}
}
2013-01-13 16:13:01 +00:00
2014-11-10 14:07:35 +00:00
// convert query string to array. remove friendica args
2018-01-15 13:05:12 +00:00
$query_array = [];
2019-12-16 00:30:34 +00:00
parse_str ( parse_url ( DI :: args () -> getQueryString (), PHP_URL_QUERY ), $query_array );
2013-01-13 16:13:01 +00:00
2012-09-29 23:56:50 +00:00
// fetch last used network view and redirect if needed
2017-09-13 06:43:43 +00:00
if ( ! $is_a_date_query ) {
2019-10-15 13:01:17 +00:00
$sel_nets = $_GET [ 'nets' ] ? ? '' ;
2012-09-29 23:56:50 +00:00
$sel_tabs = network_query_get_sel_tab ( $a );
$sel_groups = network_query_get_sel_group ( $a );
2020-01-18 15:50:57 +00:00
$last_sel_tabs = DI :: pConfig () -> get ( local_user (), 'network.view' , 'tab.selected' );
2012-09-29 23:56:50 +00:00
$remember_tab = ( $sel_tabs [ 0 ] === 'active' && is_array ( $last_sel_tabs ) && $last_sel_tabs [ 0 ] !== 'active' );
$net_baseurl = '/network' ;
2018-01-15 13:05:12 +00:00
$net_args = [];
2012-09-29 23:56:50 +00:00
2018-01-21 15:49:05 +00:00
if ( $sel_groups !== false ) {
2012-09-29 23:56:50 +00:00
$net_baseurl .= '/' . $sel_groups ;
}
2015-08-11 18:16:53 +00:00
2017-04-04 05:35:04 +00:00
if ( $remember_tab ) {
2012-09-29 23:56:50 +00:00
// redirect if current selected tab is '/network' and
2019-11-02 12:54:26 +00:00
// last selected tab is _not_ '/network?order=activity'.
2012-09-29 23:56:50 +00:00
// and this isn't a date query
2018-01-15 13:05:12 +00:00
$tab_args = [
2019-11-02 12:54:26 +00:00
'order=activity' , //all
2019-11-02 12:59:57 +00:00
'order=post' , //postord
'conv=1' , //conv
2020-01-13 20:10:13 +00:00
'new=1' , //new
2019-11-02 12:59:57 +00:00
'star=1' , //starred
'bmark=1' , //bookmarked
2018-01-15 13:05:12 +00:00
];
2012-09-29 23:56:50 +00:00
$k = array_search ( 'active' , $last_sel_tabs );
2017-04-04 05:35:04 +00:00
if ( $k != 3 ) {
// parse out tab queries
2018-01-15 13:05:12 +00:00
$dest_qa = [];
2017-04-04 05:35:04 +00:00
$dest_qs = $tab_args [ $k ];
parse_str ( $dest_qs , $dest_qa );
$net_args = array_merge ( $net_args , $dest_qa );
} else {
$remember_tab = false ;
}
2012-09-29 23:56:50 +00:00
}
2018-11-30 10:43:07 +00:00
if ( $sel_nets ) {
2014-11-10 14:37:52 +00:00
$net_args [ 'nets' ] = $sel_nets ;
}
2015-08-11 18:16:53 +00:00
2018-01-21 15:49:05 +00:00
if ( $remember_tab ) {
2014-03-09 08:19:14 +00:00
$net_args = array_merge ( $query_array , $net_args );
2019-05-27 21:18:42 +00:00
$net_queries = http_build_query ( $net_args );
2015-08-11 18:16:53 +00:00
2018-01-21 15:48:15 +00:00
$redir_url = ( $net_queries ? $net_baseurl . '?' . $net_queries : $net_baseurl );
2015-08-11 18:16:53 +00:00
2019-12-15 23:28:31 +00:00
DI :: baseUrl () -> redirect ( $redir_url );
2012-09-29 23:56:50 +00:00
}
}
2015-08-11 18:16:53 +00:00
2019-12-30 19:02:09 +00:00
if ( empty ( DI :: page ()[ 'aside' ])) {
DI :: page ()[ 'aside' ] = '' ;
2017-03-30 19:36:34 +00:00
}
2012-06-15 00:46:58 +00:00
2019-12-30 19:02:09 +00:00
DI :: page ()[ 'aside' ] .= Group :: sidebarWidget ( 'network/0' , 'network' , 'standard' , $group_id );
DI :: page ()[ 'aside' ] .= ForumManager :: widget ( local_user (), $cid );
DI :: page ()[ 'aside' ] .= Widget :: postedByYear ( 'network' , local_user (), false );
DI :: page ()[ 'aside' ] .= Widget :: networks ( 'network' , $_GET [ 'nets' ] ? ? '' );
DI :: page ()[ 'aside' ] .= Widget\SavedSearches :: getHTML ( DI :: args () -> getQueryString ());
DI :: page ()[ 'aside' ] .= Widget :: fileAs ( 'network' , $_GET [ 'file' ] ? ? '' );
2012-06-15 00:46:58 +00:00
}
/**
* Return selected tab from query
2014-03-09 08:19:14 +00:00
*
2012-06-15 00:46:58 +00:00
* urls -> returns
2019-11-02 12:59:57 +00:00
* '/network' => $no_active = 'active'
* '/network?order=activity' => $activity_active = 'active'
* '/network?order=post' => $postord_active = 'active'
2019-05-27 21:19:38 +00:00
* '/network?conv=1' , => $conv_active = 'active'
2020-01-13 20:10:13 +00:00
* '/network?new=1' , => $new_active = 'active'
2019-05-27 21:19:38 +00:00
* '/network?star=1' , => $starred_active = 'active'
2019-11-02 12:59:57 +00:00
* '/network?bmark=1' , => $bookmarked_active = 'active'
2014-03-09 08:19:14 +00:00
*
2019-01-07 06:07:42 +00:00
* @ param App $a
2019-11-02 12:54:26 +00:00
* @ return array ( $no_active , $activity_active , $postord_active , $conv_active , $new_active , $starred_active , $bookmarked_active );
2012-06-15 00:46:58 +00:00
*/
2018-01-21 15:26:05 +00:00
function network_query_get_sel_tab ( App $a )
{
$no_active = '' ;
2012-06-15 00:46:58 +00:00
$starred_active = '' ;
$new_active = '' ;
$bookmarked_active = '' ;
$all_active = '' ;
$conv_active = '' ;
2019-11-02 12:54:26 +00:00
$postord_active = '' ;
2012-06-15 00:46:58 +00:00
2020-01-13 20:10:13 +00:00
if ( ! empty ( $_GET [ 'new' ])) {
2018-01-21 15:26:05 +00:00
$new_active = 'active' ;
2012-06-15 00:46:58 +00:00
}
2013-10-14 22:49:13 +00:00
2018-11-30 14:06:22 +00:00
if ( ! empty ( $_GET [ 'star' ])) {
2012-06-15 00:46:58 +00:00
$starred_active = 'active' ;
}
2013-10-14 22:49:13 +00:00
2018-11-30 14:06:22 +00:00
if ( ! empty ( $_GET [ 'bmark' ])) {
2012-06-15 00:46:58 +00:00
$bookmarked_active = 'active' ;
}
2018-11-30 14:06:22 +00:00
if ( ! empty ( $_GET [ 'conv' ])) {
2012-06-15 00:46:58 +00:00
$conv_active = 'active' ;
}
2018-06-03 07:42:56 +00:00
if (( $new_active == '' ) && ( $starred_active == '' ) && ( $bookmarked_active == '' ) && ( $conv_active == '' )) {
2018-01-21 15:26:05 +00:00
$no_active = 'active' ;
2012-06-15 00:46:58 +00:00
}
2018-11-30 14:06:22 +00:00
if ( $no_active == 'active' && ! empty ( $_GET [ 'order' ])) {
2018-01-21 15:26:05 +00:00
switch ( $_GET [ 'order' ]) {
2019-11-02 12:59:57 +00:00
case 'post' : $postord_active = 'active' ; $no_active = '' ; break ;
2019-11-02 12:54:26 +00:00
case 'activity' : $all_active = 'active' ; $no_active = '' ; break ;
2012-06-15 00:46:58 +00:00
}
}
2013-10-14 22:49:13 +00:00
2019-11-02 12:54:26 +00:00
return [ $no_active , $all_active , $postord_active , $conv_active , $new_active , $starred_active , $bookmarked_active ];
2012-06-15 00:46:58 +00:00
}
2018-01-21 15:26:05 +00:00
function network_query_get_sel_group ( App $a )
{
2012-09-29 23:56:50 +00:00
$group = false ;
2017-09-13 06:43:43 +00:00
if ( $a -> argc >= 2 && is_numeric ( $a -> argv [ 1 ])) {
2012-09-29 23:56:50 +00:00
$group = $a -> argv [ 1 ];
}
return $group ;
}
2017-09-14 06:10:33 +00:00
/**
2020-01-19 06:05:23 +00:00
* Sets the pager data and returns SQL
2017-09-14 06:10:33 +00:00
*
2019-01-07 06:07:42 +00:00
* @ param App $a The global App
* @ param Pager $pager
2017-09-14 06:10:33 +00:00
* @ param integer $update Used for the automatic reloading
* @ return string SQL with the appropriate LIMIT clause
2019-01-07 06:07:42 +00:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
2017-09-14 06:10:33 +00:00
*/
2018-10-24 06:15:24 +00:00
function networkPager ( App $a , Pager $pager , $update )
2018-01-21 15:26:05 +00:00
{
2017-09-13 06:43:43 +00:00
if ( $update ) {
// only setup pagination on initial page view
return ' LIMIT 100' ;
}
2012-06-15 00:46:58 +00:00
2017-09-13 06:43:43 +00:00
// check if we serve a mobile device and get the user settings
// accordingly
2019-12-16 00:12:07 +00:00
if ( DI :: mode () -> isMobile ()) {
2020-01-18 15:50:57 +00:00
$itemspage_network = DI :: pConfig () -> get ( local_user (), 'system' , 'itemspage_mobile_network' );
2017-09-13 06:43:43 +00:00
$itemspage_network = (( intval ( $itemspage_network )) ? $itemspage_network : 20 );
} else {
2020-01-18 15:50:57 +00:00
$itemspage_network = DI :: pConfig () -> get ( local_user (), 'system' , 'itemspage_network' );
2017-09-13 06:43:43 +00:00
$itemspage_network = (( intval ( $itemspage_network )) ? $itemspage_network : 40 );
}
// now that we have the user settings, see if the theme forces
// a maximum item number which is lower then the user choice
if (( $a -> force_max_items > 0 ) && ( $a -> force_max_items < $itemspage_network )) {
$itemspage_network = $a -> force_max_items ;
}
2018-10-24 06:15:24 +00:00
$pager -> setItemsPerPage ( $itemspage_network );
2017-09-13 06:43:43 +00:00
2018-10-24 06:15:24 +00:00
return sprintf ( " LIMIT %d, %d " , $pager -> getStart (), $pager -> getItemsPerPage ());
2017-09-13 06:43:43 +00:00
}
2017-09-14 06:10:33 +00:00
/**
2020-01-19 06:05:23 +00:00
* Sets items as seen
2017-09-14 06:10:33 +00:00
*
* @ param array $condition The array with the SQL condition
2019-01-07 06:07:42 +00:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
2017-09-14 06:10:33 +00:00
*/
2018-01-21 15:26:05 +00:00
function networkSetSeen ( $condition )
{
2017-09-13 06:43:43 +00:00
if ( empty ( $condition )) {
return ;
}
2018-08-15 04:41:49 +00:00
$unseen = Item :: exists ( $condition );
2017-09-13 06:43:43 +00:00
if ( $unseen ) {
2019-01-07 06:23:49 +00:00
Item :: update ([ 'unseen' => false ], $condition );
2017-09-13 06:43:43 +00:00
}
}
2017-09-14 06:10:33 +00:00
/**
2020-01-19 06:05:23 +00:00
* Create the conversation HTML
2017-09-14 06:10:33 +00:00
*
2018-10-24 06:15:24 +00:00
* @ param App $a The global App
* @ param array $items Items of the conversation
2019-01-07 06:07:42 +00:00
* @ param Pager $pager
2018-10-24 06:15:24 +00:00
* @ param string $mode Display mode for the conversation
2017-09-14 06:10:33 +00:00
* @ param integer $update Used for the automatic reloading
2019-01-07 06:07:42 +00:00
* @ param string $ordering
2017-09-14 06:10:33 +00:00
* @ return string HTML of the conversation
2019-01-07 15:24:06 +00:00
* @ throws ImagickException
2019-01-07 06:07:42 +00:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
2017-09-14 06:10:33 +00:00
*/
2018-10-24 06:15:24 +00:00
function networkConversation ( App $a , $items , Pager $pager , $mode , $update , $ordering = '' )
2018-01-21 15:26:05 +00:00
{
2017-09-13 06:43:43 +00:00
// Set this so that the conversation function can find out contact info for our wall-wall items
$a -> page_contact = $a -> contact ;
2018-11-17 16:24:30 +00:00
if ( ! is_array ( $items )) {
2018-11-17 12:22:32 +00:00
Logger :: log ( " Expecting items to be an array. Got " . print_r ( $items , true ));
$items = [];
}
2018-10-24 06:15:24 +00:00
$o = conversation ( $a , $items , $pager , $mode , $update , false , $ordering , local_user ());
2017-09-13 06:43:43 +00:00
if ( ! $update ) {
2020-01-18 15:50:57 +00:00
if ( DI :: pConfig () -> get ( local_user (), 'system' , 'infinite_scroll' )) {
2018-11-06 02:06:26 +00:00
$o .= HTML :: scrollLoader ();
2017-09-13 06:43:43 +00:00
} else {
2018-10-24 06:15:24 +00:00
$o .= $pager -> renderMinimal ( count ( $items ));
2017-09-13 06:43:43 +00:00
}
}
2012-06-15 00:46:58 +00:00
2017-09-13 06:43:43 +00:00
return $o ;
}
2018-02-27 21:10:05 +00:00
function network_content ( App $a , $update = 0 , $parent = 0 )
2018-01-21 15:26:05 +00:00
{
2017-09-13 06:43:43 +00:00
if ( ! local_user ()) {
2017-12-17 16:40:59 +00:00
return Login :: form ();
2012-06-15 00:46:58 +00:00
}
2017-09-13 06:43:43 +00:00
/// @TODO Is this really necessary? $a is already available to hooks
2019-12-16 00:30:34 +00:00
$arr = [ 'query' => DI :: args () -> getQueryString ()];
2018-12-26 06:06:24 +00:00
Hook :: callAll ( 'network_content_init' , $arr );
2017-09-13 06:43:43 +00:00
2020-01-13 20:10:13 +00:00
if ( ! empty ( $_GET [ 'new' ]) || ! empty ( $_GET [ 'file' ])) {
2017-09-13 06:43:43 +00:00
$o = networkFlatView ( $a , $update );
} else {
2018-02-27 21:10:05 +00:00
$o = networkThreadedView ( $a , $update , $parent );
2017-09-13 06:43:43 +00:00
}
2018-11-17 16:27:12 +00:00
if ( $o === '' ) {
2018-11-17 12:22:32 +00:00
info ( " No items found " );
}
2017-09-13 06:43:43 +00:00
return $o ;
}
/**
2020-01-19 06:05:23 +00:00
* Get the network content in flat view
2017-09-13 06:43:43 +00:00
*
2018-10-24 06:15:24 +00:00
* @ param App $a The global App
2017-09-13 06:43:43 +00:00
* @ param integer $update Used for the automatic reloading
* @ return string HTML of the network content in flat view
2019-01-07 15:24:06 +00:00
* @ throws ImagickException
2019-01-07 06:07:42 +00:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ global Pager $pager
2017-09-13 06:43:43 +00:00
*/
2018-01-21 15:26:05 +00:00
function networkFlatView ( App $a , $update = 0 )
{
2018-10-24 06:15:24 +00:00
global $pager ;
2017-09-13 06:43:43 +00:00
// Rawmode is used for fetching new content at the end of the page
2018-07-01 07:57:59 +00:00
$rawmode = ( isset ( $_GET [ 'mode' ]) && ( $_GET [ 'mode' ] == 'raw' ));
2017-09-13 06:43:43 +00:00
$o = '' ;
2019-10-15 13:01:17 +00:00
$file = $_GET [ 'file' ] ? ? '' ;
2017-09-13 06:43:43 +00:00
if ( ! $update && ! $rawmode ) {
$tabs = network_tabs ( $a );
$o .= $tabs ;
2018-01-15 19:51:56 +00:00
Nav :: setSelected ( 'network' );
2017-09-13 06:43:43 +00:00
2018-01-15 13:05:12 +00:00
$x = [
2017-09-13 06:43:43 +00:00
'is_owner' => true ,
'allow_location' => $a -> user [ 'allow_location' ],
'default_location' => $a -> user [ 'default-location' ],
'nickname' => $a -> user [ 'nickname' ],
2018-08-18 06:20:50 +00:00
'lockstate' => ( is_array ( $a -> user ) &&
( strlen ( $a -> user [ 'allow_cid' ]) || strlen ( $a -> user [ 'allow_gid' ]) ||
strlen ( $a -> user [ 'deny_cid' ]) || strlen ( $a -> user [ 'deny_gid' ])) ? 'lock' : 'unlock' ),
2018-03-02 23:41:24 +00:00
'default_perms' => ACL :: getDefaultUserPermissions ( $a -> user ),
2019-12-30 19:02:09 +00:00
'acl' => ACL :: getFullSelectorHTML ( DI :: page (), $a -> user , true ),
2018-01-21 15:26:05 +00:00
'bang' => '' ,
2017-09-13 06:43:43 +00:00
'visitor' => 'block' ,
'profile_uid' => local_user (),
'content' => '' ,
2018-01-15 13:05:12 +00:00
];
2017-09-13 06:43:43 +00:00
2018-01-04 00:29:52 +00:00
$o .= status_editor ( $a , $x );
2017-09-13 06:43:43 +00:00
2020-01-19 20:21:13 +00:00
if ( ! DI :: config () -> get ( 'theme' , 'hide_eventlist' )) {
2018-01-15 02:22:39 +00:00
$o .= Profile :: getBirthdays ();
2018-02-28 01:47:18 +00:00
$o .= Profile :: getEventsReminderHTML ();
2017-09-13 06:43:43 +00:00
}
}
2019-12-16 00:30:34 +00:00
$pager = new Pager ( DI :: args () -> getQueryString ());
2018-10-24 06:15:24 +00:00
2019-01-07 06:23:49 +00:00
networkPager ( $a , $pager , $update );
2018-06-15 22:30:49 +00:00
2019-03-09 23:36:11 +00:00
$item_params = [ 'order' => [ 'id' => true ]];
2017-09-13 06:43:43 +00:00
if ( strlen ( $file )) {
2019-03-09 23:36:11 +00:00
$term_condition = [ " `term` = ? AND `otype` = ? AND `type` = ? AND `uid` = ? " ,
$file , Term :: OBJECT_TYPE_POST , Term :: FILE , local_user ()];
$term_params = [ 'order' => [ 'tid' => true ], 'limit' => [ $pager -> getStart (), $pager -> getItemsPerPage ()]];
$result = DBA :: select ( 'term' , [ 'oid' ], $term_condition , $term_params );
2018-06-15 22:30:49 +00:00
$posts = [];
2018-07-20 12:19:26 +00:00
while ( $term = DBA :: fetch ( $result )) {
2018-06-15 22:30:49 +00:00
$posts [] = $term [ 'oid' ];
}
2018-08-17 03:19:42 +00:00
DBA :: close ( $result );
2018-06-15 22:30:49 +00:00
2018-11-17 16:27:12 +00:00
if ( count ( $posts ) == 0 ) {
2018-11-17 12:22:32 +00:00
return '' ;
}
2019-03-09 23:36:11 +00:00
$item_condition = [ 'uid' => local_user (), 'id' => $posts ];
2017-09-13 06:43:43 +00:00
} else {
2019-03-09 23:36:11 +00:00
$item_condition = [ 'uid' => local_user ()];
$item_params [ 'limit' ] = [ $pager -> getStart (), $pager -> getItemsPerPage ()];
networkSetSeen ([ 'unseen' => true , 'uid' => local_user ()]);
2017-09-13 06:43:43 +00:00
}
2019-03-09 23:36:11 +00:00
$result = Item :: selectForUser ( local_user (), [], $item_condition , $item_params );
2018-06-24 10:48:29 +00:00
$items = Item :: inArray ( $result );
2018-10-24 06:15:24 +00:00
$o .= networkConversation ( $a , $items , $pager , 'network-new' , $update );
2017-09-13 06:43:43 +00:00
return $o ;
}
/**
2020-01-19 06:05:23 +00:00
* Get the network content in threaded view
2017-09-13 06:43:43 +00:00
*
2018-10-24 06:15:24 +00:00
* @ param App $a The global App
* @ param integer $update Used for the automatic reloading
* @ param integer $parent
2017-09-13 06:43:43 +00:00
* @ return string HTML of the network content in flat view
2019-01-07 15:24:06 +00:00
* @ throws ImagickException
2019-01-07 06:07:42 +00:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ global Pager $pager
2017-09-13 06:43:43 +00:00
*/
2018-02-27 21:10:05 +00:00
function networkThreadedView ( App $a , $update , $parent )
2018-01-21 15:26:05 +00:00
{
2018-10-24 06:15:24 +00:00
/// @TODO this will have to be converted to a static property of the converted Module\Network class
global $pager ;
2016-01-10 08:19:00 +00:00
// Rawmode is used for fetching new content at the end of the page
2018-01-21 15:48:15 +00:00
$rawmode = ( isset ( $_GET [ 'mode' ]) AND ( $_GET [ 'mode' ] == 'raw' ));
2016-01-10 08:19:00 +00:00
2018-01-21 15:48:15 +00:00
if ( isset ( $_GET [ 'last_received' ]) && isset ( $_GET [ 'last_commented' ]) && isset ( $_GET [ 'last_created' ]) && isset ( $_GET [ 'last_id' ])) {
2018-07-21 12:25:11 +00:00
$last_received = DateTimeFormat :: utc ( $_GET [ 'last_received' ]);
$last_commented = DateTimeFormat :: utc ( $_GET [ 'last_commented' ]);
$last_created = DateTimeFormat :: utc ( $_GET [ 'last_created' ]);
2018-01-21 15:48:15 +00:00
$last_id = intval ( $_GET [ 'last_id' ]);
2017-07-31 06:04:37 +00:00
} else {
$last_received = '' ;
$last_commented = '' ;
$last_created = '' ;
$last_id = 0 ;
}
2012-06-15 00:46:58 +00:00
$datequery = $datequery2 = '' ;
2018-01-11 08:26:30 +00:00
$gid = 0 ;
2012-06-15 00:46:58 +00:00
2018-08-14 22:43:27 +00:00
$default_permissions = [];
2017-09-13 06:43:43 +00:00
if ( $a -> argc > 1 ) {
for ( $x = 1 ; $x < $a -> argc ; $x ++ ) {
2020-01-15 04:06:30 +00:00
if ( DI :: dtFormat () -> isYearMonthDay ( $a -> argv [ $x ])) {
2017-09-13 06:43:43 +00:00
if ( $datequery ) {
2018-11-09 18:27:58 +00:00
$datequery2 = Strings :: escapeHtml ( $a -> argv [ $x ]);
2017-09-13 06:43:43 +00:00
} else {
2018-11-09 18:27:58 +00:00
$datequery = Strings :: escapeHtml ( $a -> argv [ $x ]);
2019-11-02 12:54:26 +00:00
$_GET [ 'order' ] = 'post' ;
2012-06-15 00:46:58 +00:00
}
2017-09-13 06:43:43 +00:00
} elseif ( intval ( $a -> argv [ $x ])) {
2018-01-11 08:26:30 +00:00
$gid = intval ( $a -> argv [ $x ]);
2019-02-11 09:00:42 +00:00
$default_permissions [ 'allow_gid' ] = [ $gid ];
2012-06-15 00:46:58 +00:00
}
}
}
$o = '' ;
2019-10-15 13:01:17 +00:00
$cid = intval ( $_GET [ 'cid' ] ? ? 0 );
$star = intval ( $_GET [ 'star' ] ? ? 0 );
$bmark = intval ( $_GET [ 'bmark' ] ? ? 0 );
$conv = intval ( $_GET [ 'conv' ] ? ? 0 );
2019-11-02 12:54:26 +00:00
$order = Strings :: escapeTags (( $_GET [ 'order' ] ? ? '' ) ? : 'activity' );
2019-10-15 13:01:17 +00:00
$nets = $_GET [ 'nets' ] ? ? '' ;
2012-06-15 00:46:58 +00:00
2019-03-02 14:28:37 +00:00
$allowedCids = [];
2017-09-13 06:43:43 +00:00
if ( $cid ) {
2019-03-02 14:28:37 +00:00
$allowedCids [] = ( int ) $cid ;
} elseif ( $nets ) {
$condition = [
'uid' => local_user (),
'network' => $nets ,
'self' => false ,
'blocked' => false ,
'pending' => false ,
'archive' => false ,
'rel' => [ Contact :: SHARING , Contact :: FRIEND ],
];
$contactStmt = DBA :: select ( 'contact' , [ 'id' ], $condition );
while ( $contact = DBA :: fetch ( $contactStmt )) {
$allowedCids [] = ( int ) $contact [ 'id' ];
}
DBA :: close ( $contactStmt );
2017-09-13 06:43:43 +00:00
}
2012-06-15 00:46:58 +00:00
2019-03-02 14:28:37 +00:00
if ( count ( $allowedCids )) {
$default_permissions [ 'allow_cid' ] = $allowedCids ;
2012-06-15 00:46:58 +00:00
}
2017-09-13 06:43:43 +00:00
if ( ! $update && ! $rawmode ) {
2016-06-23 22:33:31 +00:00
$tabs = network_tabs ( $a );
$o .= $tabs ;
2020-01-18 15:50:57 +00:00
if ( $gid && ( $t = Contact :: getOStatusCountByGroupId ( $gid )) && ! DI :: pConfig () -> get ( local_user (), 'system' , 'nowarn_insecure' )) {
2020-01-18 19:53:01 +00:00
notice ( DI :: l10n () -> tt ( " Warning: This group contains %s member from a network that doesn't allow non public messages. " ,
2018-10-24 06:15:24 +00:00
" Warning: This group contains %s members from a network that doesn't allow non public messages. " ,
$t ) . EOL );
2020-01-18 19:52:34 +00:00
notice ( DI :: l10n () -> t ( " Messages in this group won't be send to these receivers. " ) . EOL );
2012-06-15 00:46:58 +00:00
}
2018-01-15 19:51:56 +00:00
Nav :: setSelected ( 'network' );
2012-06-15 00:46:58 +00:00
2018-01-21 15:48:15 +00:00
$content = '' ;
2015-04-09 22:42:03 +00:00
if ( $cid ) {
2015-10-30 11:47:48 +00:00
// If $cid belongs to a communitity forum or a privat goup,.add a mention to the status editor
2018-01-10 03:20:33 +00:00
$condition = [ " `id` = ? AND (`forum` OR `prv`) " , $cid ];
2018-07-20 12:19:26 +00:00
$contact = DBA :: selectFirst ( 'contact' , [ 'addr' , 'nick' ], $condition );
2018-07-21 12:46:04 +00:00
if ( DBA :: isResult ( $contact )) {
2018-01-21 15:48:15 +00:00
if ( $contact [ 'addr' ] != '' ) {
$content = '!' . $contact [ 'addr' ];
2017-09-13 06:43:43 +00:00
} else {
2018-01-21 15:48:15 +00:00
$content = '!' . $contact [ 'nick' ] . '+' . $cid ;
2017-09-13 06:43:43 +00:00
}
}
2015-04-09 22:42:03 +00:00
}
2018-01-15 13:05:12 +00:00
$x = [
2012-06-15 00:46:58 +00:00
'is_owner' => true ,
'allow_location' => $a -> user [ 'allow_location' ],
'default_location' => $a -> user [ 'default-location' ],
'nickname' => $a -> user [ 'nickname' ],
2018-08-18 06:20:50 +00:00
'lockstate' => ( $gid || $cid || $nets || ( is_array ( $a -> user ) &&
( strlen ( $a -> user [ 'allow_cid' ]) || strlen ( $a -> user [ 'allow_gid' ]) ||
strlen ( $a -> user [ 'deny_cid' ]) || strlen ( $a -> user [ 'deny_gid' ]))) ? 'lock' : 'unlock' ),
2018-03-02 23:41:24 +00:00
'default_perms' => ACL :: getDefaultUserPermissions ( $a -> user ),
2019-12-30 19:02:09 +00:00
'acl' => ACL :: getFullSelectorHTML ( DI :: page (), $a -> user , true , $default_permissions ),
2018-01-21 15:26:05 +00:00
'bang' => (( $gid || $cid || $nets ) ? '!' : '' ),
2012-06-15 00:46:58 +00:00
'visitor' => 'block' ,
2013-01-26 19:52:21 +00:00
'profile_uid' => local_user (),
2015-04-09 22:42:03 +00:00
'content' => $content ,
2018-01-15 13:05:12 +00:00
];
2012-06-15 00:46:58 +00:00
2018-01-04 00:29:52 +00:00
$o .= status_editor ( $a , $x );
2012-06-15 00:46:58 +00:00
}
2013-01-27 12:57:44 +00:00
// We don't have to deal with ACLs on this page. You're looking at everything
2012-06-15 00:46:58 +00:00
// that belongs to you, hence you can see all of it. We will filter by group if
2014-03-09 08:19:14 +00:00
// desired.
2012-06-15 00:46:58 +00:00
2018-01-21 15:48:15 +00:00
$sql_post_table = '' ;
2018-07-19 13:52:05 +00:00
$sql_options = ( $star ? " AND `thread`.`starred` " : '' );
$sql_options .= ( $bmark ? sprintf ( " AND `thread`.`post-type` = %d " , Item :: PT_PAGE ) : '' );
2014-03-09 08:19:14 +00:00
$sql_extra = $sql_options ;
2018-01-21 15:48:15 +00:00
$sql_extra2 = '' ;
$sql_extra3 = '' ;
$sql_table = '`thread`' ;
$sql_parent = '`iid`' ;
2012-06-15 00:46:58 +00:00
2017-09-13 06:43:43 +00:00
if ( $update ) {
2018-01-21 15:48:15 +00:00
$sql_table = '`item`' ;
$sql_parent = '`parent`' ;
2016-11-20 09:24:56 +00:00
$sql_post_table = " INNER JOIN `thread` ON `thread`.`iid` = `item`.`parent` " ;
2014-03-09 08:19:14 +00:00
}
2012-06-15 00:46:58 +00:00
2018-07-21 13:10:13 +00:00
$sql_nets = (( $nets ) ? sprintf ( " AND $sql_table .`network` = '%s' " , DBA :: escape ( $nets )) : '' );
$sql_tag_nets = (( $nets ) ? sprintf ( " AND `item`.`network` = '%s' " , DBA :: escape ( $nets )) : '' );
2012-06-15 00:46:58 +00:00
2018-01-11 08:26:30 +00:00
if ( $gid ) {
2018-07-20 12:19:26 +00:00
$group = DBA :: selectFirst ( 'group' , [ 'name' ], [ 'id' => $gid , 'uid' => local_user ()]);
2018-07-21 12:46:04 +00:00
if ( ! DBA :: isResult ( $group )) {
2018-01-11 08:26:30 +00:00
if ( $update ) {
2018-12-26 05:40:12 +00:00
exit ();
2018-01-11 08:26:30 +00:00
}
2020-01-18 19:52:34 +00:00
notice ( DI :: l10n () -> t ( 'No such group' ) . EOL );
2019-12-15 23:28:31 +00:00
DI :: baseUrl () -> redirect ( 'network/0' );
2012-06-15 00:46:58 +00:00
// NOTREACHED
}
2019-07-15 01:48:35 +00:00
$contacts = Group :: expand ( local_user (), [ $gid ]);
2014-03-09 08:19:14 +00:00
2017-09-13 06:43:43 +00:00
if (( is_array ( $contacts )) && count ( $contacts )) {
2018-01-21 15:48:15 +00:00
$contact_str_self = '' ;
2016-01-10 08:19:00 +00:00
2018-01-21 15:26:05 +00:00
$contact_str = implode ( ',' , $contacts );
2018-07-20 12:19:26 +00:00
$self = DBA :: selectFirst ( 'contact' , [ 'id' ], [ 'uid' => local_user (), 'self' => true ]);
2018-07-21 12:46:04 +00:00
if ( DBA :: isResult ( $self )) {
2018-01-21 15:48:15 +00:00
$contact_str_self = $self [ 'id' ];
2016-01-10 08:19:00 +00:00
}
2018-01-21 15:26:05 +00:00
$sql_post_table .= " INNER JOIN `item` AS `temp1` ON `temp1`.`id` = " . $sql_table . " . " . $sql_parent ;
2016-11-20 09:24:56 +00:00
$sql_extra3 .= " AND (`thread`.`contact-id` IN ( $contact_str ) " ;
2018-11-08 15:30:45 +00:00
$sql_extra3 .= " OR (`thread`.`contact-id` = ' $contact_str_self ' AND `temp1`.`allow_gid` LIKE ' " . Strings :: protectSprintf ( '%<' . intval ( $gid ) . '>%' ) . " ' AND `temp1`.`private`)) " ;
2016-01-10 08:19:00 +00:00
} else {
$sql_extra3 .= " AND false " ;
2020-01-18 19:52:34 +00:00
info ( DI :: l10n () -> t ( 'Group is empty' ));
2012-06-15 00:46:58 +00:00
}
2018-10-31 14:44:06 +00:00
$o = Renderer :: replaceMacros ( Renderer :: getMarkupTemplate ( 'section_title.tpl' ), [
2020-01-18 19:52:34 +00:00
'$title' => DI :: l10n () -> t ( 'Group: %s' , $group [ 'name' ])
2018-01-15 13:05:12 +00:00
]) . $o ;
2017-09-13 06:43:43 +00:00
} elseif ( $cid ) {
2018-01-10 03:20:33 +00:00
$fields = [ 'id' , 'name' , 'network' , 'writable' , 'nurl' ,
2018-01-21 15:26:05 +00:00
'forum' , 'prv' , 'contact-type' , 'addr' , 'thumb' , 'location' ];
2018-01-10 03:20:33 +00:00
$condition = [ " `id` = ? AND (NOT `blocked` OR `pending`) " , $cid ];
2018-07-20 12:19:26 +00:00
$contact = DBA :: selectFirst ( 'contact' , $fields , $condition );
2018-07-21 12:46:04 +00:00
if ( DBA :: isResult ( $contact )) {
2018-01-21 15:26:05 +00:00
$sql_extra = " AND " . $sql_table . " .`contact-id` = " . intval ( $cid );
2015-05-30 00:21:30 +00:00
2018-01-15 13:05:12 +00:00
$entries [ 0 ] = [
2015-11-29 03:57:42 +00:00
'id' => 'network' ,
2018-12-25 16:37:32 +00:00
'name' => $contact [ 'name' ],
2019-10-15 13:01:17 +00:00
'itemurl' => ( $contact [ 'addr' ] ? ? '' ) ? : $contact [ 'nurl' ],
2018-07-31 02:06:22 +00:00
'thumb' => ProxyUtils :: proxifyUrl ( $contact [ 'thumb' ], false , ProxyUtils :: SIZE_THUMB ),
2018-01-11 08:26:30 +00:00
'details' => $contact [ 'location' ],
2018-01-15 13:05:12 +00:00
];
2015-11-29 03:57:42 +00:00
2018-01-21 15:48:15 +00:00
$entries [ 0 ][ 'account_type' ] = Contact :: getAccountType ( $contact );
2016-10-01 20:03:27 +00:00
2018-10-31 14:44:06 +00:00
$o = Renderer :: replaceMacros ( Renderer :: getMarkupTemplate ( 'viewcontact_template.tpl' ), [
2015-11-29 03:57:42 +00:00
'contacts' => $entries ,
2015-11-30 00:24:22 +00:00
'id' => 'network' ,
2018-01-15 13:05:12 +00:00
]) . $o ;
2015-05-30 00:21:30 +00:00
2020-01-18 15:50:57 +00:00
if ( $contact [ 'network' ] === Protocol :: OSTATUS && $contact [ 'writable' ] && ! DI :: pConfig () -> get ( local_user (), 'system' , 'nowarn_insecure' )) {
2020-01-18 19:52:34 +00:00
notice ( DI :: l10n () -> t ( 'Private messages to this person are at risk of public disclosure.' ) . EOL );
2012-06-15 00:46:58 +00:00
}
2017-09-13 06:43:43 +00:00
} else {
2020-01-18 19:52:34 +00:00
notice ( DI :: l10n () -> t ( 'Invalid contact.' ) . EOL );
2019-12-15 23:28:31 +00:00
DI :: baseUrl () -> redirect ( 'network' );
2012-06-15 00:46:58 +00:00
// NOTREACHED
}
}
2020-01-19 20:21:13 +00:00
if ( ! $gid && ! $cid && ! $update && ! DI :: config () -> get ( 'theme' , 'hide_eventlist' )) {
2018-01-15 02:22:39 +00:00
$o .= Profile :: getBirthdays ();
2018-02-28 01:47:18 +00:00
$o .= Profile :: getEventsReminderHTML ();
2012-06-15 00:46:58 +00:00
}
2017-09-13 06:43:43 +00:00
if ( $datequery ) {
2019-07-07 21:30:33 +00:00
$sql_extra3 .= Strings :: protectSprintf ( sprintf ( " AND $sql_table .received <= '%s' " ,
2018-07-21 13:10:13 +00:00
DBA :: escape ( DateTimeFormat :: convert ( $datequery , 'UTC' , date_default_timezone_get ()))));
2012-06-15 00:46:58 +00:00
}
2017-09-13 06:43:43 +00:00
if ( $datequery2 ) {
2019-07-07 21:30:33 +00:00
$sql_extra3 .= Strings :: protectSprintf ( sprintf ( " AND $sql_table .received >= '%s' " ,
2018-07-21 13:10:13 +00:00
DBA :: escape ( DateTimeFormat :: convert ( $datequery2 , 'UTC' , date_default_timezone_get ()))));
2012-06-15 00:46:58 +00:00
}
2017-07-31 06:04:37 +00:00
if ( $conv ) {
2016-01-10 16:10:56 +00:00
$sql_extra3 .= " AND $sql_table .`mention` " ;
2017-07-31 06:04:37 +00:00
}
2017-09-13 06:43:43 +00:00
// Normal conversation view
2019-11-02 12:54:26 +00:00
if ( $order === 'post' ) {
2019-07-07 21:30:33 +00:00
$ordering = '`received`' ;
$order_mode = 'received' ;
2016-07-26 20:10:13 +00:00
} else {
2018-01-21 15:48:15 +00:00
$ordering = '`commented`' ;
2018-02-28 20:21:31 +00:00
$order_mode = 'commented' ;
2017-09-13 06:43:43 +00:00
}
2019-11-02 11:17:47 +00:00
2018-07-08 09:37:05 +00:00
$sql_order = " $sql_table . $ordering " ;
2012-06-15 00:46:58 +00:00
2018-10-24 06:15:24 +00:00
if ( ! empty ( $_GET [ 'offset' ])) {
2018-07-21 13:10:13 +00:00
$sql_range = sprintf ( " AND $sql_order <= '%s' " , DBA :: escape ( $_GET [ 'offset' ]));
2018-01-08 06:57:51 +00:00
} else {
$sql_range = '' ;
2017-09-13 06:43:43 +00:00
}
2012-06-15 00:46:58 +00:00
2019-12-16 00:30:34 +00:00
$pager = new Pager ( DI :: args () -> getQueryString ());
2018-10-24 06:15:24 +00:00
$pager_sql = networkPager ( $a , $pager , $update );
2017-09-13 09:20:08 +00:00
2018-01-07 22:07:16 +00:00
$last_date = '' ;
2017-09-13 06:43:43 +00:00
switch ( $order_mode ) {
case 'received' :
if ( $last_received != '' ) {
2018-01-07 22:07:16 +00:00
$last_date = $last_received ;
2018-07-21 13:10:13 +00:00
$sql_range .= sprintf ( " AND $sql_table .`received` < '%s' " , DBA :: escape ( $last_received ));
2018-10-24 06:15:24 +00:00
$pager -> setPage ( 1 );
$pager_sql = sprintf ( " LIMIT %d, %d " , $pager -> getStart (), $pager -> getItemsPerPage ());
2017-09-13 06:43:43 +00:00
}
break ;
case 'commented' :
if ( $last_commented != '' ) {
2018-01-07 22:07:16 +00:00
$last_date = $last_commented ;
2018-07-21 13:10:13 +00:00
$sql_range .= sprintf ( " AND $sql_table .`commented` < '%s' " , DBA :: escape ( $last_commented ));
2018-10-24 06:15:24 +00:00
$pager -> setPage ( 1 );
$pager_sql = sprintf ( " LIMIT %d, %d " , $pager -> getStart (), $pager -> getItemsPerPage ());
2017-09-13 06:43:43 +00:00
}
break ;
case 'created' :
if ( $last_created != '' ) {
2018-01-07 22:07:16 +00:00
$last_date = $last_created ;
2018-07-21 13:10:13 +00:00
$sql_range .= sprintf ( " AND $sql_table .`created` < '%s' " , DBA :: escape ( $last_created ));
2018-10-24 06:15:24 +00:00
$pager -> setPage ( 1 );
$pager_sql = sprintf ( " LIMIT %d, %d " , $pager -> getStart (), $pager -> getItemsPerPage ());
2017-09-13 06:43:43 +00:00
}
break ;
case 'id' :
2018-01-21 15:48:15 +00:00
if (( $last_id > 0 ) && ( $sql_table == '`thread`' )) {
2018-07-21 13:10:13 +00:00
$sql_range .= sprintf ( " AND $sql_table .`iid` < '%s' " , DBA :: escape ( $last_id ));
2018-10-24 06:15:24 +00:00
$pager -> setPage ( 1 );
$pager_sql = sprintf ( " LIMIT %d, %d " , $pager -> getStart (), $pager -> getItemsPerPage ());
2017-09-13 06:43:43 +00:00
}
break ;
}
2012-06-15 00:46:58 +00:00
2017-09-13 06:43:43 +00:00
// Fetch a page full of parent items for this page
if ( $update ) {
2018-02-27 21:10:05 +00:00
if ( ! empty ( $parent )) {
2018-02-27 23:25:29 +00:00
// Load only a single thread
2018-02-27 21:10:05 +00:00
$sql_extra4 = " `item`.`id` = " . intval ( $parent );
2013-12-09 23:13:19 +00:00
} else {
2018-02-27 23:25:29 +00:00
// Load all unseen items
2018-02-27 21:10:05 +00:00
$sql_extra4 = " `item`.`unseen` " ;
2020-01-19 20:21:13 +00:00
if ( DI :: config () -> get ( " system " , " like_no_comment " )) {
2018-06-27 18:09:33 +00:00
$sql_extra4 .= " AND `item`.`gravity` IN ( " . GRAVITY_PARENT . " , " . GRAVITY_COMMENT . " ) " ;
2018-02-27 22:37:11 +00:00
}
2019-11-02 12:54:26 +00:00
if ( $order === 'post' ) {
2018-02-28 06:36:41 +00:00
// Only show toplevel posts when updating posts in this order mode
$sql_extra4 .= " AND `item`.`id` = `item`.`parent` " ;
}
2018-02-27 23:25:29 +00:00
}
2018-02-27 06:28:53 +00:00
$r = q ( " SELECT `item`.`parent-uri` AS `uri`, `item`.`parent` AS `item_id`, $sql_order AS `order_date`
2018-02-25 21:33:15 +00:00
FROM `item` $sql_post_table
STRAIGHT_JOIN `contact` ON `contact` . `id` = `item` . `contact-id`
AND ( NOT `contact` . `blocked` OR `contact` . `pending` )
2018-08-19 12:46:11 +00:00
AND ( `item` . `gravity` != % d
2018-04-10 02:50:03 +00:00
OR `contact` . `uid` = `item` . `uid` AND `contact` . `self`
OR `contact` . `rel` IN ( % d , % d ) AND NOT `contact` . `readonly` )
2018-05-26 18:07:27 +00:00
LEFT JOIN `user-item` ON `user-item` . `iid` = `item` . `id` AND `user-item` . `uid` = % d
2018-02-27 21:10:05 +00:00
WHERE `item` . `uid` = % d AND `item` . `visible` AND NOT `item` . `deleted`
2018-05-26 18:07:27 +00:00
AND ( `user-item` . `hidden` IS NULL OR NOT `user-item` . `hidden` )
2018-02-27 21:10:05 +00:00
AND NOT `item` . `moderated` AND $sql_extra4
2018-01-08 06:57:51 +00:00
$sql_extra3 $sql_extra $sql_range $sql_nets
ORDER BY `order_date` DESC LIMIT 100 " ,
2018-08-19 12:46:11 +00:00
intval ( GRAVITY_PARENT ),
2018-07-25 02:53:46 +00:00
intval ( Contact :: SHARING ),
intval ( Contact :: FRIEND ),
2018-05-26 18:07:27 +00:00
intval ( local_user ()),
2017-09-13 06:43:43 +00:00
intval ( local_user ())
);
} else {
2018-02-25 21:33:15 +00:00
$r = q ( " SELECT `item`.`uri`, `thread`.`iid` AS `item_id`, $sql_order AS `order_date`
FROM `thread` $sql_post_table
STRAIGHT_JOIN `contact` ON `contact` . `id` = `thread` . `contact-id`
AND ( NOT `contact` . `blocked` OR `contact` . `pending` )
STRAIGHT_JOIN `item` ON `item` . `id` = `thread` . `iid`
2018-08-19 12:46:11 +00:00
AND ( `item` . `gravity` != % d
2018-04-10 02:50:03 +00:00
OR `contact` . `uid` = `item` . `uid` AND `contact` . `self`
OR `contact` . `rel` IN ( % d , % d ) AND NOT `contact` . `readonly` )
2018-05-26 18:07:27 +00:00
LEFT JOIN `user-item` ON `user-item` . `iid` = `item` . `id` AND `user-item` . `uid` = % d
2017-09-13 06:43:43 +00:00
WHERE `thread` . `uid` = % d AND `thread` . `visible` AND NOT `thread` . `deleted`
AND NOT `thread` . `moderated`
2018-05-26 18:07:27 +00:00
AND ( `user-item` . `hidden` IS NULL OR NOT `user-item` . `hidden` )
2018-01-08 06:57:51 +00:00
$sql_extra2 $sql_extra3 $sql_range $sql_extra $sql_nets
2018-02-25 21:33:15 +00:00
ORDER BY `order_date` DESC $pager_sql " ,
2018-08-19 12:46:11 +00:00
intval ( GRAVITY_PARENT ),
2018-07-25 02:53:46 +00:00
intval ( Contact :: SHARING ),
intval ( Contact :: FRIEND ),
2018-05-26 18:07:27 +00:00
intval ( local_user ()),
2017-09-13 06:43:43 +00:00
intval ( local_user ())
);
}
2013-10-14 22:49:13 +00:00
2018-01-08 06:57:51 +00:00
// Only show it when unfiltered (no groups, no networks, ...)
2018-10-06 03:17:44 +00:00
if ( in_array ( $nets , [ '' , Protocol :: ACTIVITYPUB , Protocol :: DFRN , Protocol :: DIASPORA , Protocol :: OSTATUS ]) && ( strlen ( $sql_extra . $sql_extra2 . $sql_extra3 ) == 0 )) {
2018-07-21 12:46:04 +00:00
if ( DBA :: isResult ( $r )) {
2018-01-15 06:59:20 +00:00
$top_limit = current ( $r )[ 'order_date' ];
$bottom_limit = end ( $r )[ 'order_date' ];
2018-02-25 21:33:15 +00:00
if ( empty ( $_SESSION [ 'network_last_top_limit' ]) || ( $_SESSION [ 'network_last_top_limit' ] < $top_limit )) {
$_SESSION [ 'network_last_top_limit' ] = $top_limit ;
}
2018-01-15 06:59:20 +00:00
} else {
2018-02-26 10:44:54 +00:00
$top_limit = $bottom_limit = DateTimeFormat :: utcNow ();
2018-01-15 06:59:20 +00:00
}
2018-01-07 22:07:16 +00:00
2018-01-08 06:57:51 +00:00
// When checking for updates we need to fetch from the newest date to the newest date before
2018-02-26 07:41:58 +00:00
// Only do this, when the last stored date isn't too long ago (10 times the update interval)
2020-01-18 15:50:57 +00:00
$browser_update = DI :: pConfig () -> get ( local_user (), 'system' , 'update_interval' , 40000 ) / 1000 ;
2018-02-26 07:41:58 +00:00
if (( $browser_update > 0 ) && $update && ! empty ( $_SESSION [ 'network_last_date' ]) &&
2018-02-26 10:44:54 +00:00
(( $bottom_limit < $_SESSION [ 'network_last_date' ]) || ( $top_limit == $bottom_limit )) &&
2018-02-26 07:41:58 +00:00
(( time () - $_SESSION [ 'network_last_date_timestamp' ]) < ( $browser_update * 10 ))) {
2018-01-08 06:57:51 +00:00
$bottom_limit = $_SESSION [ 'network_last_date' ];
}
2019-05-26 20:15:38 +00:00
$_SESSION [ 'network_last_date' ] = Session :: get ( 'network_last_top_limit' , $top_limit );
2018-02-25 21:33:15 +00:00
$_SESSION [ 'network_last_date_timestamp' ] = time ();
2018-01-08 06:57:51 +00:00
2018-01-07 22:07:16 +00:00
if ( $last_date > $top_limit ) {
$top_limit = $last_date ;
2018-10-24 06:15:24 +00:00
} elseif ( $pager -> getPage () == 1 ) {
2018-01-15 06:59:20 +00:00
// Highest possible top limit when we are on the first page
2018-01-27 02:38:34 +00:00
$top_limit = DateTimeFormat :: utcNow ();
2018-01-07 22:07:16 +00:00
}
2018-07-20 12:19:26 +00:00
$items = DBA :: p ( " SELECT `item`.`parent-uri` AS `uri`, 0 AS `item_id`, `item`. $ordering AS `order_date`, `author`.`url` AS `author-link` FROM `item`
2018-02-26 06:59:32 +00:00
STRAIGHT_JOIN ( SELECT `oid` FROM `term` WHERE `term` IN
2018-01-07 22:07:16 +00:00
( SELECT SUBSTR ( `term` , 2 ) FROM `search` WHERE `uid` = ? AND `term` LIKE '#%' ) AND `otype` = ? AND `type` = ? AND `uid` = 0 ) AS `term`
ON `item` . `id` = `term` . `oid`
2018-04-28 16:12:45 +00:00
STRAIGHT_JOIN `contact` AS `author` ON `author` . `id` = `item` . `author-id`
2019-07-09 05:20:34 +00:00
WHERE `item` . `uid` = 0 AND `item` . $ordering < ? AND `item` . $ordering > ? AND `item` . `gravity` = ?
2018-04-28 16:12:45 +00:00
AND NOT `author` . `hidden` AND NOT `author` . `blocked` " . $sql_tag_nets ,
2018-04-09 00:47:16 +00:00
local_user (), TERM_OBJ_POST , TERM_HASHTAG ,
2019-07-09 05:20:34 +00:00
$top_limit , $bottom_limit , GRAVITY_PARENT );
2018-02-25 21:58:21 +00:00
2018-07-21 02:03:40 +00:00
$data = DBA :: toArray ( $items );
2018-01-07 22:07:16 +00:00
if ( count ( $data ) > 0 ) {
2018-02-25 21:33:15 +00:00
$tag_top_limit = current ( $data )[ 'order_date' ];
if ( $_SESSION [ 'network_last_date' ] < $tag_top_limit ) {
$_SESSION [ 'network_last_date' ] = $tag_top_limit ;
}
2018-10-29 21:20:46 +00:00
Logger :: log ( 'Tagged items: ' . count ( $data ) . ' - ' . $bottom_limit . ' - ' . $top_limit . ' - ' . local_user () . ' - ' . ( int ) $update );
2018-02-25 21:33:15 +00:00
$s = [];
foreach ( $r as $item ) {
$s [ $item [ 'uri' ]] = $item ;
}
foreach ( $data as $item ) {
2018-04-28 16:12:45 +00:00
// Don't show hash tag posts from blocked or ignored contacts
$condition = [ " `nurl` = ? AND `uid` = ? AND (`blocked` OR `readonly`) " ,
2018-11-08 16:28:29 +00:00
Strings :: normaliseLink ( $item [ 'author-link' ]), local_user ()];
2018-07-20 12:19:26 +00:00
if ( ! DBA :: exists ( 'contact' , $condition )) {
2018-04-28 16:12:45 +00:00
$s [ $item [ 'uri' ]] = $item ;
}
2018-02-25 21:33:15 +00:00
}
$r = $s ;
2018-01-07 22:07:16 +00:00
}
}
2017-09-13 06:43:43 +00:00
$parents_str = '' ;
2018-01-21 15:48:15 +00:00
$date_offset = '' ;
2017-09-13 06:43:43 +00:00
2018-02-25 21:33:15 +00:00
$items = $r ;
2017-07-31 06:04:37 +00:00
2018-07-21 12:46:04 +00:00
if ( DBA :: isResult ( $items )) {
2018-02-25 21:33:15 +00:00
$parents_arr = [];
2012-06-15 00:46:58 +00:00
2018-02-25 21:33:15 +00:00
foreach ( $items as $item ) {
2018-02-26 22:15:57 +00:00
if ( $date_offset < $item [ 'order_date' ]) {
$date_offset = $item [ 'order_date' ];
}
2018-02-27 13:23:25 +00:00
if ( ! in_array ( $item [ 'item_id' ], $parents_arr ) && ( $item [ 'item_id' ] > 0 )) {
2018-02-25 21:33:15 +00:00
$parents_arr [] = $item [ 'item_id' ];
2013-12-08 13:49:24 +00:00
}
2012-06-15 00:46:58 +00:00
}
2018-02-25 21:33:15 +00:00
$parents_str = implode ( ', ' , $parents_arr );
2017-09-13 06:43:43 +00:00
}
2012-09-29 23:56:50 +00:00
2018-11-30 14:06:22 +00:00
if ( ! empty ( $_GET [ 'offset' ])) {
2018-01-21 15:48:15 +00:00
$date_offset = $_GET [ 'offset' ];
2012-06-15 00:46:58 +00:00
}
2019-12-16 00:30:34 +00:00
$query_string = DI :: args () -> getQueryString ();
2018-10-24 06:15:24 +00:00
if ( $date_offset && ! preg_match ( '/[?&].offset=/' , $query_string )) {
$query_string .= '&offset=' . urlencode ( $date_offset );
}
$pager -> setQueryString ( $query_string );
2017-09-13 06:43:43 +00:00
2012-06-15 00:46:58 +00:00
// We aren't going to try and figure out at the item, group, and page
// level which items you've seen and which you haven't. If you're looking
2014-03-09 08:19:14 +00:00
// at the top level network page just mark everything seen.
2013-01-13 16:13:01 +00:00
2018-01-11 08:26:30 +00:00
if ( ! $gid && ! $cid && ! $star ) {
2018-01-15 13:05:12 +00:00
$condition = [ 'unseen' => true , 'uid' => local_user ()];
2017-10-07 21:51:03 +00:00
networkSetSeen ( $condition );
2017-09-13 06:43:43 +00:00
} elseif ( $parents_str ) {
2018-07-21 13:10:13 +00:00
$condition = [ " `uid` = ? AND `unseen` AND `parent` IN ( " . DBA :: escape ( $parents_str ) . " ) " , local_user ()];
2017-10-07 21:51:03 +00:00
networkSetSeen ( $condition );
2012-11-13 10:30:43 +00:00
}
2012-06-15 00:46:58 +00:00
2017-09-13 06:43:43 +00:00
$mode = 'network' ;
2018-10-24 06:15:24 +00:00
$o .= networkConversation ( $a , $items , $pager , $mode , $update , $ordering );
2012-06-15 00:46:58 +00:00
return $o ;
}
2016-02-07 14:11:34 +00:00
2016-06-23 22:33:31 +00:00
/**
2020-01-19 06:05:23 +00:00
* Get the network tabs menu
2017-01-09 12:14:25 +00:00
*
2017-04-30 04:17:49 +00:00
* @ param App $a The global App
2016-06-23 22:33:31 +00:00
* @ return string Html of the networktab
2019-01-07 15:24:06 +00:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
2016-06-23 22:33:31 +00:00
*/
2017-12-01 13:32:21 +00:00
function network_tabs ( App $a )
{
2016-06-23 22:33:31 +00:00
// item filter tabs
/// @TODO fix this logic, reduce duplication
2019-10-27 14:08:14 +00:00
/// DI::page()['content'] .= '<div class="tabs-wrapper">';
2019-11-02 12:54:26 +00:00
list ( $no_active , $all_active , $post_active , $conv_active , $new_active , $starred_active , $bookmarked_active ) = network_query_get_sel_tab ( $a );
2017-12-01 13:32:21 +00:00
2019-11-02 12:54:26 +00:00
// if no tabs are selected, defaults to activitys
2017-12-01 13:32:21 +00:00
if ( $no_active == 'active' ) {
$all_active = 'active' ;
}
2016-06-23 22:33:31 +00:00
2019-12-16 00:33:13 +00:00
$cmd = DI :: args () -> getCommand ();
2016-06-23 22:33:31 +00:00
2020-01-13 20:10:13 +00:00
$def_param = [];
if ( ! empty ( $_GET [ 'cid' ])) {
$def_param [ 'cid' ] = $_GET [ 'cid' ];
}
2016-06-23 22:33:31 +00:00
// tabs
2018-01-15 13:05:12 +00:00
$tabs = [
[
2020-01-18 19:52:34 +00:00
'label' => DI :: l10n () -> t ( 'Latest Activity' ),
2020-01-13 20:10:13 +00:00
'url' => $cmd . '?' . http_build_query ( array_merge ( $def_param , [ 'order' => 'activity' ])),
2016-06-23 22:33:31 +00:00
'sel' => $all_active ,
2020-01-18 19:52:34 +00:00
'title' => DI :: l10n () -> t ( 'Sort by latest activity' ),
2019-11-02 12:54:26 +00:00
'id' => 'activity-order-tab' ,
2018-01-21 15:48:15 +00:00
'accesskey' => 'e' ,
2018-01-15 13:05:12 +00:00
],
[
2020-01-18 19:52:34 +00:00
'label' => DI :: l10n () -> t ( 'Latest Posts' ),
2020-01-13 20:10:13 +00:00
'url' => $cmd . '?' . http_build_query ( array_merge ( $def_param , [ 'order' => 'post' ])),
2019-11-02 12:54:26 +00:00
'sel' => $post_active ,
2020-01-18 19:52:34 +00:00
'title' => DI :: l10n () -> t ( 'Sort by post received date' ),
2019-11-02 12:54:26 +00:00
'id' => 'post-order-tab' ,
2018-01-21 15:48:15 +00:00
'accesskey' => 't' ,
2018-01-15 13:05:12 +00:00
],
];
2016-06-23 22:33:31 +00:00
2018-11-18 20:13:46 +00:00
$tabs [] = [
2020-01-18 19:52:34 +00:00
'label' => DI :: l10n () -> t ( 'Personal' ),
2020-01-13 20:10:13 +00:00
'url' => $cmd . '?' . http_build_query ( array_merge ( $def_param , [ 'conv' => true ])),
2018-11-18 20:13:46 +00:00
'sel' => $conv_active ,
2020-01-18 19:52:34 +00:00
'title' => DI :: l10n () -> t ( 'Posts that mention or involve you' ),
2018-11-18 20:13:46 +00:00
'id' => 'personal-tab' ,
'accesskey' => 'r' ,
];
2016-06-23 22:33:31 +00:00
2018-01-21 15:26:05 +00:00
if ( Feature :: isEnabled ( local_user (), 'new_tab' )) {
2018-01-15 13:05:12 +00:00
$tabs [] = [
2020-01-18 19:52:34 +00:00
'label' => DI :: l10n () -> t ( 'New' ),
2020-01-13 20:10:13 +00:00
'url' => $cmd . '?' . http_build_query ( array_merge ( $def_param , [ 'new' => true ])),
2016-06-23 22:33:31 +00:00
'sel' => $new_active ,
2020-01-18 19:52:34 +00:00
'title' => DI :: l10n () -> t ( 'Activity Stream - by date' ),
2016-06-23 22:33:31 +00:00
'id' => 'activitiy-by-date-tab' ,
2018-01-21 15:48:15 +00:00
'accesskey' => 'w' ,
2018-01-15 13:05:12 +00:00
];
2016-06-23 22:33:31 +00:00
}
2018-01-21 15:26:05 +00:00
if ( Feature :: isEnabled ( local_user (), 'link_tab' )) {
2018-01-15 13:05:12 +00:00
$tabs [] = [
2020-01-18 19:52:34 +00:00
'label' => DI :: l10n () -> t ( 'Shared Links' ),
2020-01-13 20:10:13 +00:00
'url' => $cmd . '?' . http_build_query ( array_merge ( $def_param , [ 'bmark' => true ])),
2016-06-23 22:33:31 +00:00
'sel' => $bookmarked_active ,
2020-01-18 19:52:34 +00:00
'title' => DI :: l10n () -> t ( 'Interesting Links' ),
2016-06-23 22:33:31 +00:00
'id' => 'shared-links-tab' ,
2018-01-21 15:48:15 +00:00
'accesskey' => 'b' ,
2018-01-15 13:05:12 +00:00
];
2016-06-23 22:33:31 +00:00
}
2018-11-18 20:13:46 +00:00
$tabs [] = [
2020-01-18 19:52:34 +00:00
'label' => DI :: l10n () -> t ( 'Starred' ),
2020-01-13 20:10:13 +00:00
'url' => $cmd . '?' . http_build_query ( array_merge ( $def_param , [ 'star' => true ])),
2018-11-18 20:13:46 +00:00
'sel' => $starred_active ,
2020-01-18 19:52:34 +00:00
'title' => DI :: l10n () -> t ( 'Favourite Posts' ),
2018-11-18 20:13:46 +00:00
'id' => 'starred-posts-tab' ,
'accesskey' => 'm' ,
];
2016-06-23 22:33:31 +00:00
2017-09-13 06:43:43 +00:00
// save selected tab, but only if not in file mode
2018-11-30 14:06:22 +00:00
if ( empty ( $_GET [ 'file' ])) {
2020-01-18 15:54:50 +00:00
DI :: pConfig () -> set ( local_user (), 'network.view' , 'tab.selected' , [
2019-11-02 12:54:26 +00:00
$all_active , $post_active , $conv_active , $new_active , $starred_active , $bookmarked_active
2018-01-21 15:26:05 +00:00
]);
2016-06-23 22:33:31 +00:00
}
2018-01-15 13:05:12 +00:00
$arr = [ 'tabs' => $tabs ];
2018-12-26 06:06:24 +00:00
Hook :: callAll ( 'network_tabs' , $arr );
2017-01-09 12:14:25 +00:00
2018-10-31 14:44:06 +00:00
$tpl = Renderer :: getMarkupTemplate ( 'common_tabs.tpl' );
2016-06-23 22:33:31 +00:00
2018-10-31 14:35:50 +00:00
return Renderer :: replaceMacros ( $tpl , [ '$tabs' => $arr [ 'tabs' ]]);
2016-06-23 22:33:31 +00:00
// --- end item filter tabs
}
2018-10-24 06:15:24 +00:00
/**
* Network hook into the HTML head to enable infinite scroll .
*
* Since the HTML head is built after the module content has been generated , we need to retrieve the base query string
* of the page to make the correct asynchronous call . This is obtained through the Pager that was instantiated in
* networkThreadedView or networkFlatView .
*
2019-01-07 15:24:06 +00:00
* @ param App $a
2018-10-24 06:15:24 +00:00
* @ param string $htmlhead The head tag HTML string
2019-01-07 06:07:42 +00:00
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ global Pager $pager
2018-10-24 06:15:24 +00:00
*/
function network_infinite_scroll_head ( App $a , & $htmlhead )
{
/// @TODO this will have to be converted to a static property of the converted Module\Network class
2019-01-07 06:07:42 +00:00
/**
* @ var $pager Pager
*/
2018-10-24 06:15:24 +00:00
global $pager ;
2020-01-18 15:50:57 +00:00
if ( DI :: pConfig () -> get ( local_user (), 'system' , 'infinite_scroll' )
2019-10-15 13:01:17 +00:00
&& ( $_GET [ 'mode' ] ? ? '' ) != 'minimal'
2018-10-24 06:15:24 +00:00
) {
2018-10-31 14:44:06 +00:00
$tpl = Renderer :: getMarkupTemplate ( 'infinite_scroll_head.tpl' );
2018-10-31 14:35:50 +00:00
$htmlhead .= Renderer :: replaceMacros ( $tpl , [
2018-10-24 06:15:24 +00:00
'$pageno' => $pager -> getPage (),
'$reload_uri' => $pager -> getBaseQueryString ()
]);
}
2018-11-18 20:13:46 +00:00
}