2011-07-05 03:57:07 +00:00
< ? php
2018-01-15 19:51:56 +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 />.
*
2018-01-15 19:51:56 +00:00
*/
2018-02-26 01:03:03 +00:00
2017-04-30 04:07:00 +00:00
use Friendica\App ;
2019-08-06 11:37:48 +00:00
use Friendica\Content\Feature ;
2018-01-15 19:51:56 +00:00
use Friendica\Content\Nav ;
2018-10-24 06:15:24 +00:00
use Friendica\Content\Pager ;
2019-08-06 11:37:48 +00:00
use Friendica\Content\Widget\TrendingTags ;
2018-03-02 23:41:24 +00:00
use Friendica\Core\ACL ;
2018-10-31 14:35:50 +00:00
use Friendica\Core\Renderer ;
2019-12-27 13:07:17 +00:00
use Friendica\Core\Session ;
2018-07-20 12:19:26 +00:00
use Friendica\Database\DBA ;
2019-12-16 00:12:07 +00:00
use Friendica\DI ;
2018-08-28 20:44:39 +00:00
use Friendica\Model\Item ;
2019-01-06 22:08:35 +00:00
use Friendica\Model\User ;
2017-03-26 05:29:24 +00:00
2018-01-05 00:42:48 +00:00
function community_content ( App $a , $update = 0 )
{
2011-07-05 03:57:07 +00:00
$o = '' ;
2020-01-19 20:21:13 +00:00
if ( DI :: config () -> get ( 'system' , 'block_public' ) && ! Session :: isAuthenticated ()) {
2020-01-18 19:52:34 +00:00
notice ( DI :: l10n () -> t ( 'Public access denied.' ) . EOL );
2011-07-05 03:57:07 +00:00
return ;
}
2020-01-19 20:21:13 +00:00
$page_style = DI :: config () -> get ( 'system' , 'community_page_style' );
2018-01-04 13:04:12 +00:00
2018-04-23 11:14:25 +00:00
if ( $page_style == CP_NO_INTERNAL_COMMUNITY ) {
2020-01-18 19:52:34 +00:00
notice ( DI :: l10n () -> t ( 'Access denied.' ) . EOL );
2018-04-23 11:14:25 +00:00
return ;
}
2018-08-21 15:39:49 +00:00
$accounttype = null ;
if ( $a -> argc > 2 ) {
switch ( $a -> argv [ 2 ]) {
case 'person' :
2019-01-06 22:08:35 +00:00
$accounttype = User :: ACCOUNT_TYPE_PERSON ;
2018-08-21 15:39:49 +00:00
break ;
case 'organisation' :
2019-01-06 22:08:35 +00:00
$accounttype = User :: ACCOUNT_TYPE_ORGANISATION ;
2018-08-21 15:39:49 +00:00
break ;
case 'news' :
2019-01-06 22:08:35 +00:00
$accounttype = User :: ACCOUNT_TYPE_NEWS ;
2018-08-21 15:39:49 +00:00
break ;
case 'community' :
2019-01-06 22:08:35 +00:00
$accounttype = User :: ACCOUNT_TYPE_COMMUNITY ;
2018-08-21 15:39:49 +00:00
break ;
}
}
2018-01-04 13:04:12 +00:00
if ( $a -> argc > 1 ) {
$content = $a -> argv [ 1 ];
} else {
2020-01-19 20:21:13 +00:00
if ( ! empty ( DI :: config () -> get ( 'system' , 'singleuser' ))) {
2018-01-05 20:11:35 +00:00
// On single user systems only the global page does make sense
$content = 'global' ;
} else {
// When only the global community is allowed, we use this as default
$content = $page_style == CP_GLOBAL_COMMUNITY ? 'global' : 'local' ;
}
2018-01-04 13:04:12 +00:00
}
if ( ! in_array ( $content , [ 'local' , 'global' ])) {
2020-01-18 19:52:34 +00:00
notice ( DI :: l10n () -> t ( 'Community option not available.' ) . EOL );
2011-07-05 03:57:07 +00:00
return ;
}
2018-01-04 13:04:12 +00:00
// Check if we are allowed to display the content to visitors
if ( ! local_user ()) {
$available = $page_style == CP_USERS_AND_GLOBAL ;
if ( ! $available ) {
$available = ( $page_style == CP_USERS_ON_SERVER ) && ( $content == 'local' );
}
if ( ! $available ) {
$available = ( $page_style == CP_GLOBAL_COMMUNITY ) && ( $content == 'global' );
}
if ( ! $available ) {
2020-01-18 19:52:34 +00:00
notice ( DI :: l10n () -> t ( 'Not available.' ) . EOL );
2018-01-04 13:04:12 +00:00
return ;
}
}
2018-01-03 13:27:43 +00:00
if ( ! $update ) {
2018-01-04 14:02:04 +00:00
$tabs = [];
2020-01-19 20:21:13 +00:00
if (( local_user () || in_array ( $page_style , [ CP_USERS_AND_GLOBAL , CP_USERS_ON_SERVER ])) && empty ( DI :: config () -> get ( 'system' , 'singleuser' ))) {
2018-01-15 13:05:12 +00:00
$tabs [] = [
2020-01-18 19:52:34 +00:00
'label' => DI :: l10n () -> t ( 'Local Community' ),
2018-01-05 00:42:48 +00:00
'url' => 'community/local' ,
'sel' => $content == 'local' ? 'active' : '' ,
2020-01-18 19:52:34 +00:00
'title' => DI :: l10n () -> t ( 'Posts from local users on this server' ),
2018-01-05 00:42:48 +00:00
'id' => 'community-local-tab' ,
'accesskey' => 'l'
2018-01-15 13:05:12 +00:00
];
2018-01-04 14:22:04 +00:00
}
if ( local_user () || in_array ( $page_style , [ CP_USERS_AND_GLOBAL , CP_GLOBAL_COMMUNITY ])) {
2018-01-15 13:05:12 +00:00
$tabs [] = [
2020-01-18 19:52:34 +00:00
'label' => DI :: l10n () -> t ( 'Global Community' ),
2018-01-05 00:42:48 +00:00
'url' => 'community/global' ,
'sel' => $content == 'global' ? 'active' : '' ,
2020-01-18 19:52:34 +00:00
'title' => DI :: l10n () -> t ( 'Posts from users of the whole federated network' ),
2018-01-05 00:42:48 +00:00
'id' => 'community-global-tab' ,
'accesskey' => 'g'
2018-01-15 13:05:12 +00:00
];
2018-01-04 14:22:04 +00:00
}
2018-01-04 14:02:04 +00:00
2018-10-31 14:44:06 +00:00
$tab_tpl = Renderer :: getMarkupTemplate ( 'common_tabs.tpl' );
2018-10-31 14:35:50 +00:00
$o .= Renderer :: replaceMacros ( $tab_tpl , [ '$tabs' => $tabs ]);
2018-01-04 14:02:04 +00:00
2018-01-15 19:51:56 +00:00
Nav :: setSelected ( 'community' );
2018-01-05 13:48:06 +00:00
// We need the editor here to be able to reshare an item.
if ( local_user ()) {
2018-01-15 13:05:12 +00:00
$x = [
2018-01-05 13:48:06 +00:00
'is_owner' => true ,
'allow_location' => $a -> user [ 'allow_location' ],
'default_location' => $a -> user [ 'default-location' ],
'nickname' => $a -> user [ 'nickname' ],
'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' ),
2019-12-30 19:02:09 +00:00
'acl' => ACL :: getFullSelectorHTML ( DI :: page (), $a -> user , true ),
2018-01-05 13:48:06 +00:00
'bang' => '' ,
'visitor' => 'block' ,
'profile_uid' => local_user (),
2018-01-15 13:05:12 +00:00
];
2018-01-05 13:48:06 +00:00
$o .= status_editor ( $a , $x , 0 , true );
}
2011-07-05 03:57:07 +00:00
}
2018-01-31 23:22:41 +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' , 20 );
2018-01-31 23:22:41 +00:00
} else {
2020-01-18 15:50:57 +00:00
$itemspage_network = DI :: pConfig () -> get ( local_user (), 'system' , 'itemspage_network' , 40 );
2018-01-31 23:22:41 +00:00
}
2018-01-04 10:51:49 +00:00
2018-01-31 23:22:41 +00:00
// 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 ;
2017-03-26 05:29:24 +00:00
}
2011-07-05 03:57:07 +00:00
2019-12-16 00:30:34 +00:00
$pager = new Pager ( DI :: args () -> getQueryString (), $itemspage_network );
2018-01-31 23:22:41 +00:00
2018-10-24 06:15:24 +00:00
$r = community_getitems ( $pager -> getStart (), $pager -> getItemsPerPage (), $content , $accounttype );
2011-07-05 03:57:07 +00:00
2018-07-21 12:46:04 +00:00
if ( ! DBA :: isResult ( $r )) {
2020-01-18 19:52:34 +00:00
info ( DI :: l10n () -> t ( 'No results.' ) . EOL );
2012-07-14 18:21:58 +00:00
return $o ;
}
2020-01-19 20:21:13 +00:00
$maxpostperauthor = ( int ) DI :: config () -> get ( 'system' , 'max_author_posts_community_page' );
2014-06-10 18:21:43 +00:00
2018-01-04 13:04:12 +00:00
if (( $maxpostperauthor != 0 ) && ( $content == 'local' )) {
2014-07-10 21:13:50 +00:00
$count = 1 ;
2014-06-10 18:21:43 +00:00
$previousauthor = " " ;
$numposts = 0 ;
2018-01-15 13:05:12 +00:00
$s = [];
2014-06-10 18:21:43 +00:00
2014-07-10 21:13:50 +00:00
do {
2018-01-05 00:42:48 +00:00
foreach ( $r as $item ) {
2017-03-26 05:29:24 +00:00
if ( $previousauthor == $item [ " author-link " ]) {
2014-07-10 21:13:50 +00:00
++ $numposts ;
2017-03-26 05:29:24 +00:00
} else {
2014-07-10 21:13:50 +00:00
$numposts = 0 ;
2017-03-26 05:29:24 +00:00
}
2014-07-10 21:13:50 +00:00
$previousauthor = $item [ " author-link " ];
2014-06-10 18:21:43 +00:00
2018-10-24 06:15:24 +00:00
if (( $numposts < $maxpostperauthor ) && ( count ( $s ) < $pager -> getItemsPerPage ())) {
2014-07-10 21:13:50 +00:00
$s [] = $item ;
2017-03-26 05:29:24 +00:00
}
2014-07-10 21:13:50 +00:00
}
2018-10-24 06:15:24 +00:00
if ( count ( $s ) < $pager -> getItemsPerPage ()) {
$r = community_getitems ( $pager -> getStart () + ( $count * $pager -> getItemsPerPage ()), $pager -> getItemsPerPage (), $content , $accounttype );
2017-03-26 05:29:24 +00:00
}
2018-10-24 06:15:24 +00:00
} while (( count ( $s ) < $pager -> getItemsPerPage ()) && ( ++ $count < 50 ) && ( count ( $r ) > 0 ));
2017-03-26 05:29:24 +00:00
} else {
2014-06-10 18:21:43 +00:00
$s = $r ;
2017-03-26 05:29:24 +00:00
}
2011-07-05 03:57:07 +00:00
2020-02-14 04:40:00 +00:00
$o .= conversation ( $a , $s , 'community' , $update , false , 'commented' , local_user ());
2011-07-05 03:57:07 +00:00
2018-01-04 15:46:56 +00:00
if ( ! $update ) {
2018-10-24 06:15:24 +00:00
$o .= $pager -> renderMinimal ( count ( $r ));
2018-01-04 15:46:56 +00:00
}
2011-07-05 03:57:07 +00:00
2019-12-30 19:02:09 +00:00
if ( empty ( DI :: page ()[ 'aside' ])) {
DI :: page ()[ 'aside' ] = '' ;
2019-08-06 01:01:04 +00:00
}
2019-08-06 11:37:48 +00:00
if ( Feature :: isEnabled ( local_user (), 'trending_tags' )) {
2019-12-30 19:02:09 +00:00
DI :: page ()[ 'aside' ] .= TrendingTags :: getHTML ( $content );
2019-08-06 01:01:04 +00:00
}
2018-10-31 14:44:06 +00:00
$t = Renderer :: getMarkupTemplate ( " community.tpl " );
2018-10-31 14:35:50 +00:00
return Renderer :: replaceMacros ( $t , [
2017-11-10 19:25:17 +00:00
'$content' => $o ,
2018-01-04 14:02:04 +00:00
'$header' => '' ,
2020-01-19 20:21:13 +00:00
'$show_global_community_hint' => ( $content == 'global' ) && DI :: config () -> get ( 'system' , 'show_global_community_hint' ),
2020-01-18 19:52:34 +00:00
'$global_community_hint' => DI :: l10n () -> t ( " This community stream shows all public posts received by this node. They may not reflect the opinions of this node’ s users. " )
2018-01-15 13:05:12 +00:00
]);
2011-07-05 03:57:07 +00:00
}
2018-08-21 15:39:49 +00:00
function community_getitems ( $start , $itemspage , $content , $accounttype )
2018-01-05 00:42:48 +00:00
{
2018-01-04 13:04:12 +00:00
if ( $content == 'local' ) {
2018-08-21 15:39:49 +00:00
if ( ! is_null ( $accounttype )) {
$sql_accounttype = " AND `user`.`account-type` = ? " ;
$values = [ $accounttype , $start , $itemspage ];
} else {
$sql_accounttype = " " ;
$values = [ $start , $itemspage ];
}
2019-09-18 05:56:06 +00:00
/// @todo Use "unsearchable" here as well (instead of "hidewall")
2018-07-20 12:19:26 +00:00
$r = DBA :: p ( " SELECT `item`.`uri`, `author`.`url` AS `author-link` FROM `thread`
2019-02-10 06:37:31 +00:00
STRAIGHT_JOIN `user` ON `user` . `uid` = `thread` . `uid` AND NOT `user` . `hidewall`
STRAIGHT_JOIN `item` ON `item` . `id` = `thread` . `iid`
STRAIGHT_JOIN `contact` AS `author` ON `author` . `id` = `item` . `author-id`
2018-01-04 13:04:12 +00:00
WHERE `thread` . `visible` AND NOT `thread` . `deleted` AND NOT `thread` . `moderated`
2018-08-21 15:39:49 +00:00
AND NOT `thread` . `private` AND `thread` . `wall` AND `thread` . `origin` $sql_accounttype
ORDER BY `thread` . `commented` DESC LIMIT ? , ? " , $values );
2018-07-21 02:03:40 +00:00
return DBA :: toArray ( $r );
2018-01-04 13:04:12 +00:00
} elseif ( $content == 'global' ) {
2018-08-21 15:39:49 +00:00
if ( ! is_null ( $accounttype )) {
2019-09-18 05:20:33 +00:00
$condition = [ " `uid` = ? AND NOT `author`.`unsearchable` AND NOT `owner`.`unsearchable` AND `owner`.`contact-type` = ? " , 0 , $accounttype ];
2018-08-21 15:39:49 +00:00
} else {
2019-09-18 05:20:33 +00:00
$condition = [ " `uid` = ? AND NOT `author`.`unsearchable` AND NOT `owner`.`unsearchable` " , 0 ];
2018-08-21 15:39:49 +00:00
}
2018-08-28 20:44:39 +00:00
$r = Item :: selectThreadForUser ( 0 , [ 'uri' ], $condition , [ 'order' => [ 'commented' => true ], 'limit' => [ $start , $itemspage ]]);
2018-07-21 02:03:40 +00:00
return DBA :: toArray ( $r );
2018-01-04 13:04:12 +00:00
}
// Should never happen
2018-01-15 13:05:12 +00:00
return [];
2014-07-10 21:13:50 +00:00
}