From f1ebaf5e7d6b276c92c2fb436f5258596a6f0975 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 24 Oct 2018 02:07:21 -0400 Subject: [PATCH 1/6] Add new Content\Pager class --- src/Content/Pager.php | 295 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 src/Content/Pager.php diff --git a/src/Content/Pager.php b/src/Content/Pager.php new file mode 100644 index 0000000000..185c5506d9 --- /dev/null +++ b/src/Content/Pager.php @@ -0,0 +1,295 @@ + + */ +class Pager +{ + /** + * @var integer + */ + private $page = 1; + /** + * @var integer + */ + private $itemsPerPage = 50; + /** + * @var integer + */ + private $itemCount = 0; + + /** + * @var string + */ + private $baseQueryString = ''; + + /** + * Instantiates a new Pager with the base parameters. + * + * Guesses the page number from the GET parameter 'page'. + * + * @param string $queryString The query string of the current page + * @param integer $itemCount The total item count (for the full mode) or null (for the minimal mode) + * @param integer $itemsPerPage An optional number of items per page to override the default value + */ + public function __construct($queryString, $itemCount = null, $itemsPerPage = 50) + { + $this->setQueryString($queryString); + $this->setItemsPerPage($itemsPerPage); + $this->setItemCount(defaults($itemCount, $this->getItemsPerPage())); + $this->setPage(defaults($_GET, 'page', 1)); + } + + /** + * Returns the start offset for a LIMIT clause. Starts at 0. + * + * @return integer + */ + public function getStart() + { + return max(0, ($this->page * $this->itemsPerPage) - $this->itemsPerPage); + } + + /** + * Returns the number of items per page + * + * @return integer + */ + public function getItemsPerPage() + { + return $this->itemsPerPage; + } + + /** + * Returns the current page number + * + * @return type + */ + public function getPage() + { + return $this->page; + } + + /** + * Returns the base query string. + * + * Warning: this isn't the same value as passed to the constructor. + * See setQueryString for the inventory of transformations + * + * @see setBaseQuery() + * @return string + */ + public function getBaseQueryString() + { + return $this->baseQueryString; + } + + /** + * Sets the number of items per page, 1 minimum. + * + * @param integer $itemsPerPage + */ + public function setItemsPerPage($itemsPerPage) + { + $this->itemsPerPage = max(1, intval($itemsPerPage)); + } + + /** + * Sets the current page number. Starts at 1. + * + * @param integer $page + */ + public function setPage($page) + { + $this->page = max(1, intval($page)); + } + + /** + * Sets the item count, 0 minimum. + * + * @param integer $itemCount + */ + public function setItemCount($itemCount) + { + $this->itemCount = max(0, intval($itemCount)); + } + + /** + * Sets the base query string from a full query string. + * + * Strips the 'page' parameter, and remove the 'q=' string for some reason. + * + * @param string $queryString + */ + public function setQueryString($queryString) + { + $stripped = preg_replace('/([&?]page=[0-9]*)/', '', $queryString); + + $stripped = str_replace('q=', '', $stripped); + $stripped = trim($stripped, '/'); + + $this->baseQueryString = $stripped; + } + + /** + * Ensures the provided URI has its query string punctuation in order. + * + * @param string $uri + * @return string + */ + private function ensureQueryParameter($uri) + { + if (strpos($uri, '?') === false && ($pos = strpos($uri, '&')) !== false) { + $uri = substr($uri, 0, $pos) . '?' . substr($uri, $pos + 1); + } + + return $uri; + } + + /** + * @brief 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: + * + * $pager = new Pager($a->query_string); + * + * $params = ['order' => ['sort_field' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; + * $items = DBA::toArray(DBA::select($table, $fields, $condition, $params)); + * + * $html = $pager->renderMinimal(count($items)); + * + * @param integer $itemCount The number of displayed items on the page + * @return string HTML string of the pager + */ + public function renderMinimal($itemCount) + { + $this->setItemCount($itemCount); + + $data = [ + 'class' => 'pager', + 'prev' => [ + 'url' => $this->ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() - 1)), + 'text' => L10n::t('newer'), + 'class' => 'previous' . ($this->getPage() == 1 ? ' disabled' : '') + ], + 'next' => [ + 'url' => $this->ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() + 1)), + 'text' => L10n::t('older'), + 'class' => 'next' . ($this->itemCount <= 0 ? ' disabled' : '') + ] + ]; + + $tpl = get_markup_template('paginate.tpl'); + return replace_macros($tpl, ['pager' => $data]); + } + + /** + * @brief Full pager (first / prev / 1 / 2 / ... / 14 / 15 / next / last) + * + * This mode presents page numbers as well as first, previous, next and last links. + * The itemCount is the total number of items including those not displayed. + * + * Example usage: + * + * $total = DBA::count($table, $condition); + * + * $pager = new Pager($a->query_string, $total); + * + * $params = ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; + * $items = DBA::toArray(DBA::select($table, $fields, $condition, $params)); + * + * $html = $pager->renderFull(); + * + * @return string HTML string of the pager + */ + public function renderFull() + { + $data = []; + + $data['class'] = 'pagination'; + if ($this->itemCount > $this->getItemsPerPage()) { + $data['first'] = [ + 'url' => $this->ensureQueryParameter($this->baseQueryString . '&page=1'), + 'text' => L10n::t('first'), + 'class' => $this->getPage() == 1 ? 'disabled' : '' + ]; + $data['prev'] = [ + 'url' => $this->ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() - 1)), + 'text' => L10n::t('prev'), + 'class' => $this->getPage() == 1 ? 'disabled' : '' + ]; + + $numpages = $this->itemCount / $this->getItemsPerPage(); + + $numstart = 1; + $numstop = $numpages; + + // Limit the number of displayed page number buttons. + if ($numpages > 8) { + $numstart = (($this->getPage() > 4) ? ($this->getPage() - 4) : 1); + $numstop = (($this->getPage() > ($numpages - 7)) ? $numpages : ($numstart + 8)); + } + + $pages = []; + + for ($i = $numstart; $i <= $numstop; $i++) { + if ($i == $this->getPage()) { + $pages[$i] = [ + 'url' => '#', + 'text' => $i, + 'class' => 'current active' + ]; + } else { + $pages[$i] = [ + 'url' => $this->ensureQueryParameter($this->baseQueryString . '&page=' . $i), + 'text' => $i, + 'class' => 'n' + ]; + } + } + + if (($this->itemCount % $this->getItemsPerPage()) != 0) { + if ($i == $this->getPage()) { + $pages[$i] = [ + 'url' => '#', + 'text' => $i, + 'class' => 'current active' + ]; + } else { + $pages[$i] = [ + 'url' => $this->ensureQueryParameter($this->baseQueryString . '&page=' . $i), + 'text' => $i, + 'class' => 'n' + ]; + } + } + + $data['pages'] = $pages; + + $lastpage = (($numpages > intval($numpages)) ? intval($numpages)+1 : $numpages); + + $data['next'] = [ + 'url' => $this->ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() + 1)), + 'text' => L10n::t('next'), + 'class' => $this->getPage() == $lastpage ? 'disabled' : '' + ]; + $data['last'] = [ + 'url' => $this->ensureQueryParameter($this->baseQueryString . '&page=' . $lastpage), + 'text' => L10n::t('last'), + 'class' => $this->getPage() == $lastpage ? 'disabled' : '' + ]; + } + + $tpl = get_markup_template('paginate.tpl'); + return replace_macros($tpl, ['pager' => $data]); + } +} From a976a4cb68d196a2fb7d38247c3ad30a0026d327 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 24 Oct 2018 02:07:44 -0400 Subject: [PATCH 2/6] Add new Hook::add method to enable module hooks --- src/Core/Hook.php | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Core/Hook.php b/src/Core/Hook.php index 85ed98e886..a0200a7db3 100644 --- a/src/Core/Hook.php +++ b/src/Core/Hook.php @@ -38,16 +38,32 @@ class Hook extends BaseObject $stmt = DBA::select('hook', ['hook', 'file', 'function'], [], ['order' => ['priority' => 'desc', 'file']]); while ($hook = DBA::fetch($stmt)) { - if (!array_key_exists($hook['hook'], self::$hooks)) { - self::$hooks[$hook['hook']] = []; - } - self::$hooks[$hook['hook']][] = [$hook['file'], $hook['function']]; + self::add($hook['hook'], $hook['file'], $hook['function']); } DBA::close($stmt); } /** - * Registers a hook. + * @brief Adds a new hook to the hooks array. + * + * This function is meant to be called by modules on each page load as it works after loadHooks has been called. + * + * @param type $hook + * @param type $file + * @param type $function + */ + public static function add($hook, $file, $function) + { + if (!array_key_exists($hook, self::$hooks)) { + self::$hooks[$hook] = []; + } + self::$hooks[$hook][] = [$file, $function]; + } + + /** + * @brief Registers a hook. + * + * This function is meant to be called once when an addon is enabled for example as it doesn't add to the current hooks. * * @param string $hook the name of the hook * @param string $file the name of the file that hooks into From 14237a95998bed6a5fe5e7e9122970b9dea77a27 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 24 Oct 2018 02:15:24 -0400 Subject: [PATCH 3/6] Move $pager and $page_offset out of App - Move infinite scroll data output in a module hook - Use Pager instead of paginate() and alt_pager() --- boot.php | 42 -------- include/conversation.php | 15 +-- include/text.php | 126 ----------------------- mod/admin.php | 21 ++-- mod/allfriends.php | 7 +- mod/common.php | 9 +- mod/community.php | 17 +-- mod/directory.php | 11 +- mod/dirfind.php | 27 +++-- mod/display.php | 6 +- mod/item.php | 6 +- mod/match.php | 14 ++- mod/message.php | 13 ++- mod/network.php | 123 +++++++++++++++------- mod/notes.php | 9 +- mod/notifications.php | 9 +- mod/photos.php | 30 +++--- mod/profile.php | 11 +- mod/search.php | 11 +- mod/videos.php | 13 +-- mod/viewcontacts.php | 14 ++- src/App.php | 33 ------ src/Core/ACL.php | 3 +- src/Model/Contact.php | 11 +- src/Module/Contact.php | 9 +- view/js/main.js | 2 +- view/templates/head.tpl | 9 -- view/templates/infinite_scroll_head.tpl | 8 ++ view/theme/frio/templates/js_strings.tpl | 10 -- 29 files changed, 234 insertions(+), 385 deletions(-) create mode 100644 view/templates/infinite_scroll_head.tpl diff --git a/boot.php b/boot.php index 7fb87ca4eb..6b66625c6c 100644 --- a/boot.php +++ b/boot.php @@ -1069,45 +1069,3 @@ function validate_include(&$file) // Simply return flag return $valid; } - -/** - * @brief Get the data which is needed for infinite scroll - * - * For invinite scroll we need the page number of the actual page - * and the the URI where the content of the next page comes from. - * This data is needed for the js part in main.js. - * Note: infinite scroll does only work for the network page (module) - * - * @param string $module The name of the module (e.g. "network") - * @return array Of infinite scroll data - * 'pageno' => $pageno The number of the actual page - * 'reload_uri' => $reload_uri The URI of the content we have to load - */ -function infinite_scroll_data($module) -{ - if (PConfig::get(local_user(), 'system', 'infinite_scroll') - && $module == 'network' - && defaults($_GET, 'mode', '') != 'minimal' - ) { - // get the page number - $pageno = defaults($_GET, 'page', 1); - - $reload_uri = ""; - - // try to get the uri from which we load the content - foreach ($_GET as $param => $value) { - if (($param != "page") && ($param != "q")) { - $reload_uri .= "&" . $param . "=" . urlencode($value); - } - } - - $a = get_app(); - if ($a->page_offset != "" && !strstr($reload_uri, "&offset=")) { - $reload_uri .= "&offset=" . urlencode($a->page_offset); - } - - $arr = ["pageno" => $pageno, "reload_uri" => $reload_uri]; - - return $arr; - } -} diff --git a/include/conversation.php b/include/conversation.php index 4a05c916ba..27cbd4289b 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -6,6 +6,7 @@ use Friendica\App; use Friendica\Content\ContactSelector; use Friendica\Content\Feature; +use Friendica\Content\Pager; use Friendica\Content\Text\BBCode; use Friendica\Core\Addon; use Friendica\Core\Config; @@ -433,8 +434,8 @@ function conv_get_blocklist() * that are based on unique features of the calling module. * */ -function conversation(App $a, array $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0) { - +function conversation(App $a, array $items, Pager $pager, $mode, $update, $preview = false, $order = 'commented', $uid = 0) +{ $ssl_state = (local_user() ? true : false); $profile_owner = 0; @@ -469,7 +470,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o . ((x($_GET, 'cmax')) ? '&cmax=' . $_GET['cmax'] : '') . ((x($_GET, 'file')) ? '&file=' . $_GET['file'] : '') - . "'; var profile_page = " . $a->pager['page'] . "; \r\n"; + . "'; var profile_page = " . $pager->getPage() . "; \r\n"; } } elseif ($mode === 'profile') { $items = conversation_add_children($items, false, $order, $uid); @@ -488,7 +489,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o $live_update_div = '
' . "\r\n" . "\r\n"; + . "; var netargs = '?f='; var profile_page = " . $pager->getPage() . "; \r\n"; } } } elseif ($mode === 'notes') { @@ -498,7 +499,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o if (!$update) { $live_update_div = '
' . "\r\n" . "\r\n"; + . "; var netargs = '/?f='; var profile_page = " . $pager->getPage() . "; \r\n"; } } elseif ($mode === 'display') { $items = conversation_add_children($items, false, $order, $uid); @@ -516,7 +517,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o if (!$update) { $live_update_div = '
' . "\r\n" . "\r\n"; + ."/?f='; var profile_page = " . $pager->getPage() . "; \r\n"; } } elseif ($mode === 'contacts') { $items = conversation_add_children($items, true, $order, $uid); @@ -525,7 +526,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o if (!$update) { $live_update_div = '
' . "\r\n" . "\r\n"; + ."/?f='; var profile_page = " . $pager->getPage() . "; \r\n"; } } elseif ($mode === 'search') { $live_update_div = '' . "\r\n"; diff --git a/include/text.php b/include/text.php index 5a18529d93..2d497bd58b 100644 --- a/include/text.php +++ b/include/text.php @@ -262,132 +262,6 @@ function unxmlify($s) { return $ret; } - -/** - * @brief Paginator function. Pushes relevant links in a pager array structure. - * - * Links are generated depending on the current page and the total number of items. - * Inactive links (like "first" and "prev" on page 1) are given the "disabled" class. - * Current page link is given the "active" CSS class - * - * @param App $a App instance - * @param int $count [optional] item count (used with minimal pager) - * @return Array data for pagination template - */ -function paginate_data(App $a, $count = null) { - $stripped = preg_replace('/([&?]page=[0-9]*)/', '', $a->query_string); - - $stripped = str_replace('q=', '', $stripped); - $stripped = trim($stripped, '/'); - $pagenum = $a->pager['page']; - - if (($a->page_offset != '') && !preg_match('/[?&].offset=/', $stripped)) { - $stripped .= '&offset=' . urlencode($a->page_offset); - } - - $url = $stripped; - $data = []; - - function _l(&$d, $name, $url, $text, $class = '') { - if (strpos($url, '?') === false && ($pos = strpos($url, '&')) !== false) { - $url = substr($url, 0, $pos) . '?' . substr($url, $pos + 1); - } - - $d[$name] = ['url' => $url, 'text' => $text, 'class' => $class]; - } - - if (!is_null($count)) { - // minimal pager (newer / older) - $data['class'] = 'pager'; - _l($data, 'prev', $url . '&page=' . ($a->pager['page'] - 1), L10n::t('newer'), 'previous' . ($a->pager['page'] == 1 ? ' disabled' : '')); - _l($data, 'next', $url . '&page=' . ($a->pager['page'] + 1), L10n::t('older'), 'next' . ($count <= 0 ? ' disabled' : '')); - } else { - // full pager (first / prev / 1 / 2 / ... / 14 / 15 / next / last) - $data['class'] = 'pagination'; - if ($a->pager['total'] > $a->pager['itemspage']) { - _l($data, 'first', $url . '&page=1', L10n::t('first'), $a->pager['page'] == 1 ? 'disabled' : ''); - _l($data, 'prev', $url . '&page=' . ($a->pager['page'] - 1), L10n::t('prev'), $a->pager['page'] == 1 ? 'disabled' : ''); - - $numpages = $a->pager['total'] / $a->pager['itemspage']; - - $numstart = 1; - $numstop = $numpages; - - // Limit the number of displayed page number buttons. - if ($numpages > 8) { - $numstart = (($pagenum > 4) ? ($pagenum - 4) : 1); - $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 8)); - } - - $pages = []; - - for ($i = $numstart; $i <= $numstop; $i++) { - if ($i == $a->pager['page']) { - _l($pages, $i, '#', $i, 'current active'); - } else { - _l($pages, $i, $url . '&page='. $i, $i, 'n'); - } - } - - if (($a->pager['total'] % $a->pager['itemspage']) != 0) { - if ($i == $a->pager['page']) { - _l($pages, $i, '#', $i, 'current active'); - } else { - _l($pages, $i, $url . '&page=' . $i, $i, 'n'); - } - } - - $data['pages'] = $pages; - - $lastpage = (($numpages > intval($numpages)) ? intval($numpages)+1 : $numpages); - _l($data, 'next', $url . '&page=' . ($a->pager['page'] + 1), L10n::t('next'), $a->pager['page'] == $lastpage ? 'disabled' : ''); - _l($data, 'last', $url . '&page=' . $lastpage, L10n::t('last'), $a->pager['page'] == $lastpage ? 'disabled' : ''); - } - } - - return $data; -} - - -/** - * Automatic pagination. - * - * To use, get the count of total items. - * Then call $a->set_pager_total($number_items); - * Optionally call $a->set_pager_itemspage($n) to the number of items to display on each page - * Then call paginate($a) after the end of the display loop to insert the pager block on the page - * (assuming there are enough items to paginate). - * When using with SQL, the setting LIMIT %d, %d => $a->pager['start'],$a->pager['itemspage'] - * will limit the results to the correct items for the current page. - * The actual page handling is then accomplished at the application layer. - * - * @param App $a App instance - * @return string html for pagination #FIXME remove html - */ -function paginate(App $a) { - - $data = paginate_data($a); - $tpl = get_markup_template("paginate.tpl"); - return replace_macros($tpl, ["pager" => $data]); - -} - - -/** - * Alternative pager - * @param App $a App instance - * @param int $i - * @return string html for pagination #FIXME remove html - */ -function alt_pager(App $a, $i) { - - $data = paginate_data($a, $i); - $tpl = get_markup_template("paginate.tpl"); - return replace_macros($tpl, ['pager' => $data]); - -} - - /** * Loader for infinite scrolling * @return string html for loader diff --git a/mod/admin.php b/mod/admin.php index c50927e97c..d90cfb7ab9 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -8,6 +8,7 @@ use Friendica\App; use Friendica\BaseModule; use Friendica\Content\Feature; +use Friendica\Content\Pager; use Friendica\Content\Text\Markdown; use Friendica\Core\Addon; use Friendica\Core\Config; @@ -482,10 +483,9 @@ function admin_page_contactblock(App $a) $total = DBA::count('contact', $condition); - $a->setPagerTotal($total); - $a->setPagerItemsPage(30); + $pager = new Pager($a->query_string, $total, 30); - $statement = DBA::select('contact', [], $condition, ['limit' => [$a->pager['start'], $a->pager['itemspage']]]); + $statement = DBA::select('contact', [], $condition, ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]]); $contacts = DBA::toArray($statement); @@ -513,7 +513,7 @@ function admin_page_contactblock(App $a) '$contacts' => $contacts, '$total_contacts' => L10n::tt('%s total blocked contact', '%s total blocked contacts', $total), - '$paginate' => paginate($a), + '$paginate' => $pager->renderFull(), '$contacturl' => ['contact_url', L10n::t("Profile URL"), '', L10n::t("URL of the remote contact to block.")], ]); return $o; @@ -1812,12 +1812,7 @@ function admin_page_users(App $a) /* get pending */ $pending = Register::getPending(); - /* get users */ - $total = q("SELECT COUNT(*) AS `total` FROM `user` WHERE 1"); - if (count($total)) { - $a->setPagerTotal($total[0]['total']); - $a->setPagerItemsPage(100); - } + $pager = new Pager($a->query_string, DBA::count('user'), 100); /* ordering */ $valid_orders = [ @@ -1849,7 +1844,7 @@ function admin_page_users(App $a) FROM `user` INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self` WHERE `user`.`verified` - ORDER BY $sql_order $sql_order_direction LIMIT %d, %d", intval($a->pager['start']), intval($a->pager['itemspage']) + ORDER BY $sql_order $sql_order_direction LIMIT %d, %d", $pager->getStart(), $pager->getItemsPerPage() ); $adminlist = explode(",", str_replace(" ", "", Config::get('config', 'admin_email'))); @@ -1947,7 +1942,7 @@ function admin_page_users(App $a) '$form_security_token' => BaseModule::getFormSecurityToken("admin_users"), // values // - '$baseurl' => System::baseUrl(true), + '$baseurl' => $a->getBaseURL(true), '$pending' => $pending, 'deleted' => $deleted, @@ -1956,7 +1951,7 @@ function admin_page_users(App $a) '$newusernickname' => ['new_user_nickname', L10n::t("Nickname"), '', L10n::t("Nickname of the new user.")], '$newuseremail' => ['new_user_email', L10n::t("Email"), '', L10n::t("Email address of the new user."), '', '', 'email'], ]); - $o .= paginate($a); + $o .= $pager->renderFull(); return $o; } diff --git a/mod/allfriends.php b/mod/allfriends.php index cee067e97a..d2501e9fe4 100644 --- a/mod/allfriends.php +++ b/mod/allfriends.php @@ -5,6 +5,7 @@ use Friendica\App; use Friendica\Content\ContactSelector; +use Friendica\Content\Pager; use Friendica\Core\L10n; use Friendica\Core\System; use Friendica\Database\DBA; @@ -45,9 +46,9 @@ function allfriends_content(App $a) $total = Model\GContact::countAllFriends(local_user(), $cid); - $a->setPagerTotal($total); + $pager = new Pager($a->query_string, $total); - $r = Model\GContact::allFriends(local_user(), $cid, $a->pager['start'], $a->pager['itemspage']); + $r = Model\GContact::allFriends(local_user(), $cid, $pager->getStart(), $pager->getItemsPerPage()); if (!DBA::isResult($r)) { $o .= L10n::t('No friends to display.'); return $o; @@ -103,7 +104,7 @@ function allfriends_content(App $a) //'$title' => L10n::t('Friends of %s', htmlentities($c[0]['name'])), '$tab_str' => $tab_str, '$contacts' => $entries, - '$paginate' => paginate($a), + '$paginate' => $pager->renderFull(), ]); return $o; diff --git a/mod/common.php b/mod/common.php index 0b51f20d73..993bc58777 100644 --- a/mod/common.php +++ b/mod/common.php @@ -5,6 +5,7 @@ use Friendica\App; use Friendica\Content\ContactSelector; +use Friendica\Content\Pager; use Friendica\Core\L10n; use Friendica\Database\DBA; use Friendica\Model; @@ -87,16 +88,16 @@ function common_content(App $a) } if ($t > 0) { - $a->setPagerTotal($t); + $pager = new Pager($a->query_string, $t); } else { notice(L10n::t('No contacts in common.') . EOL); return $o; } if ($cid) { - $r = Model\GContact::commonFriends($uid, $cid, $a->pager['start'], $a->pager['itemspage']); + $r = Model\GContact::commonFriends($uid, $cid, $pager->getStart(), $pager->getItemsPerPage()); } else { - $r = Model\GContact::commonFriendsZcid($uid, $zcid, $a->pager['start'], $a->pager['itemspage']); + $r = Model\GContact::commonFriendsZcid($uid, $zcid, $pager->getStart(), $pager->getItemsPerPage()); } if (!DBA::isResult($r)) { @@ -147,7 +148,7 @@ function common_content(App $a) '$title' => $title, '$tab_str' => $tab_str, '$contacts' => $entries, - '$paginate' => paginate($a), + '$paginate' => $pager->renderFull(), ]); return $o; diff --git a/mod/community.php b/mod/community.php index 0eaccc0db0..7474fc2429 100644 --- a/mod/community.php +++ b/mod/community.php @@ -5,6 +5,7 @@ use Friendica\App; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Core\ACL; use Friendica\Core\Config; use Friendica\Core\L10n; @@ -153,9 +154,9 @@ function community_content(App $a, $update = 0) $itemspage_network = $a->force_max_items; } - $a->setPagerItemsPage($itemspage_network); + $pager = new Pager($a->query_string, null, $itemspage_network); - $r = community_getitems($a->pager['start'], $a->pager['itemspage'], $content, $accounttype); + $r = community_getitems($pager->getStart(), $pager->getItemsPerPage(), $content, $accounttype); if (!DBA::isResult($r)) { info(L10n::t('No results.') . EOL); @@ -179,22 +180,22 @@ function community_content(App $a, $update = 0) } $previousauthor = $item["author-link"]; - if (($numposts < $maxpostperauthor) && (count($s) < $a->pager['itemspage'])) { + if (($numposts < $maxpostperauthor) && (count($s) < $pager->getItemsPerPage())) { $s[] = $item; } } - if (count($s) < $a->pager['itemspage']) { - $r = community_getitems($a->pager['start'] + ($count * $a->pager['itemspage']), $a->pager['itemspage'], $content, $accounttype); + if (count($s) < $pager->getItemsPerPage()) { + $r = community_getitems($pager->getStart() + ($count * $pager->getItemsPerPage()), $pager->getItemsPerPage(), $content, $accounttype); } - } while ((count($s) < $a->pager['itemspage']) && ( ++$count < 50) && (count($r) > 0)); + } while ((count($s) < $pager->getItemsPerPage()) && ( ++$count < 50) && (count($r) > 0)); } else { $s = $r; } - $o .= conversation($a, $s, 'community', $update, false, 'commented', local_user()); + $o .= conversation($a, $s, $pager, 'community', $update, false, 'commented', local_user()); if (!$update) { - $o .= alt_pager($a, count($r)); + $o .= $pager->renderMinimal(count($r)); } $t = get_markup_template("community.tpl"); diff --git a/mod/directory.php b/mod/directory.php index 202132e366..f9104b9a53 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -5,6 +5,7 @@ use Friendica\App; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Content\Widget; use Friendica\Core\Addon; use Friendica\Core\Config; @@ -16,8 +17,6 @@ use Friendica\Util\Proxy as ProxyUtils; function directory_init(App $a) { - $a->setPagerItemsPage(60); - if (local_user()) { $a->page['aside'] .= Widget::findPeople(); $a->page['aside'] .= Widget::follow(); @@ -83,16 +82,18 @@ function directory_content(App $a) $publish = (Config::get('system', 'publish_all') ? '' : " AND `publish` = 1 " ); + $total = 0; $cnt = DBA::fetchFirst("SELECT COUNT(*) AS `total` FROM `profile` LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid` WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` $sql_extra"); if (DBA::isResult($cnt)) { - $a->setPagerTotal($cnt['total']); + $total = $cnt['total']; } + $pager = new Pager($a->query_string, $total, 60); $order = " ORDER BY `name` ASC "; - $limit = intval($a->pager['start'])."," . intval($a->pager['itemspage']); + $limit = $pager->getStart()."," . $pager->getItemsPerPage(); $r = DBA::p("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags`, `contact`.`addr`, `contact`.`url` AS profile_url FROM `profile` @@ -212,7 +213,7 @@ function directory_content(App $a) '$findterm' => (strlen($search) ? $search : ""), '$title' => L10n::t('Site Directory'), '$submit' => L10n::t('Find'), - '$paginate' => paginate($a), + '$paginate' => $pager->renderFull(), ]); } else { info(L10n::t("No entries \x28some entries may be hidden\x29.") . EOL); diff --git a/mod/dirfind.php b/mod/dirfind.php index 3e5aa83a72..7cff5f28a3 100644 --- a/mod/dirfind.php +++ b/mod/dirfind.php @@ -5,6 +5,7 @@ use Friendica\App; use Friendica\Content\ContactSelector; +use Friendica\Content\Pager; use Friendica\Content\Widget; use Friendica\Core\Config; use Friendica\Core\L10n; @@ -71,7 +72,7 @@ function dirfind_content(App $a, $prefix = "") { $j = new stdClass(); $j->total = 1; $j->items_page = 1; - $j->page = $a->pager['page']; + $j->page = $pager->getPage(); $objresult = new stdClass(); $objresult->cid = 0; @@ -100,7 +101,7 @@ function dirfind_content(App $a, $prefix = "") { $extra_sql = ""; $perpage = 80; - $startrec = (($a->pager['page']) * $perpage) - $perpage; + $startrec = (($pager->getPage()) * $perpage) - $perpage; if (Config::get('system','diaspora_enabled')) { $diaspora = Protocol::DIASPORA; @@ -141,7 +142,7 @@ function dirfind_content(App $a, $prefix = "") { $j = new stdClass(); $j->total = $count[0]["total"]; $j->items_page = $perpage; - $j->page = $a->pager['page']; + $j->page = $pager->getPage(); foreach ($results AS $result) { if (PortableContact::alternateOStatusUrl($result["nurl"])) { continue; @@ -178,7 +179,7 @@ function dirfind_content(App $a, $prefix = "") { Worker::add(PRIORITY_LOW, 'DiscoverPoCo', "dirsearch", urlencode($search)); } else { - $p = (($a->pager['page'] != 1) ? '&p=' . $a->pager['page'] : ''); + $p = (($pager->getPage() != 1) ? '&p=' . $pager->getPage() : ''); if(strlen(Config::get('system','directory'))) $x = Network::fetchUrl(get_server().'/lsearch?f=' . $p . '&search=' . urlencode($search)); @@ -186,12 +187,8 @@ function dirfind_content(App $a, $prefix = "") { $j = json_decode($x); } - if ($j->total) { - $a->setPagerTotal($j->total); - $a->setPagerItemsPage($j->items_page); - } - if (!empty($j->results)) { + $pager = new Pager($a->query_string, $j->total, $j->items_page); $id = 0; @@ -252,13 +249,13 @@ function dirfind_content(App $a, $prefix = "") { $entries[] = $entry; } - $tpl = get_markup_template('viewcontact_template.tpl'); + $tpl = get_markup_template('viewcontact_template.tpl'); - $o .= replace_macros($tpl,[ - 'title' => $header, - '$contacts' => $entries, - '$paginate' => paginate($a), - ]); + $o .= replace_macros($tpl,[ + 'title' => $header, + '$contacts' => $entries, + '$paginate' => $pager->renderFull(), + ]); } else { info(L10n::t('No matches') . EOL); diff --git a/mod/display.php b/mod/display.php index 38cdfe41d3..e4a17804b3 100644 --- a/mod/display.php +++ b/mod/display.php @@ -4,6 +4,7 @@ */ use Friendica\App; +use Friendica\Content\Pager; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\ACL; @@ -16,9 +17,8 @@ use Friendica\Model\Contact; use Friendica\Model\Group; use Friendica\Model\Item; use Friendica\Model\Profile; -use Friendica\Protocol\DFRN; use Friendica\Protocol\ActivityPub; -use Friendica\Util\Security; +use Friendica\Protocol\DFRN; function display_init(App $a) { @@ -358,7 +358,7 @@ function display_content(App $a, $update = false, $update_uid = 0) $o .= ""; } - $o .= conversation($a, [$item], 'display', $update_uid, false, 'commented', local_user()); + $o .= conversation($a, [$item], new Pager($a->query_string), 'display', $update_uid, false, 'commented', local_user()); // 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 cd64b70f85..dcccf5d75c 100644 --- a/mod/item.php +++ b/mod/item.php @@ -16,6 +16,7 @@ */ use Friendica\App; +use Friendica\Content\Pager; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Addon; @@ -33,6 +34,7 @@ use Friendica\Protocol\Email; use Friendica\Util\DateTimeFormat; use Friendica\Util\Emailer; use Friendica\Util\Security; +use function Friendica\Core\function_exists; require_once 'include/enotify.php'; require_once 'include/text.php'; @@ -667,10 +669,10 @@ function item_post(App $a) { $datarray["item_id"] = -1; $datarray["author-network"] = Protocol::DFRN; - $o = conversation($a,[array_merge($contact_record,$datarray)],'search', false, true); + $o = conversation($a, [array_merge($contact_record, $datarray)], new Pager($a->query_string), 'search', false, true); logger('preview: ' . $o); echo json_encode(['preview' => $o]); - killme(); + exit(); } Addon::callHooks('post_local',$datarray); diff --git a/mod/match.php b/mod/match.php index b299619940..4254e4c45a 100644 --- a/mod/match.php +++ b/mod/match.php @@ -4,6 +4,7 @@ */ use Friendica\App; +use Friendica\Content\Pager; use Friendica\Content\Widget; use Friendica\Core\Config; use Friendica\Core\L10n; @@ -54,8 +55,8 @@ function match_content(App $a) if ($tags) { $params['s'] = $tags; - if ($a->pager['page'] != 1) { - $params['p'] = $a->pager['page']; + if ($pager->getPage() != 1) { + $params['p'] = $pager->getPage(); } if (strlen(Config::get('system', 'directory'))) { @@ -66,12 +67,9 @@ function match_content(App $a) $j = json_decode($x); - if ($j->total) { - $a->setPagerTotal($j->total); - $a->setPagerItemsPage($j->items_page); - } - if (count($j->results)) { + $pager = new Pager($a->query_string, $j->total, $j->items_page); + $id = 0; foreach ($j->results as $jj) { @@ -119,7 +117,7 @@ function match_content(App $a) [ '$title' => L10n::t('Profile Match'), '$contacts' => $entries, - '$paginate' => paginate($a)] + '$paginate' => $pager->renderFull()] ); } else { info(L10n::t('No matches') . EOL); diff --git a/mod/message.php b/mod/message.php index 8a04f9abef..de2ee3cf01 100644 --- a/mod/message.php +++ b/mod/message.php @@ -5,6 +5,7 @@ use Friendica\App; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Content\Smilies; use Friendica\Content\Text\BBCode; use Friendica\Core\ACL; @@ -13,10 +14,10 @@ use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\Model\Contact; use Friendica\Model\Mail; +use Friendica\Module\Login; use Friendica\Util\DateTimeFormat; use Friendica\Util\Proxy as ProxyUtils; use Friendica\Util\Temporal; -use Friendica\Module\Login; require_once 'include/conversation.php'; @@ -273,16 +274,18 @@ function message_content(App $a) $o .= $header; + $total = 0; $r = q("SELECT count(*) AS `total`, ANY_VALUE(`created`) AS `created` FROM `mail` WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `created` DESC", intval(local_user()) ); - if (DBA::isResult($r)) { - $a->setPagerTotal($r[0]['total']); + $total = $r[0]['total']; } - $r = get_messages(local_user(), $a->pager['start'], $a->pager['itemspage']); + $pager = new Pager($a->query_string, $total); + + $r = get_messages(local_user(), $pager->getStart(), $pager->getItemsPerPage()); if (!DBA::isResult($r)) { info(L10n::t('No messages.') . EOL); @@ -291,7 +294,7 @@ function message_content(App $a) $o .= render_messages($r, 'mail_list.tpl'); - $o .= paginate($a); + $o .= $pager->renderFull(); return $o; } diff --git a/mod/network.php b/mod/network.php index b697cb3a63..6f02e8c113 100644 --- a/mod/network.php +++ b/mod/network.php @@ -8,14 +8,15 @@ use Friendica\App; use Friendica\Content\Feature; use Friendica\Content\ForumManager; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Content\Widget; use Friendica\Core\ACL; use Friendica\Core\Addon; use Friendica\Core\Config; +use Friendica\Core\Hook; use Friendica\Core\L10n; use Friendica\Core\PConfig; use Friendica\Core\Protocol; -use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\Model\Contact; use Friendica\Model\Group; @@ -35,6 +36,8 @@ function network_init(App $a) return; } + Hook::add('head', __FILE__, 'network_infinite_scroll_head'); + $search = (x($_GET, 'search') ? escape_tags($_GET['search']) : ''); if (($search != '') && !empty($_GET['submit'])) { @@ -279,7 +282,7 @@ function network_query_get_sel_group(App $a) * @param integer $update Used for the automatic reloading * @return string SQL with the appropriate LIMIT clause */ -function networkPager($a, $update) +function networkPager(App $a, Pager $pager, $update) { if ($update) { // only setup pagination on initial page view @@ -302,9 +305,9 @@ function networkPager($a, $update) $itemspage_network = $a->force_max_items; } - $a->setPagerItemsPage($itemspage_network); + $pager->setItemsPerPage($itemspage_network); - return sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); + return sprintf(" LIMIT %d, %d ", $pager->getStart(), $pager->getItemsPerPage()); } /** @@ -328,24 +331,24 @@ function networkSetSeen($condition) /** * @brief Create the conversation HTML * - * @param App $a The global App - * @param array $items Items of the conversation - * @param string $mode Display mode for the conversation + * @param App $a The global App + * @param array $items Items of the conversation + * @param string $mode Display mode for the conversation * @param integer $update Used for the automatic reloading * @return string HTML of the conversation */ -function networkConversation($a, $items, $mode, $update, $ordering = '') +function networkConversation(App $a, $items, Pager $pager, $mode, $update, $ordering = '') { // Set this so that the conversation function can find out contact info for our wall-wall items $a->page_contact = $a->contact; - $o = conversation($a, $items, $mode, $update, false, $ordering, local_user()); + $o = conversation($a, $items, $pager, $mode, $update, false, $ordering, local_user()); if (!$update) { if (PConfig::get(local_user(), 'system', 'infinite_scroll')) { $o .= scroll_loader(); } else { - $o .= alt_pager($a, count($items)); + $o .= $pager->renderMinimal(count($items)); } } @@ -372,7 +375,7 @@ function network_content(App $a, $update = 0, $parent = 0) } } - if (x($_GET, 'file')) { + if (!empty($_GET['file'])) { $flat_mode = true; } @@ -388,12 +391,14 @@ function network_content(App $a, $update = 0, $parent = 0) /** * @brief Get the network content in flat view * - * @param App $a The global App + * @param Pager $pager + * @param App $a The global App * @param integer $update Used for the automatic reloading * @return string HTML of the network content in flat view */ function networkFlatView(App $a, $update = 0) { + global $pager; // Rawmode is used for fetching new content at the end of the page $rawmode = (isset($_GET['mode']) && ($_GET['mode'] == 'raw')); @@ -405,7 +410,7 @@ function networkFlatView(App $a, $update = 0) $o = ''; - $file = ((x($_GET, 'file')) ? $_GET['file'] : ''); + $file = defaults($_GET, 'file', ''); if (!$update && !$rawmode) { $tabs = network_tabs($a); @@ -437,12 +442,15 @@ function networkFlatView(App $a, $update = 0) } } - $pager_sql = networkPager($a, $update); + $pager = new Pager($a->query_string); + + /// @TODO Figure out why this variable is unused + $pager_sql = networkPager($a, $pager, $update); if (strlen($file)) { $condition = ["`term` = ? AND `otype` = ? AND `type` = ? AND `uid` = ?", $file, TERM_OBJ_POST, TERM_FILE, local_user()]; - $params = ['order' => ['tid' => true], 'limit' => [$a->pager['start'], $a->pager['itemspage']]]; + $params = ['order' => ['tid' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; $result = DBA::select('term', ['oid'], $condition); $posts = []; @@ -456,14 +464,14 @@ function networkFlatView(App $a, $update = 0) $condition = ['uid' => local_user()]; } - $params = ['order' => ['id' => true], 'limit' => [$a->pager['start'], $a->pager['itemspage']]]; + $params = ['order' => ['id' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; $result = Item::selectForUser(local_user(), [], $condition, $params); $items = Item::inArray($result); $condition = ['unseen' => true, 'uid' => local_user()]; networkSetSeen($condition); - $o .= networkConversation($a, $items, 'network-new', $update); + $o .= networkConversation($a, $items, $pager, 'network-new', $update); return $o; } @@ -471,12 +479,17 @@ function networkFlatView(App $a, $update = 0) /** * @brief Get the network content in threaded view * - * @param App $a The global App - * @param integer $update Used for the automatic reloading + * @global Pager $pager + * @param App $a The global App + * @param integer $update Used for the automatic reloading + * @param integer $parent * @return string HTML of the network content in flat view */ function networkThreadedView(App $a, $update, $parent) { + /// @TODO this will have to be converted to a static property of the converted Module\Network class + global $pager; + // Rawmode is used for fetching new content at the end of the page $rawmode = (isset($_GET['mode']) AND ( $_GET['mode'] == 'raw')); @@ -543,13 +556,11 @@ function networkThreadedView(App $a, $update, $parent) $tabs = network_tabs($a); $o .= $tabs; - if ($gid) { - if (($t = Contact::getOStatusCountByGroupId($gid)) && !PConfig::get(local_user(), 'system', 'nowarn_insecure')) { - notice(L10n::tt("Warning: This group contains %s member from a network that doesn't allow non public messages.", - "Warning: This group contains %s members from a network that doesn't allow non public messages.", - $t) . EOL); - notice(L10n::t("Messages in this group won't be send to these receivers.").EOL); - } + if ($gid && ($t = Contact::getOStatusCountByGroupId($gid)) && !PConfig::get(local_user(), 'system', 'nowarn_insecure')) { + notice(L10n::tt("Warning: This group contains %s member from a network that doesn't allow non public messages.", + "Warning: This group contains %s members from a network that doesn't allow non public messages.", + $t) . EOL); + notice(L10n::t("Messages in this group won't be send to these receivers.").EOL); } Nav::setSelected('network'); @@ -706,13 +717,15 @@ function networkThreadedView(App $a, $update, $parent) $sql_order = "$sql_table.$ordering"; - if (x($_GET, 'offset')) { + if (!empty($_GET['offset'])) { $sql_range = sprintf(" AND $sql_order <= '%s'", DBA::escape($_GET['offset'])); } else { $sql_range = ''; } - $pager_sql = networkPager($a, $update); + $pager = new Pager($a->query_string); + + $pager_sql = networkPager($a, $pager, $update); $last_date = ''; @@ -721,31 +734,31 @@ function networkThreadedView(App $a, $update, $parent) if ($last_received != '') { $last_date = $last_received; $sql_range .= sprintf(" AND $sql_table.`received` < '%s'", DBA::escape($last_received)); - $a->setPagerPage(1); - $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); + $pager->setPage(1); + $pager_sql = sprintf(" LIMIT %d, %d ", $pager->getStart(), $pager->getItemsPerPage()); } break; case 'commented': if ($last_commented != '') { $last_date = $last_commented; $sql_range .= sprintf(" AND $sql_table.`commented` < '%s'", DBA::escape($last_commented)); - $a->setPagerPage(1); - $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); + $pager->setPage(1); + $pager_sql = sprintf(" LIMIT %d, %d ", $pager->getStart(), $pager->getItemsPerPage()); } break; case 'created': if ($last_created != '') { $last_date = $last_created; $sql_range .= sprintf(" AND $sql_table.`created` < '%s'", DBA::escape($last_created)); - $a->setPagerPage(1); - $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); + $pager->setPage(1); + $pager_sql = sprintf(" LIMIT %d, %d ", $pager->getStart(), $pager->getItemsPerPage()); } break; case 'id': if (($last_id > 0) && ($sql_table == '`thread`')) { $sql_range .= sprintf(" AND $sql_table.`iid` < '%s'", DBA::escape($last_id)); - $a->setPagerPage(1); - $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); + $pager->setPage(1); + $pager_sql = sprintf(" LIMIT %d, %d ", $pager->getStart(), $pager->getItemsPerPage()); } break; } @@ -835,7 +848,7 @@ function networkThreadedView(App $a, $update, $parent) if ($last_date > $top_limit) { $top_limit = $last_date; - } elseif ($a->pager['page'] == 1) { + } elseif ($pager->getPage() == 1) { // Highest possible top limit when we are on the first page $top_limit = DateTimeFormat::utcNow(); } @@ -898,7 +911,12 @@ function networkThreadedView(App $a, $update, $parent) $date_offset = $_GET['offset']; } - $a->page_offset = $date_offset; + $query_string = $a->query_string; + if ($date_offset && !preg_match('/[?&].offset=/', $query_string)) { + $query_string .= '&offset=' . urlencode($date_offset); + } + + $pager->setQueryString($query_string); // 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 @@ -914,7 +932,7 @@ function networkThreadedView(App $a, $update, $parent) $mode = 'network'; - $o .= networkConversation($a, $items, $mode, $update, $ordering); + $o .= networkConversation($a, $items, $pager, $mode, $update, $ordering); return $o; } @@ -1019,3 +1037,30 @@ function network_tabs(App $a) // --- end item filter tabs } + +/** + * 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. + * + * @global Pager $pager + * @param App $a + * @param string $htmlhead The head tag HTML string + */ +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 + global $pager; + + if (PConfig::get(local_user(), 'system', 'infinite_scroll') + && defaults($_GET, 'mode', '') != 'minimal' + ) { + $tpl = get_markup_template('infinite_scroll_head.tpl'); + $htmlhead .= replace_macros($tpl, [ + '$pageno' => $pager->getPage(), + '$reload_uri' => $pager->getBaseQueryString() + ]); + } +} \ No newline at end of file diff --git a/mod/notes.php b/mod/notes.php index 55a92f8e64..b6b6faefab 100644 --- a/mod/notes.php +++ b/mod/notes.php @@ -5,6 +5,7 @@ use Friendica\App; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Core\L10n; use Friendica\Database\DBA; use Friendica\Model\Item; @@ -60,10 +61,10 @@ function notes_content(App $a, $update = false) $condition = ['uid' => local_user(), 'post-type' => Item::PT_PERSONAL_NOTE, 'gravity' => GRAVITY_PARENT, 'wall' => false, 'contact-id'=> $a->contact['id']]; - $a->setPagerItemsPage(40); + $pager = new Pager($a->query_string, null, 40); $params = ['order' => ['created' => true], - 'limit' => [$a->pager['start'], $a->pager['itemspage']]]; + 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; $r = Item::selectThreadForUser(local_user(), ['uri'], $condition, $params); $count = 0; @@ -73,10 +74,10 @@ function notes_content(App $a, $update = false) $count = count($notes); - $o .= conversation($a, $notes, 'notes', $update); + $o .= conversation($a, $notes, $pager, 'notes', $update); } - $o .= alt_pager($a, $count); + $o .= $pager->renderMinimal($count); return $o; } diff --git a/mod/notifications.php b/mod/notifications.php index d5cfbf276d..748af40d5d 100644 --- a/mod/notifications.php +++ b/mod/notifications.php @@ -7,6 +7,7 @@ use Friendica\App; use Friendica\Content\ContactSelector; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Core\L10n; use Friendica\Core\NotificationsManager; use Friendica\Core\Protocol; @@ -120,11 +121,11 @@ function notifications_content(App $a) } // Set the pager - $a->setPagerItemsPage($perpage); + $pager = new Pager($a->query_string, null, $perpage); // Add additional informations (needed for json output) - $notifs['items_page'] = $a->pager['itemspage']; - $notifs['page'] = $a->pager['page']; + $notifs['items_page'] = $pager->getItemsPerPage(); + $notifs['page'] = $pager->getPage(); // Json output if (intval($json) === 1) { @@ -315,7 +316,7 @@ function notifications_content(App $a) '$notif_content' => $notif_content, '$notif_nocontent' => $notif_nocontent, '$notif_show_lnk' => $notif_show_lnk, - '$notif_paginate' => alt_pager($a, count($notif_content)) + '$notif_paginate' => $pager->renderMinimal(count($notif_content)) ]); return $o; diff --git a/mod/photos.php b/mod/photos.php index ef6428d7ab..b8f00c358a 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -6,6 +6,7 @@ use Friendica\App; use Friendica\Content\Feature; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Content\Text\BBCode; use Friendica\Core\ACL; use Friendica\Core\Addon; @@ -25,8 +26,8 @@ use Friendica\Object\Image; use Friendica\Protocol\DFRN; use Friendica\Util\DateTimeFormat; use Friendica\Util\Map; -use Friendica\Util\Temporal; use Friendica\Util\Security; +use Friendica\Util\Temporal; require_once 'include/items.php'; @@ -1135,16 +1136,18 @@ function photos_content(App $a) if ($datatype === 'album') { $album = hex2bin($datum); + $total = 0; $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` = '%s' AND `scale` <= 4 $sql_extra GROUP BY `resource-id`", intval($owner_uid), DBA::escape($album) ); if (DBA::isResult($r)) { - $a->setPagerTotal(count($r)); - $a->setPagerItemsPage(20); + $total = count($r); } + $pager = new Pager($a->query_string, $total, 20); + /// @TODO I have seen this many times, maybe generalize it script-wide and encapsulate it? $order_field = defaults($_GET, 'order', ''); if ($order_field === 'posted') { @@ -1160,8 +1163,8 @@ function photos_content(App $a) AND `scale` <= 4 $sql_extra GROUP BY `resource-id` ORDER BY `created` $order LIMIT %d , %d", intval($owner_uid), DBA::escape($album), - intval($a->pager['start']), - intval($a->pager['itemspage']) + $pager->getStart(), + $pager->getItemsPerPage() ); // edit album name @@ -1230,7 +1233,7 @@ function photos_content(App $a) '$upload' => [L10n::t('Upload New Photos'), 'photos/' . $a->data['user']['nickname'] . '/upload/' . bin2hex($album)], '$order' => $order, '$edit' => $edit, - '$paginate' => paginate($a), + '$paginate' => $pager->renderFull(), ]); return $o; @@ -1391,9 +1394,9 @@ function photos_content(App $a) $link_item = Item::selectFirst([], ['id' => $linked_items[0]['id']]); $condition = ["`parent` = ? AND `parent` != `id`", $link_item['parent']]; - $a->setPagerTotal(DBA::count('item', $condition)); + $pager = new Pager($a->query_string, DBA::count('item', $condition)); - $params = ['order' => ['id'], 'limit' => [$a->pager['start'], $a->pager['itemspage']]]; + $params = ['order' => ['id'], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; $result = Item::selectForUser($link_item['uid'], Item::ITEM_FIELDLIST, $condition, $params); $items = Item::inArray($result); @@ -1608,7 +1611,7 @@ function photos_content(App $a) } $responses = get_responses($conv_responses, $response_verbs, '', $link_item); - $paginate = paginate($a); + $paginate = $pager->renderFull(); } $photo_tpl = get_markup_template('photo_view.tpl'); @@ -1653,8 +1656,7 @@ function photos_content(App $a) ); if (DBA::isResult($r)) { - $a->setPagerTotal(count($r)); - $a->setPagerItemsPage(20); + $pager = new Pager($a->query_string, count($r), 20); } $r = q("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, @@ -1665,8 +1667,8 @@ function photos_content(App $a) intval($a->data['user']['uid']), DBA::escape('Contact Photos'), DBA::escape(L10n::t('Contact Photos')), - intval($a->pager['start']), - intval($a->pager['itemspage']) + $pager->getStart(), + $pager->getItemsPerPage() ); $photos = []; @@ -1709,7 +1711,7 @@ function photos_content(App $a) '$can_post' => $can_post, '$upload' => [L10n::t('Upload New Photos'), 'photos/'.$a->data['user']['nickname'].'/upload'], '$photos' => $photos, - '$paginate' => paginate($a), + '$paginate' => $pager->renderFull(), ]); return $o; diff --git a/mod/profile.php b/mod/profile.php index 6f0ab9e077..2cea4eedf4 100644 --- a/mod/profile.php +++ b/mod/profile.php @@ -5,6 +5,7 @@ use Friendica\App; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Content\Widget; use Friendica\Core\ACL; use Friendica\Core\Addon; @@ -18,10 +19,10 @@ use Friendica\Model\Group; use Friendica\Model\Item; use Friendica\Model\Profile; use Friendica\Module\Login; +use Friendica\Protocol\ActivityPub; use Friendica\Protocol\DFRN; use Friendica\Util\DateTimeFormat; use Friendica\Util\Security; -use Friendica\Protocol\ActivityPub; function profile_init(App $a) { @@ -307,9 +308,9 @@ function profile_content(App $a, $update = 0) $itemspage_network = $a->force_max_items; } - $a->setPagerItemsPage($itemspage_network); + $pager = new Pager($a->query_string, null, $itemspage_network); - $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); + $pager_sql = sprintf(" LIMIT %d, %d ", $pager->getStart(), $pager->getItemsPerPage()); $items = q("SELECT `item`.`uri` FROM `thread` @@ -344,10 +345,10 @@ function profile_content(App $a, $update = 0) } } - $o .= conversation($a, $items, 'profile', $update, false, 'created', local_user()); + $o .= conversation($a, $items, $pager, 'profile', $update, false, 'created', local_user()); if (!$update) { - $o .= alt_pager($a, count($items)); + $o .= $pager->renderMinimal(count($items)); } return $o; diff --git a/mod/search.php b/mod/search.php index 80b1c184ff..e5ac7588e3 100644 --- a/mod/search.php +++ b/mod/search.php @@ -6,6 +6,7 @@ use Friendica\App; use Friendica\Content\Feature; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Core\Cache; use Friendica\Core\Config; use Friendica\Core\L10n; @@ -200,6 +201,8 @@ function search_content(App $a) { // 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($a->query_string); + if ($tag) { logger("Start tag search for '".$search."'", LOGGER_DEBUG); @@ -207,7 +210,7 @@ function search_content(App $a) { AND `otype` = ? AND `type` = ? AND `term` = ?", local_user(), TERM_OBJ_POST, TERM_HASHTAG, $search]; $params = ['order' => ['created' => true], - 'limit' => [$a->pager['start'], $a->pager['itemspage']]]; + 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; $terms = DBA::select('term', ['oid'], $condition, $params); $itemids = []; @@ -230,7 +233,7 @@ function search_content(App $a) { AND `body` LIKE CONCAT('%',?,'%')", local_user(), $search]; $params = ['order' => ['id' => true], - 'limit' => [$a->pager['start'], $a->pager['itemspage']]]; + 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; $items = Item::selectForUser(local_user(), [], $condition, $params); $r = Item::inArray($items); } @@ -252,9 +255,9 @@ function search_content(App $a) { ]); logger("Start Conversation for '".$search."'", LOGGER_DEBUG); - $o .= conversation($a, $r, 'search', false, false, 'commented', local_user()); + $o .= conversation($a, $r, $pager, 'search', false, false, 'commented', local_user()); - $o .= alt_pager($a,count($r)); + $o .= $pager->renderMinimal(count($r)); logger("Done '".$search."'", LOGGER_DEBUG); diff --git a/mod/videos.php b/mod/videos.php index 521201394b..ee50d26d77 100644 --- a/mod/videos.php +++ b/mod/videos.php @@ -5,6 +5,7 @@ use Friendica\App; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Core\Config; use Friendica\Core\L10n; use Friendica\Core\System; @@ -334,15 +335,15 @@ function videos_content(App $a) // Default - show recent videos (no upload link for now) //$o = ''; + $total = 0; $r = q("SELECT hash FROM `attach` WHERE `uid` = %d AND filetype LIKE '%%video%%' $sql_extra GROUP BY hash", intval($a->data['user']['uid']) ); - if (DBA::isResult($r)) { - $a->setPagerTotal(count($r)); - $a->setPagerItemsPage(20); + $total = count($r); } + $pager = new Pager($a->query_string, $total, 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` @@ -350,8 +351,8 @@ function videos_content(App $a) WHERE `uid` = %d AND filetype LIKE '%%video%%' $sql_extra GROUP BY hash ORDER BY `created` DESC LIMIT %d , %d", intval($a->data['user']['uid']), - intval($a->pager['start']), - intval($a->pager['itemspage']) + $pager->getStart(), + $pager->getItemsPerPage() ); $videos = []; @@ -388,7 +389,7 @@ function videos_content(App $a) '$delete_url' => (($can_post) ? System::baseUrl() . '/videos/' . $a->data['user']['nickname'] : false) ]); - $o .= paginate($a); + $o .= $pager->renderFull(); return $o; } diff --git a/mod/viewcontacts.php b/mod/viewcontacts.php index 563c13c6d4..ea5bcc6527 100644 --- a/mod/viewcontacts.php +++ b/mod/viewcontacts.php @@ -2,17 +2,19 @@ /** * @file mod/viewcontacts.php */ + use Friendica\App; use Friendica\Content\ContactSelector; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Core\Config; use Friendica\Core\L10n; use Friendica\Core\Protocol; +use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\Model\Contact; use Friendica\Model\Profile; use Friendica\Util\Proxy as ProxyUtils; -use Friendica\Core\System; function viewcontacts_init(App $a) { @@ -61,6 +63,7 @@ function viewcontacts_content(App $a) return $o; } + $total = 0; $r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` AND NOT `hidden` AND NOT `archive` @@ -71,8 +74,9 @@ function viewcontacts_content(App $a) DBA::escape(Protocol::OSTATUS) ); if (DBA::isResult($r)) { - $a->setPagerTotal($r[0]['total']); + $total = $r[0]['total']; } + $pager = new Pager($a->query_string, $total); $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` @@ -83,8 +87,8 @@ function viewcontacts_content(App $a) DBA::escape(Protocol::DFRN), DBA::escape(Protocol::DIASPORA), DBA::escape(Protocol::OSTATUS), - intval($a->pager['start']), - intval($a->pager['itemspage']) + $pager->getStart(), + $pager->getItemsPerPage() ); if (!DBA::isResult($r)) { info(L10n::t('No contacts.').EOL); @@ -124,7 +128,7 @@ function viewcontacts_content(App $a) $o .= replace_macros($tpl, [ '$title' => L10n::t('Contacts'), '$contacts' => $contacts, - '$paginate' => paginate($a), + '$paginate' => $pager->renderFull(), ]); return $o; diff --git a/src/App.php b/src/App.php index 9fb63ce679..5fadab1f23 100644 --- a/src/App.php +++ b/src/App.php @@ -34,8 +34,6 @@ class App public $query_string = ''; public $config = []; public $page = []; - public $pager = []; - public $page_offset; public $profile; public $profile_uid; public $user; @@ -303,16 +301,6 @@ class App $this->module = 'home'; } - // See if there is any page number information, and initialise pagination - $this->pager['page'] = !empty($_GET['page']) && intval($_GET['page']) > 0 ? intval($_GET['page']) : 1; - $this->pager['itemspage'] = 50; - $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage']; - - if ($this->pager['start'] < 0) { - $this->pager['start'] = 0; - } - $this->pager['total'] = 0; - // Detect mobile devices $mobile_detect = new MobileDetect(); $this->is_mobile = $mobile_detect->isMobile(); @@ -732,23 +720,6 @@ class App return $this->urlPath; } - public function setPagerTotal($n) - { - $this->pager['total'] = intval($n); - } - - public function setPagerItemsPage($n) - { - $this->pager['itemspage'] = ((intval($n) > 0) ? intval($n) : 0); - $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage']; - } - - public function setPagerPage($n) - { - $this->pager['page'] = $n; - $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage']; - } - /** * Initializes App->page['htmlhead']. * @@ -798,9 +769,6 @@ class App $touch_icon = 'images/friendica-128.png'; } - // get data wich is needed for infinite scroll on the network page - $infinite_scroll = infinite_scroll_data($this->module); - Core\Addon::callHooks('head', $this->page['htmlhead']); $tpl = get_markup_template('head.tpl'); @@ -818,7 +786,6 @@ class App '$update_interval' => $interval, '$shortcut_icon' => $shortcut_icon, '$touch_icon' => $touch_icon, - '$infinite_scroll' => $infinite_scroll, '$block_public' => intval(Core\Config::get('system', 'block_public')), '$stylesheets' => $this->stylesheets, ]) . $this->page['htmlhead']; diff --git a/src/Core/ACL.php b/src/Core/ACL.php index 8f630409ff..bbe24545c7 100644 --- a/src/Core/ACL.php +++ b/src/Core/ACL.php @@ -341,8 +341,7 @@ class ACL extends BaseObject if (Config::get('system', 'poco_local_search')) { $return = GContact::searchByName($search, $mode); } else { - $a = self::getApp(); - $p = $a->pager['page'] != 1 ? '&p=' . $a->pager['page'] : ''; + $p = defaults($_GET, 'page', 1) != 1 ? '&p=' . defaults($_GET, 'page', 1) : ''; $curlResult = Network::curl(get_server() . '/lsearch?f=' . $p . '&search=' . urlencode($search)); if ($curlResult->isSuccess()) { diff --git a/src/Model/Contact.php b/src/Model/Contact.php index fdb49ac133..f653f9ccd5 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -5,6 +5,7 @@ namespace Friendica\Model; use Friendica\BaseObject; +use Friendica\Content\Pager; use Friendica\Core\Addon; use Friendica\Core\Config; use Friendica\Core\L10n; @@ -1345,25 +1346,27 @@ class Contact extends BaseObject $cid, GRAVITY_PARENT, GRAVITY_COMMENT, local_user()]; } + $pager = new Pager($a->query_string); + $params = ['order' => ['created' => true], - 'limit' => [$a->pager['start'], $a->pager['itemspage']]]; + 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; if ($thread_mode) { $r = Item::selectThreadForUser(local_user(), ['uri'], $condition, $params); $items = Item::inArray($r); - $o = conversation($a, $items, 'contacts', $update); + $o = conversation($a, $items, $pager, 'contacts', $update); } else { $r = Item::selectForUser(local_user(), [], $condition, $params); $items = Item::inArray($r); - $o = conversation($a, $items, 'contact-posts', false); + $o = conversation($a, $items, $pager, 'contact-posts', false); } if (!$update) { - $o .= alt_pager($a, count($items)); + $o .= $pager->renderMinimal(count($items)); } return $o; diff --git a/src/Module/Contact.php b/src/Module/Contact.php index fb0bf0edee..b6ead69f0f 100644 --- a/src/Module/Contact.php +++ b/src/Module/Contact.php @@ -6,6 +6,7 @@ use Friendica\App; use Friendica\BaseModule; use Friendica\Content\ContactSelector; use Friendica\Content\Nav; +use Friendica\Content\Pager; use Friendica\Content\Text\BBCode; use Friendica\Content\Widget; use Friendica\Core\ACL; @@ -778,9 +779,9 @@ class Contact extends BaseModule intval($_SESSION['uid']) ); if (DBA::isResult($r)) { - $a->setPagerTotal($r[0]['total']); $total = $r[0]['total']; } + $pager = new Pager($a->query_string, $total); $sql_extra3 = Widget::unavailableNetworks(); @@ -788,8 +789,8 @@ class Contact extends BaseModule $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `pending` = 0 $sql_extra $sql_extra2 $sql_extra3 ORDER BY `name` ASC LIMIT %d , %d ", intval($_SESSION['uid']), - intval($a->pager['start']), - intval($a->pager['itemspage']) + $pager->getStart(), + $pager->getItemsPerPage() ); if (DBA::isResult($r)) { foreach ($r as $rr) { @@ -821,7 +822,7 @@ class Contact extends BaseModule 'contacts_batch_drop' => L10n::t('Delete'), ], '$h_batch_actions' => L10n::t('Batch Actions'), - '$paginate' => paginate($a), + '$paginate' => $pager->renderFull(), ]); return $o; diff --git a/view/js/main.js b/view/js/main.js index b2c469a6d9..384b355230 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -733,7 +733,7 @@ function loadScrollContent() { // get the raw content from the next page and insert this content // right before "#conversation-end" - $.get('network?mode=raw' + infinite_scroll.reload_uri + '&last_received=' + received + '&last_commented=' + commented + '&last_created=' + created + '&last_id=' + id + '&page=' + infinite_scroll.pageno, function(data) { + $.get(infinite_scroll.reload_uri + '&mode=raw&last_received=' + received + '&last_commented=' + commented + '&last_created=' + created + '&last_id=' + id + '&page=' + infinite_scroll.pageno, function(data) { $("#scroll-loader").hide(); if ($(data).length > 0) { $(data).insertBefore('#conversation-end'); diff --git a/view/templates/head.tpl b/view/templates/head.tpl index 6c55f99771..e76b97b8b9 100644 --- a/view/templates/head.tpl +++ b/view/templates/head.tpl @@ -48,15 +48,6 @@ var updateInterval = {{$update_interval}}; var localUser = {{if $local_user}}{{$local_user}}{{else}}false{{/if}}; - {{* Create an object with the data which is needed for infinite scroll. - For the relevant js part look at function loadContent() in main.js. *}} - {{if $infinite_scroll}} - var infinite_scroll = { - "pageno" : {{$infinite_scroll.pageno}}, - "reload_uri" : "{{$infinite_scroll.reload_uri}}" - } - {{/if}} - function confirmDelete() { return confirm("{{$delitem}}"); } function commentExpand(id) { $("#comment-edit-text-" + id).value = ""; diff --git a/view/templates/infinite_scroll_head.tpl b/view/templates/infinite_scroll_head.tpl new file mode 100644 index 0000000000..b46fb1844c --- /dev/null +++ b/view/templates/infinite_scroll_head.tpl @@ -0,0 +1,8 @@ + diff --git a/view/theme/frio/templates/js_strings.tpl b/view/theme/frio/templates/js_strings.tpl index c4173197aa..b649159b9b 100644 --- a/view/theme/frio/templates/js_strings.tpl +++ b/view/theme/frio/templates/js_strings.tpl @@ -1,5 +1,4 @@ - {{* Strings which are needed for some js functions (e.g. translation or the interval for page update) They are loaded into the html so that js functions can use them *}} From 7c0b591043b8c5183b1b697be9de772667f4778b Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 24 Oct 2018 11:42:59 -0400 Subject: [PATCH 4/6] Move itemCount parameter from constructor to renderFull() - Remove Pager->itemCount property and Pager->setItemCount() method - Update usage --- mod/admin.php | 8 ++++---- mod/allfriends.php | 4 ++-- mod/common.php | 30 +++++++++++++++--------------- mod/directory.php | 4 ++-- mod/dirfind.php | 4 ++-- mod/match.php | 14 ++++++-------- mod/message.php | 4 ++-- mod/photos.php | 34 +++++++++++++++++++--------------- mod/videos.php | 5 +++-- mod/viewcontacts.php | 4 ++-- src/Content/Pager.php | 35 +++++++++++------------------------ src/Module/Contact.php | 4 ++-- 12 files changed, 70 insertions(+), 80 deletions(-) diff --git a/mod/admin.php b/mod/admin.php index d90cfb7ab9..5de292916e 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -483,7 +483,7 @@ function admin_page_contactblock(App $a) $total = DBA::count('contact', $condition); - $pager = new Pager($a->query_string, $total, 30); + $pager = new Pager($a->query_string, 30); $statement = DBA::select('contact', [], $condition, ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]]); @@ -513,7 +513,7 @@ function admin_page_contactblock(App $a) '$contacts' => $contacts, '$total_contacts' => L10n::tt('%s total blocked contact', '%s total blocked contacts', $total), - '$paginate' => $pager->renderFull(), + '$paginate' => $pager->renderFull($total), '$contacturl' => ['contact_url', L10n::t("Profile URL"), '', L10n::t("URL of the remote contact to block.")], ]); return $o; @@ -1812,7 +1812,7 @@ function admin_page_users(App $a) /* get pending */ $pending = Register::getPending(); - $pager = new Pager($a->query_string, DBA::count('user'), 100); + $pager = new Pager($a->query_string, 100); /* ordering */ $valid_orders = [ @@ -1951,7 +1951,7 @@ function admin_page_users(App $a) '$newusernickname' => ['new_user_nickname', L10n::t("Nickname"), '', L10n::t("Nickname of the new user.")], '$newuseremail' => ['new_user_email', L10n::t("Email"), '', L10n::t("Email address of the new user."), '', '', 'email'], ]); - $o .= $pager->renderFull(); + $o .= $pager->renderFull(DBA::count('user')); return $o; } diff --git a/mod/allfriends.php b/mod/allfriends.php index d2501e9fe4..83ea73af6b 100644 --- a/mod/allfriends.php +++ b/mod/allfriends.php @@ -46,7 +46,7 @@ function allfriends_content(App $a) $total = Model\GContact::countAllFriends(local_user(), $cid); - $pager = new Pager($a->query_string, $total); + $pager = new Pager($a->query_string); $r = Model\GContact::allFriends(local_user(), $cid, $pager->getStart(), $pager->getItemsPerPage()); if (!DBA::isResult($r)) { @@ -104,7 +104,7 @@ function allfriends_content(App $a) //'$title' => L10n::t('Friends of %s', htmlentities($c[0]['name'])), '$tab_str' => $tab_str, '$contacts' => $entries, - '$paginate' => $pager->renderFull(), + '$paginate' => $pager->renderFull($total), ]); return $o; diff --git a/mod/common.php b/mod/common.php index 993bc58777..8fb19b57cd 100644 --- a/mod/common.php +++ b/mod/common.php @@ -82,44 +82,44 @@ function common_content(App $a) } if ($cid) { - $t = Model\GContact::countCommonFriends($uid, $cid); + $total = Model\GContact::countCommonFriends($uid, $cid); } else { - $t = Model\GContact::countCommonFriendsZcid($uid, $zcid); + $total = Model\GContact::countCommonFriendsZcid($uid, $zcid); } - if ($t > 0) { - $pager = new Pager($a->query_string, $t); - } else { + if ($total < 1) { notice(L10n::t('No contacts in common.') . EOL); return $o; } + $pager = new Pager($a->query_string); + if ($cid) { - $r = Model\GContact::commonFriends($uid, $cid, $pager->getStart(), $pager->getItemsPerPage()); + $common_friends = Model\GContact::commonFriends($uid, $cid, $pager->getStart(), $pager->getItemsPerPage()); } else { - $r = Model\GContact::commonFriendsZcid($uid, $zcid, $pager->getStart(), $pager->getItemsPerPage()); + $common_friends = Model\GContact::commonFriendsZcid($uid, $zcid, $pager->getStart(), $pager->getItemsPerPage()); } - if (!DBA::isResult($r)) { + if (!DBA::isResult($common_friends)) { return $o; } $id = 0; $entries = []; - foreach ($r as $rr) { + foreach ($common_friends as $common_friend) { //get further details of the contact - $contact_details = Model\Contact::getDetailsByURL($rr['url'], $uid); + $contact_details = Model\Contact::getDetailsByURL($common_friend['url'], $uid); // $rr['id'] is needed to use contact_photo_menu() /// @TODO Adding '/" here avoids E_NOTICE on missing constants - $rr['id'] = $rr['cid']; + $common_friend['id'] = $common_friend['cid']; - $photo_menu = Model\Contact::photoMenu($rr); + $photo_menu = Model\Contact::photoMenu($common_friend); $entry = [ - 'url' => $rr['url'], - 'itemurl' => defaults($contact_details, 'addr', $rr['url']), + 'url' => $common_friend['url'], + 'itemurl' => defaults($contact_details, 'addr', $common_friend['url']), 'name' => $contact_details['name'], 'thumb' => ProxyUtils::proxifyUrl($contact_details['thumb'], false, ProxyUtils::SIZE_THUMB), 'img_hover' => htmlentities($contact_details['name']), @@ -148,7 +148,7 @@ function common_content(App $a) '$title' => $title, '$tab_str' => $tab_str, '$contacts' => $entries, - '$paginate' => $pager->renderFull(), + '$paginate' => $pager->renderFull($total), ]); return $o; diff --git a/mod/directory.php b/mod/directory.php index f9104b9a53..6c8be7c3c5 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -89,7 +89,7 @@ function directory_content(App $a) if (DBA::isResult($cnt)) { $total = $cnt['total']; } - $pager = new Pager($a->query_string, $total, 60); + $pager = new Pager($a->query_string, 60); $order = " ORDER BY `name` ASC "; @@ -213,7 +213,7 @@ function directory_content(App $a) '$findterm' => (strlen($search) ? $search : ""), '$title' => L10n::t('Site Directory'), '$submit' => L10n::t('Find'), - '$paginate' => $pager->renderFull(), + '$paginate' => $pager->renderFull($total), ]); } else { info(L10n::t("No entries \x28some entries may be hidden\x29.") . EOL); diff --git a/mod/dirfind.php b/mod/dirfind.php index 7cff5f28a3..9d3c852f49 100644 --- a/mod/dirfind.php +++ b/mod/dirfind.php @@ -188,7 +188,7 @@ function dirfind_content(App $a, $prefix = "") { } if (!empty($j->results)) { - $pager = new Pager($a->query_string, $j->total, $j->items_page); + $pager = new Pager($a->query_string, $j->items_page); $id = 0; @@ -254,7 +254,7 @@ function dirfind_content(App $a, $prefix = "") { $o .= replace_macros($tpl,[ 'title' => $header, '$contacts' => $entries, - '$paginate' => $pager->renderFull(), + '$paginate' => $pager->renderFull($j->total), ]); } else { diff --git a/mod/match.php b/mod/match.php index 4254e4c45a..a514439db6 100644 --- a/mod/match.php +++ b/mod/match.php @@ -54,6 +54,8 @@ function match_content(App $a) $tags = trim($r[0]['pub_keywords'] . ' ' . $r[0]['prv_keywords']); if ($tags) { + $pager = new Pager($a->query_string, $j->items_page); + $params['s'] = $tags; if ($pager->getPage() != 1) { $params['p'] = $pager->getPage(); @@ -68,8 +70,6 @@ function match_content(App $a) $j = json_decode($x); if (count($j->results)) { - $pager = new Pager($a->query_string, $j->total, $j->items_page); - $id = 0; foreach ($j->results as $jj) { @@ -112,13 +112,11 @@ function match_content(App $a) $tpl = get_markup_template('viewcontact_template.tpl'); - $o .= replace_macros( - $tpl, - [ - '$title' => L10n::t('Profile Match'), + $o .= replace_macros($tpl, [ + '$title' => L10n::t('Profile Match'), '$contacts' => $entries, - '$paginate' => $pager->renderFull()] - ); + '$paginate' => $pager->renderFull($j->total) + ]); } else { info(L10n::t('No matches') . EOL); } diff --git a/mod/message.php b/mod/message.php index de2ee3cf01..5f7ffb2b70 100644 --- a/mod/message.php +++ b/mod/message.php @@ -283,7 +283,7 @@ function message_content(App $a) $total = $r[0]['total']; } - $pager = new Pager($a->query_string, $total); + $pager = new Pager($a->query_string); $r = get_messages(local_user(), $pager->getStart(), $pager->getItemsPerPage()); @@ -294,7 +294,7 @@ function message_content(App $a) $o .= render_messages($r, 'mail_list.tpl'); - $o .= $pager->renderFull(); + $o .= $pager->renderFull($total); return $o; } diff --git a/mod/photos.php b/mod/photos.php index b8f00c358a..008d59cd9c 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -1146,7 +1146,7 @@ function photos_content(App $a) $total = count($r); } - $pager = new Pager($a->query_string, $total, 20); + $pager = new Pager($a->query_string, 20); /// @TODO I have seen this many times, maybe generalize it script-wide and encapsulate it? $order_field = defaults($_GET, 'order', ''); @@ -1227,14 +1227,14 @@ function photos_content(App $a) $tpl = get_markup_template('photo_album.tpl'); $o .= replace_macros($tpl, [ - '$photos' => $photos, - '$album' => $album, - '$can_post' => $can_post, - '$upload' => [L10n::t('Upload New Photos'), 'photos/' . $a->data['user']['nickname'] . '/upload/' . bin2hex($album)], - '$order' => $order, - '$edit' => $edit, - '$paginate' => $pager->renderFull(), - ]); + '$photos' => $photos, + '$album' => $album, + '$can_post' => $can_post, + '$upload' => [L10n::t('Upload New Photos'), 'photos/' . $a->data['user']['nickname'] . '/upload/' . bin2hex($album)], + '$order' => $order, + '$edit' => $edit, + '$paginate' => $pager->renderFull($total), + ]); return $o; @@ -1388,13 +1388,16 @@ function photos_content(App $a) $map = null; $link_item = []; + $total = 0; if (DBA::isResult($linked_items)) { // This is a workaround to not being forced to rewrite the while $sql_extra handling $link_item = Item::selectFirst([], ['id' => $linked_items[0]['id']]); $condition = ["`parent` = ? AND `parent` != `id`", $link_item['parent']]; - $pager = new Pager($a->query_string, DBA::count('item', $condition)); + $total = DBA::count('item', $condition); + + $pager = new Pager($a->query_string); $params = ['order' => ['id'], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; $result = Item::selectForUser($link_item['uid'], Item::ITEM_FIELDLIST, $condition, $params); @@ -1611,7 +1614,7 @@ function photos_content(App $a) } $responses = get_responses($conv_responses, $response_verbs, '', $link_item); - $paginate = $pager->renderFull(); + $paginate = $pager->renderFull($total); } $photo_tpl = get_markup_template('photo_view.tpl'); @@ -1647,18 +1650,19 @@ function photos_content(App $a) // Default - show recent photos with upload link (if applicable) //$o = ''; - + $total = 0; $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra GROUP BY `resource-id`", intval($a->data['user']['uid']), DBA::escape('Contact Photos'), DBA::escape(L10n::t('Contact Photos')) ); - if (DBA::isResult($r)) { - $pager = new Pager($a->query_string, count($r), 20); + $total = count($r); } + $pager = new Pager($a->query_string, 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`, ANY_VALUE(`created`) AS `created` FROM `photo` @@ -1711,7 +1715,7 @@ function photos_content(App $a) '$can_post' => $can_post, '$upload' => [L10n::t('Upload New Photos'), 'photos/'.$a->data['user']['nickname'].'/upload'], '$photos' => $photos, - '$paginate' => $pager->renderFull(), + '$paginate' => $pager->renderFull($total), ]); return $o; diff --git a/mod/videos.php b/mod/videos.php index ee50d26d77..51f15a47ae 100644 --- a/mod/videos.php +++ b/mod/videos.php @@ -343,7 +343,8 @@ function videos_content(App $a) if (DBA::isResult($r)) { $total = count($r); } - $pager = new Pager($a->query_string, $total, 20); + + $pager = new Pager($a->query_string, 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` @@ -389,7 +390,7 @@ function videos_content(App $a) '$delete_url' => (($can_post) ? System::baseUrl() . '/videos/' . $a->data['user']['nickname'] : false) ]); - $o .= $pager->renderFull(); + $o .= $pager->renderFull($total); return $o; } diff --git a/mod/viewcontacts.php b/mod/viewcontacts.php index ea5bcc6527..9a2513a6c4 100644 --- a/mod/viewcontacts.php +++ b/mod/viewcontacts.php @@ -76,7 +76,7 @@ function viewcontacts_content(App $a) if (DBA::isResult($r)) { $total = $r[0]['total']; } - $pager = new Pager($a->query_string, $total); + $pager = new Pager($a->query_string); $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` @@ -128,7 +128,7 @@ function viewcontacts_content(App $a) $o .= replace_macros($tpl, [ '$title' => L10n::t('Contacts'), '$contacts' => $contacts, - '$paginate' => $pager->renderFull(), + '$paginate' => $pager->renderFull($total), ]); return $o; diff --git a/src/Content/Pager.php b/src/Content/Pager.php index 185c5506d9..a95fc7cf65 100644 --- a/src/Content/Pager.php +++ b/src/Content/Pager.php @@ -19,10 +19,6 @@ class Pager * @var integer */ private $itemsPerPage = 50; - /** - * @var integer - */ - private $itemCount = 0; /** * @var string @@ -35,14 +31,12 @@ class Pager * Guesses the page number from the GET parameter 'page'. * * @param string $queryString The query string of the current page - * @param integer $itemCount The total item count (for the full mode) or null (for the minimal mode) * @param integer $itemsPerPage An optional number of items per page to override the default value */ - public function __construct($queryString, $itemCount = null, $itemsPerPage = 50) + public function __construct($queryString, $itemsPerPage = 50) { $this->setQueryString($queryString); $this->setItemsPerPage($itemsPerPage); - $this->setItemCount(defaults($itemCount, $this->getItemsPerPage())); $this->setPage(defaults($_GET, 'page', 1)); } @@ -80,7 +74,7 @@ class Pager * Returns the base query string. * * Warning: this isn't the same value as passed to the constructor. - * See setQueryString for the inventory of transformations + * See setQueryString() for the inventory of transformations * * @see setBaseQuery() * @return string @@ -110,16 +104,6 @@ class Pager $this->page = max(1, intval($page)); } - /** - * Sets the item count, 0 minimum. - * - * @param integer $itemCount - */ - public function setItemCount($itemCount) - { - $this->itemCount = max(0, intval($itemCount)); - } - /** * Sets the base query string from a full query string. * @@ -172,7 +156,7 @@ class Pager */ public function renderMinimal($itemCount) { - $this->setItemCount($itemCount); + $displayedItemCount = max(0, intval($itemCount)); $data = [ 'class' => 'pager', @@ -184,7 +168,7 @@ class Pager 'next' => [ 'url' => $this->ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() + 1)), 'text' => L10n::t('older'), - 'class' => 'next' . ($this->itemCount <= 0 ? ' disabled' : '') + 'class' => 'next' . ($displayedItemCount <= 0 ? ' disabled' : '') ] ]; @@ -209,14 +193,17 @@ class Pager * * $html = $pager->renderFull(); * + * @param integer $itemCount The total number of items including those note displayed on the page * @return string HTML string of the pager */ - public function renderFull() + public function renderFull($itemCount) { + $totalItemCount = max(0, intval($itemCount)); + $data = []; $data['class'] = 'pagination'; - if ($this->itemCount > $this->getItemsPerPage()) { + if ($totalItemCount > $this->getItemsPerPage()) { $data['first'] = [ 'url' => $this->ensureQueryParameter($this->baseQueryString . '&page=1'), 'text' => L10n::t('first'), @@ -228,7 +215,7 @@ class Pager 'class' => $this->getPage() == 1 ? 'disabled' : '' ]; - $numpages = $this->itemCount / $this->getItemsPerPage(); + $numpages = $totalItemCount / $this->getItemsPerPage(); $numstart = 1; $numstop = $numpages; @@ -257,7 +244,7 @@ class Pager } } - if (($this->itemCount % $this->getItemsPerPage()) != 0) { + if (($totalItemCount % $this->getItemsPerPage()) != 0) { if ($i == $this->getPage()) { $pages[$i] = [ 'url' => '#', diff --git a/src/Module/Contact.php b/src/Module/Contact.php index b6ead69f0f..817c70e852 100644 --- a/src/Module/Contact.php +++ b/src/Module/Contact.php @@ -781,7 +781,7 @@ class Contact extends BaseModule if (DBA::isResult($r)) { $total = $r[0]['total']; } - $pager = new Pager($a->query_string, $total); + $pager = new Pager($a->query_string); $sql_extra3 = Widget::unavailableNetworks(); @@ -822,7 +822,7 @@ class Contact extends BaseModule 'contacts_batch_drop' => L10n::t('Delete'), ], '$h_batch_actions' => L10n::t('Batch Actions'), - '$paginate' => $pager->renderFull(), + '$paginate' => $pager->renderFull($total), ]); return $o; From 74e80f137bafb1b2f750f600a80f2901f8a29f99 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 24 Oct 2018 11:50:37 -0400 Subject: [PATCH 5/6] Update Pager->__construct calls for minimal use cases --- mod/community.php | 2 +- mod/notes.php | 2 +- mod/notifications.php | 2 +- mod/profile.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mod/community.php b/mod/community.php index 7474fc2429..1017698eaa 100644 --- a/mod/community.php +++ b/mod/community.php @@ -154,7 +154,7 @@ function community_content(App $a, $update = 0) $itemspage_network = $a->force_max_items; } - $pager = new Pager($a->query_string, null, $itemspage_network); + $pager = new Pager($a->query_string, $itemspage_network); $r = community_getitems($pager->getStart(), $pager->getItemsPerPage(), $content, $accounttype); diff --git a/mod/notes.php b/mod/notes.php index b6b6faefab..01e6e5ab99 100644 --- a/mod/notes.php +++ b/mod/notes.php @@ -61,7 +61,7 @@ function notes_content(App $a, $update = false) $condition = ['uid' => local_user(), 'post-type' => Item::PT_PERSONAL_NOTE, 'gravity' => GRAVITY_PARENT, 'wall' => false, 'contact-id'=> $a->contact['id']]; - $pager = new Pager($a->query_string, null, 40); + $pager = new Pager($a->query_string, 40); $params = ['order' => ['created' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]]; diff --git a/mod/notifications.php b/mod/notifications.php index 748af40d5d..81084c1bc3 100644 --- a/mod/notifications.php +++ b/mod/notifications.php @@ -121,7 +121,7 @@ function notifications_content(App $a) } // Set the pager - $pager = new Pager($a->query_string, null, $perpage); + $pager = new Pager($a->query_string, $perpage); // Add additional informations (needed for json output) $notifs['items_page'] = $pager->getItemsPerPage(); diff --git a/mod/profile.php b/mod/profile.php index 2cea4eedf4..d068fca47b 100644 --- a/mod/profile.php +++ b/mod/profile.php @@ -308,7 +308,7 @@ function profile_content(App $a, $update = 0) $itemspage_network = $a->force_max_items; } - $pager = new Pager($a->query_string, null, $itemspage_network); + $pager = new Pager($a->query_string, $itemspage_network); $pager_sql = sprintf(" LIMIT %d, %d ", $pager->getStart(), $pager->getItemsPerPage()); From dde8d8976d2164a7c75b6c659a626d210bfc5dcd Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 24 Oct 2018 12:03:14 -0400 Subject: [PATCH 6/6] Fix usages of Pager with JSON calls in mod/match and mod/dirfind --- mod/dirfind.php | 26 ++++++++++++-------------- mod/match.php | 4 +++- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/mod/dirfind.php b/mod/dirfind.php index 9d3c852f49..5d7815bd80 100644 --- a/mod/dirfind.php +++ b/mod/dirfind.php @@ -67,6 +67,7 @@ function dirfind_content(App $a, $prefix = "") { $o = ''; if ($search) { + $pager = new Pager($a->query_string); if ($discover_user) { $j = new stdClass(); @@ -94,14 +95,13 @@ function dirfind_content(App $a, $prefix = "") { Model\GContact::update($user_data); } } elseif ($local) { - - if ($community) + if ($community) { $extra_sql = " AND `community`"; - else + } else { $extra_sql = ""; + } - $perpage = 80; - $startrec = (($pager->getPage()) * $perpage) - $perpage; + $pager->setItemsPerPage(80); if (Config::get('system','diaspora_enabled')) { $diaspora = Protocol::DIASPORA; @@ -138,10 +138,10 @@ function dirfind_content(App $a, $prefix = "") { DBA::escape(Protocol::DFRN), DBA::escape($ostatus), DBA::escape($diaspora), DBA::escape(escape_tags($search2)), DBA::escape(escape_tags($search2)), DBA::escape(escape_tags($search2)), DBA::escape(escape_tags($search2)), DBA::escape(escape_tags($search2)), DBA::escape(escape_tags($search2)), - intval($startrec), intval($perpage)); + $pager->getStart(), $pager->getItemsPerPage()); $j = new stdClass(); $j->total = $count[0]["total"]; - $j->items_page = $perpage; + $j->items_page = $pager->getItemsPerPage(); $j->page = $pager->getPage(); foreach ($results AS $result) { if (PortableContact::alternateOStatusUrl($result["nurl"])) { @@ -178,18 +178,18 @@ function dirfind_content(App $a, $prefix = "") { // Add found profiles from the global directory to the local directory Worker::add(PRIORITY_LOW, 'DiscoverPoCo', "dirsearch", urlencode($search)); } else { - $p = (($pager->getPage() != 1) ? '&p=' . $pager->getPage() : ''); - if(strlen(Config::get('system','directory'))) - $x = Network::fetchUrl(get_server().'/lsearch?f=' . $p . '&search=' . urlencode($search)); + if (strlen(Config::get('system','directory'))) { + $x = Network::fetchUrl(get_server() . '/lsearch?f=' . $p . '&search=' . urlencode($search)); + } $j = json_decode($x); + + $pager->setItemsPerPage($j->items_page); } if (!empty($j->results)) { - $pager = new Pager($a->query_string, $j->items_page); - $id = 0; foreach ($j->results as $jj) { @@ -250,13 +250,11 @@ function dirfind_content(App $a, $prefix = "") { } $tpl = get_markup_template('viewcontact_template.tpl'); - $o .= replace_macros($tpl,[ 'title' => $header, '$contacts' => $entries, '$paginate' => $pager->renderFull($j->total), ]); - } else { info(L10n::t('No matches') . EOL); } diff --git a/mod/match.php b/mod/match.php index a514439db6..43a3916506 100644 --- a/mod/match.php +++ b/mod/match.php @@ -54,7 +54,7 @@ function match_content(App $a) $tags = trim($r[0]['pub_keywords'] . ' ' . $r[0]['prv_keywords']); if ($tags) { - $pager = new Pager($a->query_string, $j->items_page); + $pager = new Pager($a->query_string); $params['s'] = $tags; if ($pager->getPage() != 1) { @@ -70,6 +70,8 @@ function match_content(App $a) $j = json_decode($x); if (count($j->results)) { + $pager->setItemsPerPage($j->items_page); + $id = 0; foreach ($j->results as $jj) {