* Type of the community page
* @{
*/
-define('CP_NO_COMMUNITY_PAGE', -1);
+define('CP_NO_COMMUNITY_PAGE', -1);
define('CP_USERS_ON_SERVER', 0);
define('CP_GLOBAL_COMMUNITY', 1);
+define('CP_USERS_AND_GLOBAL', 2);
/**
* @}
*/
if (strlen($gdir)) {
$gdirpath = zrl($gdir, true);
}
- } elseif (Config::get('system', 'community_page_style') == CP_USERS_ON_SERVER) {
+ }
+
+ if (in_array(Config::get('system', 'community_page_style'), [CP_USERS_ON_SERVER, CP_USERS_AND_GLOBAL])) {
$nav['community'] = array('community', t('Community'), '', t('Conversations on this site'));
- } elseif (Config::get('system', 'community_page_style') == CP_GLOBAL_COMMUNITY) {
- $nav['community'] = array('community', t('Community'), '', t('Conversations on the network'));
+ }
+
+ if (in_array(Config::get('system', 'community_page_style'), [CP_GLOBAL_COMMUNITY, CP_USERS_AND_GLOBAL])) {
+ $nav['global'] = array('global', t('Global Timeline'), '', t('Conversations on the network'));
}
if (local_user()) {
function nav_set_selected($item){
$a = get_app();
$a->nav_sel = array(
+ 'global' => null,
'community' => null,
'network' => null,
'home' => null,
}
// Controller class routing
- if (! $a->module_loaded && class_exists('Friendica\\Module\\' . ucfirst($a->module))) {
- $a->module_class = 'Friendica\\Module\\' . ucfirst($a->module);
- $a->module_loaded = true;
+ $classes = ['Friendica\\Module\\' . ucfirst($a->module), 'Friendica\\Module\\' . ucfirst($a->module) . 'Module'];
+ foreach ($classes as $class) {
+ if (!$a->module_loaded && class_exists($class)) {
+ $a->module_class = $class;
+ $a->module_loaded = true;
+ break;
+ }
}
/**
$community_page_style_choices = array(
CP_NO_COMMUNITY_PAGE => t("No community page"),
CP_USERS_ON_SERVER => t("Public postings from users of this site"),
- CP_GLOBAL_COMMUNITY => t("Global community page")
+ CP_GLOBAL_COMMUNITY => t("Global community page"),
+ CP_USERS_AND_GLOBAL => t("Public user postings and global postings")
);
/* OStatus conversation poll choices */
use Friendica\Database\DBM;
function community_init(App $a) {
- if (! local_user()) {
+ if (!local_user()) {
unset($_SESSION['theme']);
unset($_SESSION['mobile-theme']);
}
function community_content(App $a, $update = 0) {
$o = '';
- if ((Config::get('system','block_public')) && (! local_user()) && (! remote_user())) {
- notice( t('Public access denied.') . EOL);
+ if (Config::get('system','block_public') && !local_user() && !remote_user()) {
+ notice(t('Public access denied.') . EOL);
return;
}
- if (Config::get('system','community_page_style') == CP_NO_COMMUNITY_PAGE) {
- notice( t('Not available.') . EOL);
+ if (!in_array(Config::get('system','community_page_style'), [CP_USERS_ON_SERVER, CP_USERS_AND_GLOBAL])) {
+ notice(t('Not available.') . EOL);
return;
}
- require_once("include/bbcode.php");
- require_once('include/security.php');
- require_once('include/conversation.php');
+ require_once 'include/bbcode.php';
+ require_once 'include/security.php';
+ require_once 'include/conversation.php';
- if (! $update) {
+ if (!$update) {
nav_set_selected('community');
}
if (x($a->data,'search')) {
$search = notags(trim($a->data['search']));
} else {
- $search = ((x($_GET,'search')) ? notags(trim(rawurldecode($_GET['search']))) : '');
+ $search = (x($_GET,'search') ? notags(trim(rawurldecode($_GET['search']))) : '');
}
// Here is the way permissions work in this module...
$r = community_getitems($a->pager['start'], $a->pager['itemspage']);
- if (! DBM::is_result($r)) {
- info( t('No results.') . EOL);
+ if (!DBM::is_result($r)) {
+ info(t('No results.') . EOL);
return $o;
}
$s[] = $item;
}
}
- if ((sizeof($s) < $a->pager['itemspage'])) {
+ if (sizeof($s) < $a->pager['itemspage']) {
$r = community_getitems($a->pager['start'] + ($count * $a->pager['itemspage']), $a->pager['itemspage']);
}
} while ((sizeof($s) < $a->pager['itemspage']) && (++$count < 50) && (sizeof($r) > 0));
return replace_macros($t, array(
'$content' => $o,
'$header' => t("Community"),
- '$show_global_community_hint' => (Config::get('system', 'community_page_style') == CP_GLOBAL_COMMUNITY && Config::get('system', 'show_global_community_hint')),
- '$global_community_hint' => t("This community stream shows all public posts received by this node. They may not reflect the opinions of this node’s users.")
+ '$show_global_community_hint' => false,
+ '$global_community_hint' => ''
));
}
function community_getitems($start, $itemspage) {
- if (Config::get('system','community_page_style') == CP_GLOBAL_COMMUNITY) {
- return(community_getpublicitems($start, $itemspage));
- }
$r = dba::p("SELECT ".item_fieldlists()." FROM `thread`
INNER JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall`
INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
return dba::inArray($r);
}
-
-function community_getpublicitems($start, $itemspage) {
- $r = dba::p("SELECT ".item_fieldlists()." FROM `thread`
- INNER JOIN `item` ON `item`.`id` = `thread`.`iid` ".item_joins().
- "WHERE `thread`.`uid` = 0 AND `verb` = ?
- ORDER BY `thread`.`commented` DESC LIMIT ".intval($start).", ".intval($itemspage),
- ACTIVITY_POST
- );
-
- while ($rr = dba::fetch($r)) {
- if (!in_array($rr['item_id'], $parents_arr)) {
- $parents_arr[] = $rr['item_id'];
- }
- }
-
- dba::close();
-
- $max_comments = Config::get("system", "max_comments", 100);
-
- $items = array();
-
- foreach ($parents_arr AS $parents) {
- $thread_items = dba::p(item_query()." AND `item`.`uid` = 0
- AND `item`.`parent` = ?
- ORDER BY `item`.`commented` DESC LIMIT ".intval($max_comments + 1),
- $parents
- );
-
- if (DBM::is_result($thread_items)) {
- $items = array_merge($items, dba::inArray($thread_items));
- }
- }
- $items = conv_sort($items, "`commented`");
-
- return $items;
-}
--- /dev/null
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+use Friendica\Core\Config;
+use Friendica\Database\DBM;
+use dba;
+
+/**
+ * Global module
+ *
+ * Displays global posts on the server
+ *
+ * @author heluecht@pirati.ca
+ */
+class GlobalModule extends BaseModule {
+ public static function init() {
+ if (!local_user()) {
+ unset($_SESSION['theme']);
+ unset($_SESSION['mobile-theme']);
+ }
+ }
+
+ public static function content($update = 0) {
+ $a = self::getApp();
+
+ $o = '';
+
+ if (Config::get('system','block_public') && !local_user() && !remote_user()) {
+ notice(t('Public access denied.') . EOL);
+ return;
+ }
+
+ if (!in_array(Config::get('system','community_page_style'), [CP_GLOBAL_COMMUNITY, CP_USERS_AND_GLOBAL])) {
+ notice(t('Not available.') . EOL);
+ return;
+ }
+
+ require_once 'include/bbcode.php';
+ require_once 'include/security.php';
+ require_once 'include/conversation.php';
+
+ if (!$update) {
+ nav_set_selected('global');
+ }
+
+ if (x($a->data,'search')) {
+ $search = notags(trim($a->data['search']));
+ } else {
+ $search = (x($_GET,'search') ? notags(trim(rawurldecode($_GET['search']))) : '');
+ }
+
+ // Here is the way permissions work in this module...
+ // Only public posts can be shown
+ // OR your own posts if you are a logged in member
+
+ $r = self::getPublicItems($a->pager['start'], $a->pager['itemspage']);
+
+ if (!DBM::is_result($r)) {
+ info(t('No results.') . EOL);
+ return $o;
+ }
+
+ $maxpostperauthor = Config::get('system','max_author_posts_community_page');
+
+ if ($maxpostperauthor != 0) {
+ $count = 1;
+ $previousauthor = "";
+ $numposts = 0;
+ $s = array();
+
+ do {
+ foreach ($r AS $row=>$item) {
+ if ($previousauthor == $item["author-link"]) {
+ ++$numposts;
+ } else {
+ $numposts = 0;
+ }
+ $previousauthor = $item["author-link"];
+
+ if (($numposts < $maxpostperauthor) && (sizeof($s) < $a->pager['itemspage'])) {
+ $s[] = $item;
+ }
+ }
+ if (sizeof($s) < $a->pager['itemspage']) {
+ $r = self::getPublicItems($a->pager['start'] + ($count * $a->pager['itemspage']), $a->pager['itemspage']);
+ }
+ } while ((sizeof($s) < $a->pager['itemspage']) && (++$count < 50) && (sizeof($r) > 0));
+ } else {
+ $s = $r;
+ }
+ // we behave the same in message lists as the search module
+
+ $o .= conversation($a, $s, 'community', $update);
+
+ $o .= alt_pager($a, count($r));
+
+ $t = get_markup_template("community.tpl");
+ return replace_macros($t, array(
+ '$content' => $o,
+ '$header' => t("Global Timeline"),
+ '$show_global_community_hint' => Config::get('system', 'show_global_community_hint'),
+ '$global_community_hint' => t("This community stream shows all public posts received by this node. They may not reflect the opinions of this node’s users.")
+ ));
+ }
+
+ private static function getPublicItems($start, $itemspage) {
+ $r = dba::p("SELECT ".item_fieldlists()." FROM `thread`
+ INNER JOIN `item` ON `item`.`id` = `thread`.`iid` ".item_joins().
+ "WHERE `thread`.`uid` = 0 AND `verb` = ?
+ ORDER BY `thread`.`created` DESC LIMIT ".intval($start).", ".intval($itemspage),
+ ACTIVITY_POST
+ );
+
+ return dba::inArray($r);
+
+ // Currently deactivated
+ $parents_arr = [];
+
+ while ($rr = dba::fetch($r)) {
+ if (!in_array($rr['item_id'], $parents_arr)) {
+ $parents_arr[] = $rr['item_id'];
+ }
+ }
+
+ dba::close($r);
+
+ $max_comments = Config::get("system", "max_comments", 100);
+
+ $items = array();
+
+ foreach ($parents_arr AS $parents) {
+ $thread_items = dba::p(item_query()." AND `item`.`uid` = 0
+ AND `item`.`parent` = ?
+ ORDER BY `item`.`commented` DESC LIMIT ".intval($max_comments + 1),
+ $parents
+ );
+
+ if (DBM::is_result($thread_items)) {
+ $items = array_merge($items, dba::inArray($thread_items));
+ }
+ }
+
+ foreach ($items as $index => $item) {
+ $items[$index]['writable'] = in_array($item['network'], [NETWORK_DIASPORA, NETWORK_OSTATUS]);
+ if ($item['network'] == NETWORK_DFRN) {
+ $fields = ['id', 'writable', 'self'];
+ $condition = ['nurl' => normalise_link($item['author-link']), 'uid' => local_user()];
+ $contact = dba::select('contact', $fields, $condition, ['limit' => 1]);
+ if (DBM::is_result($contact)) {
+ $items[$index]['contact-id'] = $contact['id'];
+ $items[$index]['cid'] = $contact['id'];
+ $items[$index]['writable'] = $contact['writable'];
+ $items[$index]['self'] = $contact['self'];
+ }
+ }
+ }
+
+ $items = conv_sort($items, "`commented`");
+
+ return $items;
+ }
+}
unset($buttons["like"]);
}
+ // If a contact isn't writable, we cannot send a like or dislike to it
+ if (!$item['writable']) {
+ unset($buttons["like"]);
+ unset($buttons["dislike"]);
+ }
+
$tmp_item = array(
'template' => $this->getTemplate(),
'type' => implode("", array_slice(explode("/", $item['verb']), -1)),
{{if $nav.community}}
<a accesskey="c" id="nav-community-link" class="nav-commlink {{$nav.community.2}} {{$sel.community}}" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
{{/if}}
+ {{if $nav.global}}
+ <a accesskey="g" id="nav-global-link" class="nav-commlink {{$nav.global.2}} {{$sel.global}}" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
+ {{/if}}
{{if $nav.introductions}}
<a id="nav-notify-link" class="nav-commlink {{$nav.introductions.2}} {{$sel.introductions}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a>
<span id="intro-update" class="nav-ajax-left"></span>
{{if $nav.community}}
<a accesskey="c" id="nav-community-link" class="nav-commlink {{$nav.community.2}} {{$sel.community}}" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
{{/if}}
+ {{if $nav.global}}
+ <a accesskey="g" id="nav-global-link" class="nav-commlink {{$nav.global.2}} {{$sel.global}}" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
+ {{/if}}
{{if $nav.introductions}}
<a id="nav-notify-link" class="nav-commlink {{$nav.introductions.2}} {{$sel.introductions}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a>
<span id="intro-update" class="nav-ajax-left"></span>
$("#topbar-second > .container > #tabmenu").append(newText);
}
+ if( $(".global-content-wrapper").length) {
+ // get the heading element
+ var heading = $(".global-content-wrapper > h3").first();
+ // get the text of the heading
+ var headingContent = heading.text();
+ // create a new element with the content of the heading
+ var newText = '<h4 class="heading">'+headingContent+'</h4>';
+ // remove the old heading element
+ heading.remove(),
+ // put the new element to the second nav bar
+ $("#topbar-second > .container > #tabmenu").append(newText);
+ }
+
// Dropdown menus with the class "dropdown-head" will display the active tab
// as button text
$("body").on('click', '.dropdown-head .dropdown-menu li a, .dropdown-head .dropdown-menu li button', function(){
{{if $nav.community}}
<a role="menuitem" class="nav-menu {{$sel.community}}" href="{{$nav.community.0}}" data-toggle="tooltip" title="{{$nav.community.3}}"><i class="fa fa-lg fa-bullseye" aria-hidden="true"></i></a>
{{/if}}
+
+ {{if $nav.global}}
+ <a role="menuitem" class="nav-menu {{$sel.global}}" href="{{$nav.global.0}}" data-toggle="tooltip" title="{{$nav.global.3}}"><i class="fa fa-lg fa-globe" aria-hidden="true"></i></a>
+ {{/if}}
</li>
<li id="nav-personal" class="nav-segment hidden-xs" role="presentation">
<a id="nav-community-link" class="{{$nav.community.2}} {{$sel.community}} nav-load-page-link" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
</li>
{{/if}}
+
+ {{if $nav.global}}
+ <li>
+ <a id="nav-global-link" class="{{$nav.global.2}} {{$sel.global}} nav-load-page-link" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
+ </li>
+ {{/if}}
</ul>
</div>
<a id="nav-community-link" class="{{$nav.community.2}} {{$sel.community}} nav-load-page-link" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
</li>
{{/if}}
+
+ {{if $nav.global}}
+ <li>
+ <a id="nav-global-link" class="{{$nav.global.2}} {{$sel.global}} nav-load-page-link" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
+ </li>
+ {{/if}}
</ul>
</div>
</ul>
</li>
{{/if}}
-
+
+ {{if $nav.global}}
+ <li id="nav-global-link" class="nav-menu {{$sel.global}}">
+ <a class="{{$nav.global.2}}" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
+ </li>
+ {{/if}}
+
{{if $nav.community}}
<li id="nav-community-link" class="nav-menu {{$sel.community}}">
<a class="{{$nav.community.2}}" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
</li>
{{/if}}
-
+
{{if $nav.network}}
<li id="nav-network-link" class="nav-menu {{$sel.network}}">
<a accesskey="n" class="{{$nav.network.2}}" href="{{$nav.network.0}}" title="{{$nav.network.3}}" >{{$nav.network.1}}</a>
<span id="net-update" class="nav-notify"></span>
</li>
{{/if}}
+
{{if $nav.home}}
<li id="nav-home-link" class="nav-menu {{$sel.home}}">
<a accesskey="p" class="{{$nav.home.2}}" href="{{$nav.home.0}}" title="{{$nav.home.3}}" >{{$nav.home.1}}</a>
<span id="home-update" class="nav-notify"></span>
</li>
{{/if}}
-
+
{{if $nav.introductions}}
<li id="nav-introductions-link" class="nav-menu-icon {{$sel.introductions}}">
<a class="{{$nav.introductions.2}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >
<span id="intro-update" class="nav-notify"></span>
</li>
{{/if}}
-
+
{{if $nav.messages}}
<li id="nav-messages-link" class="nav-menu-icon {{$sel.messages}}">
<a class="{{$nav.messages.2}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" >
</li>
{{/if}}
-
-
{{if $nav.notifications}}
<li id="nav-notifications-linkmenu" class="nav-menu-icon"><a accesskey="f" href="{{$nav.notifications.0}}" rel="#nav-notifications-menu" title="{{$nav.notifications.1}}"><span class="icon s22 notify">{{$nav.notifications.1}}</span></a>
<span id="notify-update" class="nav-notify"></span>
{{if $nav.network}}<li><a id="nav-network-link" class="nav-commlink {{$nav.network.2}}" href="{{$nav.network.0}}">{{$nav.network.1}}</a></li>{{/if}}
- {{if $nav.community}}
- <li><a id="nav-community-link" class="nav-commlink {{$nav.community.2}}" href="{{$nav.community.0}}">{{$nav.community.1}}</a></li>
- {{/if}}
+ {{if $nav.community}}
+ <li><a id="nav-community-link" class="nav-commlink {{$nav.community.2}}" href="{{$nav.community.0}}">{{$nav.community.1}}</a></li>
+ {{/if}}
+
+ {{if $nav.global}}
+ <li><a id="nav-global-link" class="nav-commlink {{$nav.global.2}}" href="{{$nav.global.0}}">{{$nav.global.1}}</a></li>
+ {{/if}}
<li><a id="nav-search-link" class="nav-link {{$nav.search.2}}" href="{{$nav.search.0}}">{{$nav.search.1}}</a></li>
<li><a id="nav-directory-link" class="nav-link {{$nav.directory.2}}" href="{{$nav.directory.0}}">{{$nav.directory.1}}</a></li>
</li>
{{/if}}
+ {{if $nav.global}}
+ <li role="menuitem" id="nav-global-link" class="nav-menu {{$sel.global}}">
+ <a accesskey="g" class="{{$nav.global.2}} desktop-view" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
+ <a class="{{$nav.global.2}} mobile-view" href="{{$nav.global.0}}" title="{{$nav.global.3}}" ><i class="icon s22 icon-bullseye"></i></a>
+ </li>
+ {{/if}}
+
<li role="menu" aria-haspopup="true" id="nav-site-linkmenu" class="nav-menu-icon"><a><span class="icon s22 icon-question"><span class="sr-only">{{$nav.help.3}}</span></span></a>
<ul id="nav-site-menu" class="menu-popup">
{{if $nav.help}} <li role="menuitem"><a class="{{$nav.help.2}}" href="{{$nav.help.0}}" title="{{$nav.help.3}}" >{{$nav.help.1}}</a></li>{{/if}}