diff --git a/include/conversation.php b/include/conversation.php
index 7d0ec0b72..e713994bc 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -460,7 +460,6 @@ function conv_get_blocklist()
* that are based on unique features of the calling module.
* @param App $a
* @param array $items
- * @param Pager $pager
* @param $mode
* @param $update
* @param bool $preview
@@ -470,7 +469,7 @@ function conv_get_blocklist()
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
-function conversation(App $a, array $items, Pager $pager, $mode, $update, $preview = false, $order = 'commented', $uid = 0)
+function conversation(App $a, array $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0)
{
$ssl_state = (local_user() ? true : false);
@@ -506,7 +505,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
. (!empty($_GET['cmax']) ? '&cmax=' . rawurlencode($_GET['cmax']) : '')
. (!empty($_GET['file']) ? '&file=' . rawurlencode($_GET['file']) : '')
- . "'; var profile_page = " . $pager->getPage() . "; \r\n";
+ . "'; \r\n";
}
} elseif ($mode === 'profile') {
$items = conversation_add_children($items, false, $order, $uid);
@@ -525,7 +524,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
$live_update_div = '
' . "\r\n"
. "\r\n";
+ . "; var netargs = '?f='; \r\n";
}
}
} elseif ($mode === 'notes') {
@@ -535,7 +534,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
if (!$update) {
$live_update_div = '' . "\r\n"
. "\r\n";
+ . "; var netargs = '/?f='; \r\n";
}
} elseif ($mode === 'display') {
$items = conversation_add_children($items, false, $order, $uid);
@@ -544,7 +543,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
if (!$update) {
$live_update_div = '' . "\r\n"
. "";
+ . "";
}
} elseif ($mode === 'community') {
$items = conversation_add_children($items, true, $order, $uid);
@@ -553,7 +552,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
if (!$update) {
$live_update_div = '' . "\r\n"
. "\r\n";
+ ."/?f='; \r\n";
}
} elseif ($mode === 'contacts') {
$items = conversation_add_children($items, false, $order, $uid);
@@ -562,7 +561,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
if (!$update) {
$live_update_div = '' . "\r\n"
. "\r\n";
+ ."/?f='; \r\n";
}
} elseif ($mode === 'search') {
$live_update_div = '' . "\r\n";
diff --git a/mod/common.php b/mod/common.php
index 6e923fd19..0ccad4238 100644
--- a/mod/common.php
+++ b/mod/common.php
@@ -107,7 +107,7 @@ function common_content(App $a)
return $o;
}
- $pager = new Pager(DI::args()->getQueryString());
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString());
if ($cid) {
$common_friends = Model\GContact::commonFriends($uid, $cid, $pager->getStart(), $pager->getItemsPerPage());
diff --git a/mod/community.php b/mod/community.php
deleted file mode 100644
index 7aa00240b..000000000
--- a/mod/community.php
+++ /dev/null
@@ -1,259 +0,0 @@
-.
- *
- */
-
-use Friendica\App;
-use Friendica\Content\Feature;
-use Friendica\Content\Nav;
-use Friendica\Content\Pager;
-use Friendica\Content\Widget\TrendingTags;
-use Friendica\Core\ACL;
-use Friendica\Core\Renderer;
-use Friendica\Core\Session;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Item;
-use Friendica\Model\User;
-
-function community_content(App $a, $update = 0)
-{
- $o = '';
-
- if (DI::config()->get('system', 'block_public') && !Session::isAuthenticated()) {
- notice(DI::l10n()->t('Public access denied.') . EOL);
- return;
- }
-
- $page_style = DI::config()->get('system', 'community_page_style');
-
- if ($page_style == CP_NO_INTERNAL_COMMUNITY) {
- notice(DI::l10n()->t('Access denied.') . EOL);
- return;
- }
-
- $accounttype = null;
-
- if ($a->argc > 2) {
- switch ($a->argv[2]) {
- case 'person':
- $accounttype = User::ACCOUNT_TYPE_PERSON;
- break;
- case 'organisation':
- $accounttype = User::ACCOUNT_TYPE_ORGANISATION;
- break;
- case 'news':
- $accounttype = User::ACCOUNT_TYPE_NEWS;
- break;
- case 'community':
- $accounttype = User::ACCOUNT_TYPE_COMMUNITY;
- break;
- }
- }
-
- if ($a->argc > 1) {
- $content = $a->argv[1];
- } else {
- if (!empty(DI::config()->get('system', 'singleuser'))) {
- // 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';
- }
- }
-
- if (!in_array($content, ['local', 'global'])) {
- notice(DI::l10n()->t('Community option not available.') . EOL);
- return;
- }
-
- // 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) {
- notice(DI::l10n()->t('Not available.') . EOL);
- return;
- }
- }
-
- if (!$update) {
- $tabs = [];
-
- if ((local_user() || in_array($page_style, [CP_USERS_AND_GLOBAL, CP_USERS_ON_SERVER])) && empty(DI::config()->get('system', 'singleuser'))) {
- $tabs[] = [
- 'label' => DI::l10n()->t('Local Community'),
- 'url' => 'community/local',
- 'sel' => $content == 'local' ? 'active' : '',
- 'title' => DI::l10n()->t('Posts from local users on this server'),
- 'id' => 'community-local-tab',
- 'accesskey' => 'l'
- ];
- }
-
- if (local_user() || in_array($page_style, [CP_USERS_AND_GLOBAL, CP_GLOBAL_COMMUNITY])) {
- $tabs[] = [
- 'label' => DI::l10n()->t('Global Community'),
- 'url' => 'community/global',
- 'sel' => $content == 'global' ? 'active' : '',
- 'title' => DI::l10n()->t('Posts from users of the whole federated network'),
- 'id' => 'community-global-tab',
- 'accesskey' => 'g'
- ];
- }
-
- $tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
- $o .= Renderer::replaceMacros($tab_tpl, ['$tabs' => $tabs]);
-
- Nav::setSelected('community');
-
- // We need the editor here to be able to reshare an item.
- if (local_user()) {
- $x = [
- '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'),
- 'acl' => ACL::getFullSelectorHTML(DI::page(), $a->user, true),
- 'bang' => '',
- 'visitor' => 'block',
- 'profile_uid' => local_user(),
- ];
- $o .= status_editor($a, $x, 0, true);
- }
- }
-
- // check if we serve a mobile device and get the user settings accordingly
- if (DI::mode()->isMobile()) {
- $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network', 20);
- } else {
- $itemspage_network = DI::pConfig()->get(local_user(), 'system', '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;
- }
-
- $pager = new Pager(DI::args()->getQueryString(), $itemspage_network);
-
- $r = community_getitems($pager->getStart(), $pager->getItemsPerPage(), $content, $accounttype);
-
- if (!DBA::isResult($r)) {
- info(DI::l10n()->t('No results.') . EOL);
- return $o;
- }
-
- $maxpostperauthor = (int) DI::config()->get('system', 'max_author_posts_community_page');
-
- if (($maxpostperauthor != 0) && ($content == 'local')) {
- $count = 1;
- $previousauthor = "";
- $numposts = 0;
- $s = [];
-
- do {
- foreach ($r as $item) {
- if ($previousauthor == $item["author-link"]) {
- ++$numposts;
- } else {
- $numposts = 0;
- }
- $previousauthor = $item["author-link"];
-
- if (($numposts < $maxpostperauthor) && (count($s) < $pager->getItemsPerPage())) {
- $s[] = $item;
- }
- }
- if (count($s) < $pager->getItemsPerPage()) {
- $r = community_getitems($pager->getStart() + ($count * $pager->getItemsPerPage()), $pager->getItemsPerPage(), $content, $accounttype);
- }
- } while ((count($s) < $pager->getItemsPerPage()) && ( ++$count < 50) && (count($r) > 0));
- } else {
- $s = $r;
- }
-
- $o .= conversation($a, $s, $pager, 'community', $update, false, 'commented', local_user());
-
- if (!$update) {
- $o .= $pager->renderMinimal(count($r));
- }
-
- if (empty(DI::page()['aside'])) {
- DI::page()['aside'] = '';
- }
-
- if (Feature::isEnabled(local_user(), 'trending_tags')) {
- DI::page()['aside'] .= TrendingTags::getHTML($content);
- }
-
- $t = Renderer::getMarkupTemplate("community.tpl");
- return Renderer::replaceMacros($t, [
- '$content' => $o,
- '$header' => '',
- '$show_global_community_hint' => ($content == 'global') && DI::config()->get('system', 'show_global_community_hint'),
- '$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.")
- ]);
-}
-
-function community_getitems($start, $itemspage, $content, $accounttype)
-{
- if ($content == 'local') {
- if (!is_null($accounttype)) {
- $sql_accounttype = " AND `user`.`account-type` = ?";
- $values = [$accounttype, $start, $itemspage];
- } else {
- $sql_accounttype = "";
- $values = [$start, $itemspage];
- }
-
- /// @todo Use "unsearchable" here as well (instead of "hidewall")
- $r = DBA::p("SELECT `item`.`uri`, `author`.`url` AS `author-link` FROM `thread`
- 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`
- WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated`
- AND NOT `thread`.`private` AND `thread`.`wall` AND `thread`.`origin` $sql_accounttype
- ORDER BY `thread`.`commented` DESC LIMIT ?, ?", $values);
- return DBA::toArray($r);
- } elseif ($content == 'global') {
- if (!is_null($accounttype)) {
- $condition = ["`uid` = ? AND NOT `author`.`unsearchable` AND NOT `owner`.`unsearchable` AND `owner`.`contact-type` = ?", 0, $accounttype];
- } else {
- $condition = ["`uid` = ? AND NOT `author`.`unsearchable` AND NOT `owner`.`unsearchable`", 0];
- }
-
- $r = Item::selectThreadForUser(0, ['uri'], $condition, ['order' => ['commented' => true], 'limit' => [$start, $itemspage]]);
- return DBA::toArray($r);
- }
-
- // Should never happen
- return [];
-}
diff --git a/mod/display.php b/mod/display.php
index ea52a994b..dce8b25b9 100644
--- a/mod/display.php
+++ b/mod/display.php
@@ -331,7 +331,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
$o .= "";
}
- $o .= conversation($a, [$item], new Pager(DI::args()->getQueryString()), 'display', $update_uid, false, 'commented', $item_uid);
+ $o .= conversation($a, [$item], 'display', $update_uid, false, 'commented', $item_uid);
// Preparing the meta header
$description = trim(HTML::toPlaintext(BBCode::convert($item["body"], false), 0, true));
diff --git a/mod/item.php b/mod/item.php
index 636bd8c31..2e5a08203 100644
--- a/mod/item.php
+++ b/mod/item.php
@@ -675,7 +675,7 @@ function item_post(App $a) {
$datarray["item_id"] = -1;
$datarray["author-network"] = Protocol::DFRN;
- $o = conversation($a, [array_merge($contact_record, $datarray)], new Pager(DI::args()->getQueryString()), 'search', false, true);
+ $o = conversation($a, [array_merge($contact_record, $datarray)], 'search', false, true);
System::jsonExit(['preview' => $o]);
}
diff --git a/mod/message.php b/mod/message.php
index e871e22e3..c62a15eb2 100644
--- a/mod/message.php
+++ b/mod/message.php
@@ -296,7 +296,7 @@ function message_content(App $a)
$total = $r[0]['total'];
}
- $pager = new Pager(DI::args()->getQueryString());
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString());
$r = get_messages(local_user(), $pager->getStart(), $pager->getItemsPerPage());
diff --git a/mod/network.php b/mod/network.php
index 1f7afebf3..6c63753d9 100644
--- a/mod/network.php
+++ b/mod/network.php
@@ -228,14 +228,12 @@ function networkPager(App $a, Pager $pager, $update)
return ' LIMIT 100';
}
- // check if we serve a mobile device and get the user settings
- // accordingly
if (DI::mode()->isMobile()) {
- $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network');
- $itemspage_network = ((intval($itemspage_network)) ? $itemspage_network : 20);
+ $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network',
+ DI::config()->get('system', 'itemspage_network_mobile'));
} else {
- $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_network');
- $itemspage_network = ((intval($itemspage_network)) ? $itemspage_network : 40);
+ $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_network',
+ DI::config()->get('system', 'itemspage_network'));
}
// now that we have the user settings, see if the theme forces
@@ -291,7 +289,7 @@ function networkConversation(App $a, $items, Pager $pager, $mode, $update, $orde
$items = [];
}
- $o = conversation($a, $items, $pager, $mode, $update, false, $ordering, local_user());
+ $o = conversation($a, $items, $mode, $update, false, $ordering, local_user());
if (!$update) {
if (DI::pConfig()->get(local_user(), 'system', 'infinite_scroll')) {
@@ -377,7 +375,7 @@ function networkFlatView(App $a, $update = 0)
}
}
- $pager = new Pager(DI::args()->getQueryString());
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString());
networkPager($a, $pager, $update);
@@ -669,7 +667,7 @@ function networkThreadedView(App $a, $update, $parent)
$sql_range = '';
}
- $pager = new Pager(DI::args()->getQueryString());
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString());
$pager_sql = networkPager($a, $pager, $update);
diff --git a/mod/notes.php b/mod/notes.php
index ccd30926c..67f8fcab2 100644
--- a/mod/notes.php
+++ b/mod/notes.php
@@ -69,7 +69,15 @@ function notes_content(App $a, $update = false)
$condition = ['uid' => local_user(), 'post-type' => Item::PT_PERSONAL_NOTE, 'gravity' => GRAVITY_PARENT,
'contact-id'=> $a->contact['id']];
- $pager = new Pager(DI::args()->getQueryString(), 40);
+ if (DI::mode()->isMobile()) {
+ $itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network',
+ DI::config()->get('system', 'itemspage_network_mobile'));
+ } else {
+ $itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_network',
+ DI::config()->get('system', 'itemspage_network'));
+ }
+
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), $itemsPerPage);
$params = ['order' => ['created' => true],
'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
@@ -82,7 +90,7 @@ function notes_content(App $a, $update = false)
$count = count($notes);
- $o .= conversation($a, $notes, $pager, 'notes', $update);
+ $o .= conversation($a, $notes, 'notes', $update);
}
$o .= $pager->renderMinimal($count);
diff --git a/mod/photos.php b/mod/photos.php
index 5e5917452..03b78e0e1 100644
--- a/mod/photos.php
+++ b/mod/photos.php
@@ -1023,7 +1023,7 @@ function photos_content(App $a)
$total = count($r);
}
- $pager = new Pager(DI::args()->getQueryString(), 20);
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 20);
/// @TODO I have seen this many times, maybe generalize it script-wide and encapsulate it?
$order_field = $_GET['order'] ?? '';
@@ -1299,7 +1299,7 @@ function photos_content(App $a)
$condition = ["`parent` = ? AND `parent` != `id`", $link_item['parent']];
$total = DBA::count('item', $condition);
- $pager = new Pager(DI::args()->getQueryString());
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString());
$params = ['order' => ['id'], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
$result = Item::selectForUser($link_item['uid'], Item::ITEM_FIELDLIST, $condition, $params);
@@ -1565,7 +1565,7 @@ function photos_content(App $a)
$total = count($r);
}
- $pager = new Pager(DI::args()->getQueryString(), 20);
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 20);
$r = q("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`,
ANY_VALUE(`type`) AS `type`, ANY_VALUE(`album`) AS `album`, max(`scale`) AS `scale`,
diff --git a/mod/settings.php b/mod/settings.php
index 9b505a81e..061e83fe0 100644
--- a/mod/settings.php
+++ b/mod/settings.php
@@ -356,11 +356,15 @@ function settings_post(App $a)
}
}
- $itemspage_network = !empty($_POST['itemspage_network']) ? intval($_POST['itemspage_network']) : 40;
+ $itemspage_network = !empty($_POST['itemspage_network']) ?
+ intval($_POST['itemspage_network']) :
+ DI::config()->get('system', 'itemspage_network');
if ($itemspage_network > 100) {
$itemspage_network = 100;
}
- $itemspage_mobile_network = !empty($_POST['itemspage_mobile_network']) ? intval($_POST['itemspage_mobile_network']) : 20;
+ $itemspage_mobile_network = !empty($_POST['itemspage_mobile_network']) ?
+ intval($_POST['itemspage_mobile_network']) :
+ DI::config()->get('system', 'itemspage_network_mobile');
if ($itemspage_mobile_network > 100) {
$itemspage_mobile_network = 100;
}
@@ -938,9 +942,9 @@ function settings_content(App $a)
}
$itemspage_network = intval(DI::pConfig()->get(local_user(), 'system', 'itemspage_network'));
- $itemspage_network = (($itemspage_network > 0 && $itemspage_network < 101) ? $itemspage_network : 40); // default if not set: 40 items
+ $itemspage_network = (($itemspage_network > 0 && $itemspage_network < 101) ? $itemspage_network : DI::config()->get('system', 'itemspage_network'));
$itemspage_mobile_network = intval(DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network'));
- $itemspage_mobile_network = (($itemspage_mobile_network > 0 && $itemspage_mobile_network < 101) ? $itemspage_mobile_network : 20); // default if not set: 20 items
+ $itemspage_mobile_network = (($itemspage_mobile_network > 0 && $itemspage_mobile_network < 101) ? $itemspage_mobile_network : DI::config()->get('system', 'itemspage_network_mobile'));
$nosmile = DI::pConfig()->get(local_user(), 'system', 'no_smilies', 0);
$first_day_of_week = DI::pConfig()->get(local_user(), 'system', 'first_day_of_week', 0);
diff --git a/mod/update_community.php b/mod/update_community.php
deleted file mode 100644
index 8a12142eb..000000000
--- a/mod/update_community.php
+++ /dev/null
@@ -1,55 +0,0 @@
-.
- *
- * See update_profile.php for documentation
- */
-
-use Friendica\App;
-use Friendica\DI;
-
-require_once 'mod/community.php';
-
-function update_community_content(App $a) {
- header("Content-type: text/html");
- echo "\r\n";
- echo "";
-
- if ($_GET["force"] == 1) {
- $text = community_content($a, true);
- } else {
- $text = '';
- }
-
- if (DI::pConfig()->get(local_user(), "system", "bandwidth_saver")) {
- $replace = "
" . DI::l10n()->t("[Embedded content - reload page to view]") . "
";
- $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
- $text = preg_replace($pattern, $replace, $text);
- }
-
- echo str_replace("\t", " ", $text);
- echo "";
- echo "\r\n";
- exit();
-}
diff --git a/mod/update_contact.php b/mod/update_contact.php
index 768ff0c74..5fb62e6a0 100644
--- a/mod/update_contact.php
+++ b/mod/update_contact.php
@@ -22,35 +22,17 @@
*/
use Friendica\App;
+use Friendica\Core\System;
use Friendica\DI;
use Friendica\Module\Contact;
function update_contact_content(App $a)
{
- header("Content-type: text/html");
- echo "\r\n";
- echo "";
-
if ($_GET["force"] == 1) {
$text = Contact::content([], true);
} else {
$text = '';
}
- if (DI::pConfig()->get(local_user(), "system", "bandwidth_saver")) {
- $replace = "
" . DI::l10n()->t("[Embedded content - reload page to view]") . "
";
- $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
- $text = preg_replace($pattern, $replace, $text);
- }
-
- echo str_replace("\t", " ", $text);
- echo "";
- echo "\r\n";
- exit();
+ System::htmlUpdateExit($text);
}
diff --git a/mod/update_display.php b/mod/update_display.php
index 73fd915e4..601808ff5 100644
--- a/mod/update_display.php
+++ b/mod/update_display.php
@@ -21,6 +21,7 @@
*/
use Friendica\App;
+use Friendica\Core\System;
use Friendica\DI;
require_once "mod/display.php";
@@ -29,26 +30,7 @@ function update_display_content(App $a)
{
$profile_uid = intval($_GET["p"]);
- header("Content-type: text/html");
- echo "\r\n";
- echo "";
-
$text = display_content($a, true, $profile_uid);
- if (DI::pConfig()->get(local_user(), "system", "bandwidth_saver")) {
- $replace = "
" . DI::l10n()->t("[Embedded content - reload page to view]") . "
";
- $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
- $text = preg_replace($pattern, $replace, $text);
- }
-
- echo str_replace("\t", " ", $text);
- echo "";
- echo "\r\n";
- exit();
+ System::htmlUpdateExit($text);
}
diff --git a/mod/update_network.php b/mod/update_network.php
index d6b77aedb..aafc0e22f 100644
--- a/mod/update_network.php
+++ b/mod/update_network.php
@@ -21,6 +21,7 @@
*/
use Friendica\App;
+use Friendica\Core\System;
use Friendica\DI;
require_once "mod/network.php";
@@ -34,30 +35,10 @@ function update_network_content(App $a)
$profile_uid = intval($_GET['p']);
$parent = intval($_GET['item']);
- header("Content-type: text/html");
- echo "\r\n";
- echo "";
-
if (!DI::pConfig()->get($profile_uid, "system", "no_auto_update") || ($_GET["force"] == 1)) {
$text = network_content($a, $profile_uid, $parent);
} else {
$text = "";
}
-
- if (DI::pConfig()->get(local_user(), "system", "bandwidth_saver")) {
- $replace = "
" . DI::l10n()->t("[Embedded content - reload page to view]") . "
";
- $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
- $text = preg_replace($pattern, $replace, $text);
- }
-
- echo str_replace("\t", " ", $text);
- echo "";
- echo "\r\n";
- exit();
+ System::htmlUpdateExit($text);
}
diff --git a/mod/update_notes.php b/mod/update_notes.php
index 87822f513..75958a41b 100644
--- a/mod/update_notes.php
+++ b/mod/update_notes.php
@@ -21,6 +21,7 @@
*/
use Friendica\App;
+use Friendica\Core\System;
use Friendica\DI;
require_once("mod/notes.php");
@@ -29,11 +30,6 @@ function update_notes_content(App $a) {
$profile_uid = intval($_GET["p"]);
- header("Content-type: text/html");
- echo "\r\n";
-
- echo "";
-
/**
*
* Grab the page inner contents by calling the content function from the profile module directly,
@@ -46,21 +42,5 @@ function update_notes_content(App $a) {
$text = notes_content($a, $profile_uid);
- if (DI::pConfig()->get(local_user(), "system", "bandwidth_saver")) {
- $replace = "
" . DI::l10n()->t("[Embedded content - reload page to view]") . "
";
- $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
- $text = preg_replace($pattern, $replace, $text);
- $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
- $text = preg_replace($pattern, $replace, $text);
- }
-
- // reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well
- echo str_replace("\t", " ", $text);
- echo "";
- echo "\r\n";
- exit();
+ System::htmlUpdateExit($text);
}
\ No newline at end of file
diff --git a/mod/videos.php b/mod/videos.php
index 3cb2b84bc..49c64ef97 100644
--- a/mod/videos.php
+++ b/mod/videos.php
@@ -225,7 +225,7 @@ function videos_content(App $a)
$total = count($r);
}
- $pager = new Pager(DI::args()->getQueryString(), 20);
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 20);
$r = q("SELECT hash, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`created`) AS `created`,
ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`filetype`) as `filetype`
diff --git a/src/Content/BoundariesPager.php b/src/Content/BoundariesPager.php
new file mode 100644
index 000000000..b8b7f67bb
--- /dev/null
+++ b/src/Content/BoundariesPager.php
@@ -0,0 +1,137 @@
+.
+ *
+ */
+
+namespace Friendica\Content;
+
+use Friendica\Core\L10n;
+use Friendica\Core\Renderer;
+use Friendica\Util\Network;
+use Friendica\Util\Strings;
+
+/**
+ * This pager should be used by lists using the since_id†/max_id† parameters
+ *
+ * This pager automatically identifies if the sorting is done increasingly or decreasingly if the first item id†
+ * and last item id† are different. Otherwise it defaults to decreasingly like reverse chronological lists.
+ *
+ * † In this context, "id" refers to the value of the column that the item list is ordered by.
+ */
+class BoundariesPager extends Pager
+{
+ protected $first_item_id;
+ protected $last_item_id;
+ protected $first_page = true;
+
+ /**
+ * Instantiates a new Pager with the base parameters.
+ *
+ * @param L10n $l10n
+ * @param string $queryString The query string of the current page
+ * @param string $first_item_id The id† of the first item in the displayed item list
+ * @param string $last_item_id The id† of the last item in the displayed item list
+ * @param integer $itemsPerPage An optional number of items per page to override the default value
+ */
+ public function __construct(L10n $l10n, $queryString, $first_item_id = null, $last_item_id = null, $itemsPerPage = 50)
+ {
+ parent::__construct($l10n, $queryString, $itemsPerPage);
+
+ $this->first_item_id = $first_item_id;
+ $this->last_item_id = $last_item_id;
+
+ $parsed = parse_url($this->getBaseQueryString());
+ if ($parsed) {
+ parse_str($parsed['query'], $queryParameters);
+
+ $this->first_page = !($queryParameters['since_id'] ?? null) && !($queryParameters['max_id'] ?? null);
+
+ unset($queryParameters['since_id']);
+ unset($queryParameters['max_id']);
+
+ $parsed['query'] = http_build_query($queryParameters);
+
+ $url = Network::unparseURL($parsed);
+
+ $this->setQueryString($url);
+ }
+ }
+
+ public function getStart()
+ {
+ throw new \BadMethodCallException();
+ }
+
+ public function getPage()
+ {
+ throw new \BadMethodCallException();
+ }
+
+ /**
+ * Minimal pager (newer/older)
+ *
+ * This mode is intended for reverse chronological pages and presents only two links, newer (previous) and older (next).
+ * The itemCount is the number of displayed items. If no items are displayed, the older button is disabled.
+ *
+ * Example usage:
+ *
+ * $params = ['order' => ['sort_field' => true], 'limit' => $itemsPerPage];
+ * $items = DBA::toArray(DBA::select($table, $fields, $condition, $params));
+ *
+ * $pager = new BoundariesPager($a->query_string, $items[0]['sort_field'], $items[coutn($items) - 1]['sort_field'], $itemsPerPage);
+ *
+ * $html = $pager->renderMinimal(count($items));
+ *
+ * @param int $itemCount The number of displayed items on the page
+ * @return string HTML string of the pager
+ * @throws \Exception
+ */
+ public function renderMinimal(int $itemCount)
+ {
+ $displayedItemCount = max(0, intval($itemCount));
+
+ $data = [
+ 'class' => 'pager',
+ 'prev' => [
+ 'url' => Strings::ensureQueryParameter($this->baseQueryString .
+ ($this->first_item_id >= $this->last_item_id ?
+ '&since_id=' . $this->first_item_id : '&max_id=' . $this->first_item_id)
+ ),
+ 'text' => $this->l10n->t('newer'),
+ 'class' => 'previous' . ($this->first_page ? ' disabled' : '')
+ ],
+ 'next' => [
+ 'url' => Strings::ensureQueryParameter($this->baseQueryString .
+ ($this->first_item_id >= $this->last_item_id ?
+ '&max_id=' . $this->last_item_id : '&since_id=' . $this->last_item_id)
+ ),
+ 'text' => $this->l10n->t('older'),
+ 'class' => 'next' . ($displayedItemCount < $this->getItemsPerPage() ? ' disabled' : '')
+ ]
+ ];
+
+ $tpl = Renderer::getMarkupTemplate('paginate.tpl');
+ return Renderer::replaceMacros($tpl, ['pager' => $data]);
+ }
+
+ public function renderFull($itemCount)
+ {
+ throw new \BadMethodCallException();
+ }
+}
diff --git a/src/Content/Pager.php b/src/Content/Pager.php
index badc8af4e..5b4345a4c 100644
--- a/src/Content/Pager.php
+++ b/src/Content/Pager.php
@@ -21,8 +21,8 @@
namespace Friendica\Content;
+use Friendica\Core\L10n;
use Friendica\Core\Renderer;
-use Friendica\DI;
use Friendica\Util\Strings;
/**
@@ -30,30 +30,29 @@ use Friendica\Util\Strings;
*/
class Pager
{
- /**
- * @var integer
- */
+ /** @var integer */
private $page = 1;
- /**
- * @var integer
- */
- private $itemsPerPage = 50;
+ /** @var integer */
+ protected $itemsPerPage = 50;
+ /** @var string */
+ protected $baseQueryString = '';
- /**
- * @var string
- */
- private $baseQueryString = '';
+ /** @var L10n */
+ protected $l10n;
/**
* Instantiates a new Pager with the base parameters.
*
* Guesses the page number from the GET parameter 'page'.
*
+ * @param L10n $l10n
* @param string $queryString The query string of the current page
* @param integer $itemsPerPage An optional number of items per page to override the default value
*/
- public function __construct($queryString, $itemsPerPage = 50)
+ public function __construct(L10n $l10n, $queryString, $itemsPerPage = 50)
{
+ $this->l10n = $l10n;
+
$this->setQueryString($queryString);
$this->setItemsPerPage($itemsPerPage);
$this->setPage(($_GET['page'] ?? 0) ?: 1);
@@ -134,7 +133,6 @@ class Pager
{
$stripped = preg_replace('/([&?]page=[0-9]*)/', '', $queryString);
- $stripped = str_replace('q=', '', $stripped);
$stripped = trim($stripped, '/');
$this->baseQueryString = $stripped;
@@ -155,11 +153,11 @@ class Pager
*
* $html = $pager->renderMinimal(count($items));
*
- * @param integer $itemCount The number of displayed items on the page
+ * @param int $itemCount The number of displayed items on the page
* @return string HTML string of the pager
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ * @throws \Exception
*/
- public function renderMinimal($itemCount)
+ public function renderMinimal(int $itemCount)
{
$displayedItemCount = max(0, intval($itemCount));
@@ -167,12 +165,12 @@ class Pager
'class' => 'pager',
'prev' => [
'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() - 1)),
- 'text' => DI::l10n()->t('newer'),
+ 'text' => $this->l10n->t('newer'),
'class' => 'previous' . ($this->getPage() == 1 ? ' disabled' : '')
],
'next' => [
'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() + 1)),
- 'text' => DI::l10n()->t('older'),
+ 'text' => $this->l10n->t('older'),
'class' => 'next' . ($displayedItemCount < $this->getItemsPerPage() ? ' disabled' : '')
]
];
@@ -212,12 +210,12 @@ class Pager
if ($totalItemCount > $this->getItemsPerPage()) {
$data['first'] = [
'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=1'),
- 'text' => DI::l10n()->t('first'),
+ 'text' => $this->l10n->t('first'),
'class' => $this->getPage() == 1 ? 'disabled' : ''
];
$data['prev'] = [
'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() - 1)),
- 'text' => DI::l10n()->t('prev'),
+ 'text' => $this->l10n->t('prev'),
'class' => $this->getPage() == 1 ? 'disabled' : ''
];
@@ -272,12 +270,12 @@ class Pager
$data['next'] = [
'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() + 1)),
- 'text' => DI::l10n()->t('next'),
+ 'text' => $this->l10n->t('next'),
'class' => $this->getPage() == $lastpage ? 'disabled' : ''
];
$data['last'] = [
'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . $lastpage),
- 'text' => DI::l10n()->t('last'),
+ 'text' => $this->l10n->t('last'),
'class' => $this->getPage() == $lastpage ? 'disabled' : ''
];
}
diff --git a/src/Core/System.php b/src/Core/System.php
index f092427e5..87abfdf8e 100644
--- a/src/Core/System.php
+++ b/src/Core/System.php
@@ -292,6 +292,36 @@ class System
return true;
}
+ /**
+ * Exit method used by asynchronous update modules
+ *
+ * @param string $o
+ */
+ public static function htmlUpdateExit($o)
+ {
+ if (DI::pConfig()->get(local_user(), "system", "bandwidth_saver")) {
+ $replace = "
".DI::l10n()->t("[Embedded content - reload page to view]")."
";
+ $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
+ $o = preg_replace($pattern, $replace, $o);
+ $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
+ $o = preg_replace($pattern, $replace, $o);
+ $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
+ $o = preg_replace($pattern, $replace, $o);
+ $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
+ $o = preg_replace($pattern, $replace, $o);
+ }
+
+ header("Content-type: text/html");
+ echo "\r\n";
+ // We can remove this hack once Internet Explorer recognises HTML5 natively
+ echo "";
+ // reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well
+ echo str_replace("\t", " ", $o);
+ echo "";
+ echo "\r\n";
+ exit();
+ }
+
/// @todo Move the following functions from boot.php
/*
function local_user()
diff --git a/src/Model/Contact.php b/src/Model/Contact.php
index 5eb4ed036..4eaca00f9 100644
--- a/src/Model/Contact.php
+++ b/src/Model/Contact.php
@@ -1804,7 +1804,15 @@ class Contact
$cid, GRAVITY_PARENT, GRAVITY_COMMENT, local_user()];
}
- $pager = new Pager(DI::args()->getQueryString());
+ if (DI::mode()->isMobile()) {
+ $itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network',
+ DI::config()->get('system', 'itemspage_network_mobile'));
+ } else {
+ $itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_network',
+ DI::config()->get('system', 'itemspage_network'));
+ }
+
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), $itemsPerPage);
$params = ['order' => ['received' => true],
'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
@@ -1814,13 +1822,13 @@ class Contact
$items = Item::inArray($r);
- $o = conversation($a, $items, $pager, 'contacts', $update, false, 'commented', local_user());
+ $o = conversation($a, $items, 'contacts', $update, false, 'commented', local_user());
} else {
$r = Item::selectForUser(local_user(), [], $condition, $params);
$items = Item::inArray($r);
- $o = conversation($a, $items, $pager, 'contact-posts', false);
+ $o = conversation($a, $items, 'contact-posts', false);
}
if (!$update) {
diff --git a/src/Module/Admin/Blocklist/Contact.php b/src/Module/Admin/Blocklist/Contact.php
index 5d87139df..889362323 100644
--- a/src/Module/Admin/Blocklist/Contact.php
+++ b/src/Module/Admin/Blocklist/Contact.php
@@ -68,7 +68,7 @@ class Contact extends BaseAdmin
$total = DBA::count('contact', $condition);
- $pager = new Pager(DI::args()->getQueryString(), 30);
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 30);
$contacts = Model\Contact::selectToArray([], $condition, ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]]);
diff --git a/src/Module/Admin/Users.php b/src/Module/Admin/Users.php
index fbaab1ded..b446a2c47 100644
--- a/src/Module/Admin/Users.php
+++ b/src/Module/Admin/Users.php
@@ -194,7 +194,7 @@ class Users extends BaseAdmin
/* get pending */
$pending = Register::getPending();
- $pager = new Pager(DI::args()->getQueryString(), 100);
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100);
// @TODO Move below block to Model\User::getUsers($start, $count, $order = 'contact.name', $order_direction = '+')
$valid_orders = [
diff --git a/src/Module/AllFriends.php b/src/Module/AllFriends.php
index f916c1671..5d73f53cb 100644
--- a/src/Module/AllFriends.php
+++ b/src/Module/AllFriends.php
@@ -67,7 +67,7 @@ class AllFriends extends BaseModule
$total = Model\GContact::countAllFriends(local_user(), $cid);
- $pager = new Pager(DI::args()->getQueryString());
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString());
$friends = Model\GContact::allFriends(local_user(), $cid, $pager->getStart(), $pager->getItemsPerPage());
if (empty($friends)) {
diff --git a/src/Module/BaseNotifications.php b/src/Module/BaseNotifications.php
index 9e7b1cd97..4715641c2 100644
--- a/src/Module/BaseNotifications.php
+++ b/src/Module/BaseNotifications.php
@@ -102,7 +102,7 @@ abstract class BaseNotifications extends BaseModule
}
// Set the pager
- $pager = new Pager(DI::args()->getQueryString(), self::ITEMS_PER_PAGE);
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), self::ITEMS_PER_PAGE);
// Add additional informations (needed for json output)
$notifications = [
@@ -132,7 +132,7 @@ abstract class BaseNotifications extends BaseModule
$tabs = self::getTabs();
// Set the pager
- $pager = new Pager(DI::args()->getQueryString(), self::ITEMS_PER_PAGE);
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), self::ITEMS_PER_PAGE);
$notif_tpl = Renderer::getMarkupTemplate('notifications/notifications.tpl');
return Renderer::replaceMacros($notif_tpl, [
diff --git a/src/Module/BaseSearch.php b/src/Module/BaseSearch.php
index ca940ae4e..e67d3c3c9 100644
--- a/src/Module/BaseSearch.php
+++ b/src/Module/BaseSearch.php
@@ -81,8 +81,15 @@ class BaseSearch extends BaseModule
$header = DI::l10n()->t('Forum Search - %s', $search);
}
- $args = DI::args();
- $pager = new Pager($args->getQueryString());
+ if (DI::mode()->isMobile()) {
+ $itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network',
+ DI::config()->get('system', 'itemspage_network_mobile'));
+ } else {
+ $itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_network',
+ DI::config()->get('system', 'itemspage_network'));
+ }
+
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), $itemsPerPage);
if ($localSearch && empty($results)) {
$pager->setItemsPerPage(80);
diff --git a/src/Module/Contact.php b/src/Module/Contact.php
index be6f16a53..ee0ccce7e 100644
--- a/src/Module/Contact.php
+++ b/src/Module/Contact.php
@@ -731,7 +731,7 @@ class Contact extends BaseModule
}
DBA::close($stmt);
- $pager = new Pager(DI::args()->getQueryString());
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString());
$sql_values[] = $pager->getStart();
$sql_values[] = $pager->getItemsPerPage();
diff --git a/src/Module/Conversation/Community.php b/src/Module/Conversation/Community.php
new file mode 100644
index 000000000..58af38eb1
--- /dev/null
+++ b/src/Module/Conversation/Community.php
@@ -0,0 +1,337 @@
+.
+ *
+ * See update_profile.php for documentation
+ */
+
+namespace Friendica\Module\Conversation;
+
+use Friendica\BaseModule;
+use Friendica\Content\BoundariesPager;
+use Friendica\Content\Feature;
+use Friendica\Content\Nav;
+use Friendica\Content\Widget\TrendingTags;
+use Friendica\Core\ACL;
+use Friendica\Core\Renderer;
+use Friendica\Core\Session;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Model\Item;
+use Friendica\Model\User;
+use Friendica\Network\HTTPException;
+
+class Community extends BaseModule
+{
+ protected static $page_style;
+ protected static $content;
+ protected static $accounttype;
+ protected static $itemsPerPage;
+ protected static $since_id;
+ protected static $max_id;
+
+ public static function content(array $parameters = [])
+ {
+ self::parseRequest($parameters);
+
+ $tabs = [];
+
+ if ((Session::isAuthenticated() || in_array(self::$page_style, [CP_USERS_AND_GLOBAL, CP_USERS_ON_SERVER])) && empty(DI::config()->get('system', 'singleuser'))) {
+ $tabs[] = [
+ 'label' => DI::l10n()->t('Local Community'),
+ 'url' => 'community/local',
+ 'sel' => self::$content == 'local' ? 'active' : '',
+ 'title' => DI::l10n()->t('Posts from local users on this server'),
+ 'id' => 'community-local-tab',
+ 'accesskey' => 'l'
+ ];
+ }
+
+ if (Session::isAuthenticated() || in_array(self::$page_style, [CP_USERS_AND_GLOBAL, CP_GLOBAL_COMMUNITY])) {
+ $tabs[] = [
+ 'label' => DI::l10n()->t('Global Community'),
+ 'url' => 'community/global',
+ 'sel' => self::$content == 'global' ? 'active' : '',
+ 'title' => DI::l10n()->t('Posts from users of the whole federated network'),
+ 'id' => 'community-global-tab',
+ 'accesskey' => 'g'
+ ];
+ }
+
+ $tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
+ $o = Renderer::replaceMacros($tab_tpl, ['$tabs' => $tabs]);
+
+ Nav::setSelected('community');
+
+ $items = self::getItems();
+
+ if (!DBA::isResult($items)) {
+ info(DI::l10n()->t('No results.'));
+ return $o;
+ }
+
+ // We need the editor here to be able to reshare an item.
+ if (Session::isAuthenticated()) {
+ $x = [
+ 'is_owner' => true,
+ 'allow_location' => DI::app()->user['allow_location'],
+ 'default_location' => DI::app()->user['default-location'],
+ 'nickname' => DI::app()->user['nickname'],
+ 'lockstate' => (is_array(DI::app()->user) && (strlen(DI::app()->user['allow_cid']) || strlen(DI::app()->user['allow_gid']) || strlen(DI::app()->user['deny_cid']) || strlen(DI::app()->user['deny_gid'])) ? 'lock' : 'unlock'),
+ 'acl' => ACL::getFullSelectorHTML(DI::page(), DI::app()->user, true),
+ 'bang' => '',
+ 'visitor' => 'block',
+ 'profile_uid' => local_user(),
+ ];
+ $o .= status_editor(DI::app(), $x, 0, true);
+ }
+
+ $o .= conversation(DI::app(), $items, 'community', false, false, 'commented', local_user());
+
+ $pager = new BoundariesPager(
+ DI::l10n(),
+ DI::args()->getQueryString(),
+ $items[0]['commented'],
+ $items[count($items) - 1]['commented'],
+ self::$itemsPerPage
+ );
+
+ $o .= $pager->renderMinimal(count($items));
+
+ if (Feature::isEnabled(local_user(), 'trending_tags')) {
+ DI::page()['aside'] .= TrendingTags::getHTML(self::$content);
+ }
+
+ $t = Renderer::getMarkupTemplate("community.tpl");
+ return Renderer::replaceMacros($t, [
+ '$content' => $o,
+ '$header' => '',
+ '$show_global_community_hint' => (self::$content == 'global') && DI::config()->get('system', 'show_global_community_hint'),
+ '$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.")
+ ]);
+ }
+
+ /**
+ * Computes module parameters from the request and local configuration
+ *
+ * @param array $parameters
+ * @throws HTTPException\BadRequestException
+ * @throws HTTPException\ForbiddenException
+ */
+ protected static function parseRequest(array $parameters)
+ {
+ if (DI::config()->get('system', 'block_public') && !Session::isAuthenticated()) {
+ throw new HTTPException\ForbiddenException(DI::l10n()->t('Public access denied.'));
+ }
+
+ self::$page_style = DI::config()->get('system', 'community_page_style');
+
+ if (self::$page_style == CP_NO_INTERNAL_COMMUNITY) {
+ throw new HTTPException\ForbiddenException(DI::l10n()->t('Access denied.'));
+ }
+
+ switch ($parameters['accounttype'] ?? '') {
+ case 'person':
+ self::$accounttype = User::ACCOUNT_TYPE_PERSON;
+ break;
+ case 'organisation':
+ self::$accounttype = User::ACCOUNT_TYPE_ORGANISATION;
+ break;
+ case 'news':
+ self::$accounttype = User::ACCOUNT_TYPE_NEWS;
+ break;
+ case 'community':
+ self::$accounttype = User::ACCOUNT_TYPE_COMMUNITY;
+ break;
+ default:
+ self::$accounttype = null;
+ break;
+ }
+
+ self::$content = $parameters['content'] ?? '';
+ if (!self::$content) {
+ if (!empty(DI::config()->get('system', 'singleuser'))) {
+ // On single user systems only the global page does make sense
+ self::$content = 'global';
+ } else {
+ // When only the global community is allowed, we use this as default
+ self::$content = self::$page_style == CP_GLOBAL_COMMUNITY ? 'global' : 'local';
+ }
+ }
+
+ if (!in_array(self::$content, ['local', 'global'])) {
+ throw new HTTPException\BadRequestException(DI::l10n()->t('Community option not available.'));
+ }
+
+ // Check if we are allowed to display the content to visitors
+ if (!Session::isAuthenticated()) {
+ $available = self::$page_style == CP_USERS_AND_GLOBAL;
+
+ if (!$available) {
+ $available = (self::$page_style == CP_USERS_ON_SERVER) && (self::$content == 'local');
+ }
+
+ if (!$available) {
+ $available = (self::$page_style == CP_GLOBAL_COMMUNITY) && (self::$content == 'global');
+ }
+
+ if (!$available) {
+ throw new HTTPException\ForbiddenException(DI::l10n()->t('Not available.'));
+ }
+ }
+
+ if (DI::mode()->isMobile()) {
+ self::$itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network',
+ DI::config()->get('system', 'itemspage_network_mobile'));
+ } else {
+ self::$itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_network',
+ DI::config()->get('system', 'itemspage_network'));
+ }
+
+ // now that we have the user settings, see if the theme forces
+ // a maximum item number which is lower then the user choice
+ if ((DI::app()->force_max_items > 0) && (DI::app()->force_max_items < self::$itemsPerPage)) {
+ self::$itemsPerPage = DI::app()->force_max_items;
+ }
+
+ self::$since_id = $_GET['since_id'] ?? null;
+ self::$max_id = $_GET['max_id'] ?? null;
+ }
+
+ /**
+ * Computes the displayed items.
+ *
+ * Community pages have a restriction on how many successive posts by the same author can show on any given page,
+ * so we may have to retrieve more content beyond the first query
+ *
+ * @return array
+ * @throws \Exception
+ */
+ protected static function getItems()
+ {
+ $items = self::selectItems(self::$since_id, self::$max_id, self::$itemsPerPage);
+
+ $maxpostperauthor = (int) DI::config()->get('system', 'max_author_posts_community_page');
+ if ($maxpostperauthor != 0 && self::$content == 'local') {
+ $count = 1;
+ $previousauthor = '';
+ $numposts = 0;
+ $selected_items = [];
+
+ while (count($selected_items) < self::$itemsPerPage && ++$count < 50 && count($items) > 0) {
+ foreach ($items as $item) {
+ if ($previousauthor == $item["author-link"]) {
+ ++$numposts;
+ } else {
+ $numposts = 0;
+ }
+ $previousauthor = $item["author-link"];
+
+ if (($numposts < $maxpostperauthor) && (count($selected_items) < self::$itemsPerPage)) {
+ $selected_items[] = $item;
+ }
+ }
+
+ // If we're looking at a "previous page", the lookup continues forward in time because the list is
+ // sorted in chronologically decreasing order
+ if (isset(self::$since_id)) {
+ self::$since_id = $items[0]['commented'];
+ } else {
+ // In any other case, the lookup continues backwards in time
+ self::$max_id = $items[count($items) - 1]['commented'];
+ }
+
+ $items = self::selectItems(self::$since_id, self::$max_id, self::$itemsPerPage);
+ }
+ } else {
+ $selected_items = $items;
+ }
+
+ return $selected_items;
+ }
+
+ /**
+ * Database query for the comunity page
+ *
+ * @param $since_id
+ * @param $max_id
+ * @param $itemspage
+ * @return array
+ * @throws \Exception
+ * @TODO Move to repository/factory
+ */
+ private static function selectItems($since_id, $max_id, $itemspage)
+ {
+ $r = false;
+
+ if (self::$content == 'local') {
+ $values = [];
+
+ $sql_accounttype = '';
+ $sql_boundaries = '';
+ if (!is_null(self::$accounttype)) {
+ $sql_accounttype = " AND `user`.`account-type` = ?";
+ $values[] = [self::$accounttype];
+ }
+
+ if (isset($since_id)) {
+ $sql_boundaries .= " AND `thread`.`commented` > ?";
+ $values[] = $since_id;
+ }
+
+ if (isset($max_id)) {
+ $sql_boundaries .= " AND `thread`.`commented` < ?";
+ $values[] = $max_id;
+ }
+
+ $values[] = $itemspage;
+
+ /// @todo Use "unsearchable" here as well (instead of "hidewall")
+ $r = DBA::p("SELECT `item`.`uri`, `author`.`url` AS `author-link`, `thread`.`commented` FROM `thread`
+ 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`
+ WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated`
+ AND NOT `thread`.`private` AND `thread`.`wall` AND `thread`.`origin`
+ $sql_accounttype
+ $sql_boundaries
+ ORDER BY `thread`.`commented` DESC
+ LIMIT ?", $values);
+ } elseif (self::$content == 'global') {
+ if (!is_null(self::$accounttype)) {
+ $condition = ["`uid` = ? AND NOT `author`.`unsearchable` AND NOT `owner`.`unsearchable` AND `owner`.`contact-type` = ?", 0, self::$accounttype];
+ } else {
+ $condition = ["`uid` = ? AND NOT `author`.`unsearchable` AND NOT `owner`.`unsearchable`", 0];
+ }
+
+ if (isset($max_id)) {
+ $condition[0] .= " AND `commented` < ?";
+ $condition[] = $max_id;
+ }
+
+ if (isset($since_id)) {
+ $condition[0] .= " AND `commented` > ?";
+ $condition[] = $since_id;
+ }
+
+ $r = Item::selectThreadForUser(0, ['uri', 'commented'], $condition, ['order' => ['commented' => true], 'limit' => $itemspage]);
+ }
+
+ return DBA::toArray($r);
+ }
+}
diff --git a/src/Module/Directory.php b/src/Module/Directory.php
index 6bf246a37..0709aa397 100644
--- a/src/Module/Directory.php
+++ b/src/Module/Directory.php
@@ -70,7 +70,7 @@ class Directory extends BaseModule
$gDirPath = Profile::zrl($dirURL, true);
}
- $pager = new Pager(DI::args()->getQueryString(), 60);
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 60);
$profiles = Profile::searchProfiles($pager->getStart(), $pager->getItemsPerPage(), $search);
diff --git a/src/Module/Profile/Contacts.php b/src/Module/Profile/Contacts.php
index 5ea3e0684..3a42b0d31 100644
--- a/src/Module/Profile/Contacts.php
+++ b/src/Module/Profile/Contacts.php
@@ -85,7 +85,7 @@ class Contacts extends BaseProfile
$total = DBA::count('contact', $condition);
- $pager = new Pager(DI::args()->getQueryString());
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString());
$params = ['order' => ['name' => false], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
diff --git a/src/Module/Profile/Status.php b/src/Module/Profile/Status.php
index c3c5e461f..338cf6ef4 100644
--- a/src/Module/Profile/Status.php
+++ b/src/Module/Profile/Status.php
@@ -166,12 +166,12 @@ class Status extends BaseProfile
$sql_extra3 = "";
}
- // check if we serve a mobile device and get the user settings
- // accordingly
if (DI::mode()->isMobile()) {
- $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network', 10);
+ $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network',
+ DI::config()->get('system', 'itemspage_network_mobile'));
} else {
- $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_network', 20);
+ $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_network',
+ DI::config()->get('system', 'itemspage_network'));
}
// now that we have the user settings, see if the theme forces
@@ -180,7 +180,7 @@ class Status extends BaseProfile
$itemspage_network = $a->force_max_items;
}
- $pager = new Pager($args->getQueryString(), $itemspage_network);
+ $pager = new Pager(DI::l10n(), $args->getQueryString(), $itemspage_network);
$pager_sql = sprintf(" LIMIT %d, %d ", $pager->getStart(), $pager->getItemsPerPage());
@@ -231,7 +231,7 @@ class Status extends BaseProfile
$items = array_merge($items, $pinned);
}
- $o .= conversation($a, $items, $pager, 'profile', false, false, 'pinned_received', $a->profile['uid']);
+ $o .= conversation($a, $items, 'profile', false, false, 'pinned_received', $a->profile['uid']);
$o .= $pager->renderMinimal(count($items));
diff --git a/src/Module/Search/Index.php b/src/Module/Search/Index.php
index a68086ecc..44407623e 100644
--- a/src/Module/Search/Index.php
+++ b/src/Module/Search/Index.php
@@ -137,7 +137,15 @@ class Index extends BaseSearch
// OR your own posts if you are a logged in member
// No items will be shown if the member has a blocked profile wall.
- $pager = new Pager(DI::args()->getQueryString());
+ if (DI::mode()->isMobile()) {
+ $itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network',
+ DI::config()->get('system', 'itemspage_network_mobile'));
+ } else {
+ $itemsPerPage = DI::pConfig()->get(local_user(), 'system', 'itemspage_network',
+ DI::config()->get('system', 'itemspage_network'));
+ }
+
+ $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), $itemsPerPage);
if ($tag) {
Logger::info('Start tag search.', ['q' => $search]);
@@ -200,7 +208,7 @@ class Index extends BaseSearch
Logger::info('Start Conversation.', ['q' => $search]);
- $o .= conversation(DI::app(), $r, $pager, 'search', false, false, 'commented', local_user());
+ $o .= conversation(DI::app(), $r, 'search', false, false, 'commented', local_user());
$o .= $pager->renderMinimal(count($r));
diff --git a/src/Module/Update/Community.php b/src/Module/Update/Community.php
new file mode 100644
index 000000000..e0bc6c067
--- /dev/null
+++ b/src/Module/Update/Community.php
@@ -0,0 +1,44 @@
+.
+ *
+ * See update_profile.php for documentation
+ */
+
+namespace Friendica\Module\Update;
+
+use Friendica\Core\System;
+use Friendica\DI;
+use Friendica\Module\Conversation\Community as CommunityModule;
+
+/**
+ * Asynchronous update module for the community page
+ *
+ * @package Friendica\Module\Update
+ */
+class Community extends CommunityModule
+{
+ public static function rawContent(array $parameters = [])
+ {
+ self::parseRequest($parameters);
+
+ $o = conversation(DI::app(), self::getItems(), 'community', true, false, 'commented', local_user());
+
+ System::htmlUpdateExit($o);
+ }
+}
diff --git a/src/Module/Update/Profile.php b/src/Module/Update/Profile.php
index d23f766b5..662042eb1 100644
--- a/src/Module/Update/Profile.php
+++ b/src/Module/Update/Profile.php
@@ -24,6 +24,7 @@ namespace Friendica\Module\Update;
use Friendica\BaseModule;
use Friendica\Content\Pager;
use Friendica\Core\Session;
+use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Item;
@@ -95,8 +96,6 @@ class Profile extends BaseModule
return '';
}
- $pager = new Pager(DI::args()->getQueryString());
-
// Set a time stamp for this page. We will make use of it when we
// search for new items (update routine)
$last_updated_array[$last_updated_key] = time();
@@ -116,29 +115,8 @@ class Profile extends BaseModule
$items = DBA::toArray($items_stmt);
- $o .= conversation($a, $items, $pager, 'profile', $profile_uid, false, 'received', $a->profile['uid']);
+ $o .= conversation($a, $items, 'profile', $profile_uid, false, 'received', $a->profile['uid']);
- header("Content-type: text/html");
- echo "\r\n";
- // We can remove this hack once Internet Explorer recognises HTML5 natively
- echo "";
- echo $o;
- if (DI::pConfig()->get(local_user(), "system", "bandwidth_saver")) {
- $replace = "
".DI::l10n()->t("[Embedded content - reload page to view]")."
";
- $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
- $o = preg_replace($pattern, $replace, $o);
- $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
- $o = preg_replace($pattern, $replace, $o);
- $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
- $o = preg_replace($pattern, $replace, $o);
- $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
- $o = preg_replace($pattern, $replace, $o);
- }
-
- // reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well
- echo str_replace("\t", " ", $o);
- echo "";
- echo "\r\n";
- exit();
+ System::htmlUpdateExit($o);
}
}
diff --git a/static/defaults.config.php b/static/defaults.config.php
index f9eda841f..ab47eef19 100644
--- a/static/defaults.config.php
+++ b/static/defaults.config.php
@@ -227,6 +227,15 @@ return [
// If set true registration is only possible after a current member of the node has send an invitation.
'invitation_only' => false,
+ // itemspage_network (Integer)
+ // default number of items per page in stream pages (network, community, profile/contact statuses, search)
+ 'itemspage_network' => 40,
+
+ // itemspage_network_mobile (Integer)
+ // default number of items per page in stream pages (network, community, profile/contact statuses, search)
+ // on detected mobile devices
+ 'itemspage_network_mobile' => 20,
+
// like_no_comment (Boolean)
// Don't update the "commented" value of an item when it is liked.
'like_no_comment' => false,
diff --git a/static/routes.config.php b/static/routes.config.php
index 489e99f48..d0a1bde76 100644
--- a/static/routes.config.php
+++ b/static/routes.config.php
@@ -102,6 +102,9 @@ return [
'/attach/{item:\d+}' => [Module\Attach::class, [R::GET]],
'/babel' => [Module\Debug\Babel::class, [R::GET, R::POST]],
'/bookmarklet' => [Module\Bookmarklet::class, [R::GET]],
+
+ '/community[/{content}[/{accounttype}]]' => [Module\Conversation\Community::class, [R::GET]],
+
'/compose[/{type}]' => [Module\Item\Compose::class, [R::GET, R::POST]],
'/contact' => [
@@ -288,6 +291,7 @@ return [
'/toggle_mobile' => [Module\ToggleMobile::class, [R::GET]],
'/tos' => [Module\Tos::class, [R::GET]],
+ '/update_community[/{content}[/{accounttype}]]' => [Module\Update\Community::class, [R::GET]],
'/update_profile' => [Module\Update\Profile::class, [R::GET]],
'/view/theme/{theme}/style.pcss' => [Module\Theme::class, [R::GET]],
diff --git a/view/js/main.js b/view/js/main.js
index 41bae7cf2..0718ea3ca 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -104,6 +104,20 @@ function decodeHtml(html) {
return txt.value;
}
+/**
+ * Retrieves a single named query string parameter
+ *
+ * @param {string} name
+ * @returns {string}
+ * @see https://davidwalsh.name/query-string-javascript
+ */
+function getUrlParameter(name) {
+ name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
+ var regex = new RegExp('[\\?&]' + name + '=([^]*)');
+ var results = regex.exec(location.search);
+ return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
+};
+
var src = null;
var prev = null;
var livetime = null;
@@ -511,7 +525,13 @@ function updateConvItems(data) {
var ident = $(this).attr('id');
// Add new top-level item.
- if ($('#' + ident).length == 0 && profile_page == 1) {
+ if ($('#' + ident).length === 0
+ && (!getUrlParameter('page')
+ && !getUrlParameter('max_id')
+ && !getUrlParameter('since_id')
+ || getUrlParameter('page') === '1'
+ )
+ ) {
$('#' + prev).after($(this));
// Replace already existing thread.
@@ -573,7 +593,18 @@ function liveUpdate(src) {
var orgHeight = $("section").height();
var udargs = ((netargs.length) ? '/' + netargs : '');
- var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&page=' + profile_page + '&force=' + ((force_update) ? 1 : 0) + '&item=' + update_item;
+
+ var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&force=' + ((force_update) ? 1 : 0) + '&item=' + update_item;
+
+ if (getUrlParameter('page')) {
+ update_url += '&page=' + getUrlParameter('page');
+ }
+ if (getUrlParameter('since_id')) {
+ update_url += '&since_id=' + getUrlParameter('since_id');
+ }
+ if (getUrlParameter('max_id')) {
+ update_url += '&max_id=' + getUrlParameter('max_id');
+ }
$.get(update_url,function(data) {
in_progress = false;