From 99d84c933003d6ecc5a7fe2d81f87cb0e1de9017 Mon Sep 17 00:00:00 2001 From: Dries Buytaert Date: Sat, 14 Dec 2002 11:55:54 +0000 Subject: - Committed Marco's pager improvements. - Fixed another annoyance with editing content. --- includes/common.inc | 72 ++++++++++++++++++++------ includes/pager.inc | 145 +++++++++++++++++++++------------------------------- 2 files changed, 114 insertions(+), 103 deletions(-) (limited to 'includes') diff --git a/includes/common.inc b/includes/common.inc index 9fd254497..cd01940b1 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -369,19 +369,11 @@ function check_form($text) { return htmlspecialchars(stripslashes($text)); } -function check_export($text) { - return htmlspecialchars(stripslashes($text)); -} - -function check_code($text) { - return $text; -} - -function check_preview($text) { - return check_output(check_input($text)); +function check_query($text) { + return addslashes(stripslashes($text)); } -function check_query($text) { +function check_input($text) { return addslashes(stripslashes($text)); } @@ -395,12 +387,19 @@ function filter($text) { return $text; } -function check_input($text) { - return check_query($text); -} - function check_output($text, $nl2br = 0) { - return ($text) ? ($nl2br ? str_replace("\r", "", str_replace("\n", "
", stripslashes($text))) : stripslashes($text)) : message_na(); + if ($text) { + $text = stripslashes($text); + + if (strip_tags($text, "") == $text) { + $text = nl2br($text); + } + } + else { + $text = message_na(); + } + + return $text; } function check_file($filename) { @@ -640,6 +639,34 @@ function form_weight($title = NULL, $name = "weight", $value = 0, $delta = 10, $ return form_select($title, $name, $value, $weights, $description, $extra); } +/** + * Parse an URL; this function must be follow the changes of a clean url implementation + * + * @param string $url optional, url to parse; default to request_uri() + * @return array $result associative array: + * script => index/node/module/admin + * query => GET variables + * + */ +function drupal_parse_url($url = NULL) { + global $PHP_SELF; + static $cache; + + if ($url == NULL) { + $url = $PHP_SELF ."?". getenv("QUERY_STRING"); + } + + if (!$cache[$url]) { + $parts = parse_url($url); + preg_match("/(\w+?)\.php/", $parts["path"], $found); + $cache[$url]["script"] = $found[1]; + parse_str($parts["query"], $cache[$url]["query"]); + $cache[$url]["anchor"] = $parts["fragment"]; + } + + return $cache[$url]; +} + /** * Build an URL; use this functions when you must write an URL * for example in a form or a redirect. @@ -649,9 +676,20 @@ function form_weight($title = NULL, $name = "weight", $value = 0, $delta = 10, $ * @param $anchor optional, anchor name */ function drupal_url($args = array(), $script = "node", $anchor = 0) { + static $search, $replace; + + if (!$search) { + /* + According to RFC 1738 [3] the special characters "$-_.+!*'()," and the + reserved characters "/:@#?&=" can be used unencoded within an URL + */ + $search = array("%24", "%2B", "%21", "%2A", "%27", "%28", "%29", "%2C", "%2F", "%3A", "%40", "%23", "%3F", "%26", "%3D"); + $replace = array("$", "+", "!", "*", "'", "(", ")", ",", "/", ":", "@", "#", "?", "&", "="); + } + $t = array(); foreach ($args as $key => $value) { - $t[] = "$key=". urlencode($value); + $t[] = "$key=". str_replace($search, $replace, urlencode($value)); } if (count($t)) { return "$script.php?". implode("&", $t) . ($anchor ? "#$anchor" : ""); diff --git a/includes/pager.inc b/includes/pager.inc index a7cb48784..8f93a5a54 100644 --- a/includes/pager.inc +++ b/includes/pager.inc @@ -5,7 +5,7 @@ function pager_help() { ?>

Implementation note: making queries pagable

The pager uses LIMIT-based queries to fetch only the records required to render a certain page. However, it has to learn the total number of records returned by the query to (among others) compute the number of pages (= number of all records / number of records per page). This is done by inserting COUNT(*) in the original query, ie. by rewriting the original query

SELECT nid, type FROM node WHERE status = '1' ORDER BY static DESC, created DESC
to read
SELECT COUNT(*) FROM node WHERE status = '1' ORDER BY static DESC, created DESC
Rewriting the query is accomplished using a regular expression; preg_replace("/SELECT.*FROM/i", "SELECT COUNT(*) FROM", $query).

-

Unfortunately, the call to preg_replace() does not work as intended for queries that already have a COUNT() clause; the original COUNT() will be removed from the query, possibly making the remainder of the query fail (eg. when the use of HAVING or ORDER depends on the value returned by COUNT()). In practice, for queries to be db_query_pager()-able, they shold be reformulated not to use COUNT().

+

Unfortunately, the call to preg_replace() does not work as intended for queries that already have a COUNT() clause; the original COUNT() will be removed from the query, possibly making the remainder of the query fail (eg. when the use of HAVING or ORDER depends on the value returned by COUNT()). In practice, for queries to be pager_query()-able, they shold be reformulated not to use COUNT().

"; - $output .= ""; - $output .= ""; - $output .= ""; - $output .= ""; - $output .= ""; + $output .= ""; + $output .= ""; + $output .= ""; + $output .= ""; + $output .= ""; $output .= "
". pager_first(($tags[0] ? $tags[0] : t("first page")), $limit, $element) ."". pager_previous(($tags[1] ? $tags[1] : t("previous page")), $limit, $element) ."". pager_list($limit, $element, ($tags[2] ? $tags[2] : 9 )) ."". pager_next(($tags[3] ? $tags[3] : t("next page")), $limit, $element) ."". pager_last(($tags[4] ? $tags[4] : t("last page")), $limit, $element) ."". pager_first(($tags[0] ? $tags[0] : t("first page")), $limit, $element, $attributes) ."". pager_previous(($tags[1] ? $tags[1] : t("previous page")), $limit, $element, 1, $attributes) ."". pager_list($limit, $element, ($tags[2] ? $tags[2] : 9 ), "", $attributes) ."". pager_next(($tags[3] ? $tags[3] : t("next page")), $limit, $element, 1, $attributes) ."". pager_last(($tags[4] ? $tags[4] : t("last page")), $limit, $element, $attributes) ."
"; return "$output"; @@ -56,13 +56,13 @@ function pager_display_default($tags = "", $limit = 10, $element = 0) { * * @see pager_display */ -function pager_display_simple($tags = "", $limit = 10, $element = 0) { +function pager_display_simple($tags = "", $limit = 10, $element = 0, $attributes = array()) { /* ** It's left as an exercise to theme writers to create an alternative ** pager for pager_display_simple(). if your theme does not offer a ** replacement, the theme.inc pager_display_default() is used. */ - return pager_display_default($tags, $limit, $element); + return pager_display_default($tags, $limit, $element, $attributes); } /** @@ -73,13 +73,13 @@ function pager_display_simple($tags = "", $limit = 10, $element = 0) { * * @see pager_display */ -function pager_display_admin($tags = "", $limit = 10, $element = 0) { +function pager_display_admin($tags = "", $limit = 10, $element = 0, $attributes = array()) { /* ** It's left as an exercise to theme writers to create an alternative ** pager for pager_display_admin(). if your theme does not offer a ** replacement, the pager.inc pager_display_default() is used. */ - return pager_display_default($tags, $limit, $element); + return pager_display_default($tags, $limit, $element, $attributes); } /* ******************************************************************* @@ -94,11 +94,11 @@ function pager_display_admin($tags = "", $limit = 10, $element = 0) { * * @see pager_previous */ -function pager_first($text, $limit, $element = 0) { - global $from_array; +function pager_first($text, $limit, $element = 0, $attributes = array()) { + global $pager_from_array; - if ($from_array[$element]) { - return "
$text"; + if ($pager_from_array[$element]) { + return "$text"; } else { // we are already at the first page, return nothing @@ -116,13 +116,13 @@ function pager_first($text, $limit, $element = 0) { * * @return string html of this pager piece */ -function pager_previous($text, $limit, $element = 0, $n = 1) { - global $from_array; - $from_new = pager_load_array(((int)$from_array[$element] - ((int)$limit * (int)$n)), $element, $from_array); +function pager_previous($text, $limit, $element = 0, $n = 1, $attributes = array()) { + global $pager_from_array; + $from_new = pager_load_array(((int)$pager_from_array[$element] - ((int)$limit * (int)$n)), $element, $pager_from_array); if ($from_new[$element] < 1) { - return pager_first($text, $limit, $element); + return pager_first($text, $limit, $element, $attributes); } - return "$text"; + return "$text"; } /** @@ -130,11 +130,11 @@ function pager_previous($text, $limit, $element = 0, $n = 1) { * * @see pager_previous */ -function pager_next($text, $limit, $element = 0, $n = 1) { - global $from_array, $pager_total; - $from_new = pager_load_array(((int)$from_array[$element] + ((int)$limit * (int)$n)), $element, $from_array); +function pager_next($text, $limit, $element = 0, $n = 1, $attributes = array()) { + global $pager_from_array, $pager_total; + $from_new = pager_load_array(((int)$pager_from_array[$element] + ((int)$limit * (int)$n)), $element, $pager_from_array); if ($from_new[$element] < $pager_total[$element]) { - return "$text"; + return "$text"; } return " "; } @@ -144,15 +144,15 @@ function pager_next($text, $limit, $element = 0, $n = 1) { * * @see pager_previous */ -function pager_last($text, $limit, $element = 0) { - global $from_array, $pager_total; +function pager_last($text, $limit, $element = 0, $attributes = array()) { + global $pager_from_array, $pager_total; - $from_new = pager_load_array(($pager_total[$element] - $limit), $element, $from_array); - if ($from_new[$element] < ($from_array[$element] + $limit)) { - return pager_next($text, $limit, $element); + $from_new = pager_load_array(($pager_total[$element] - $limit), $element, $pager_from_array); + if ($from_new[$element] < ($pager_from_array[$element] + $limit)) { + return pager_next($text, $limit, $element, 1, $attributes); } - if (($from_new[$element] > $from_array[$element]) && ($from_new[$element] > 0) && $from_new[$element] < $pager_total[$element]) { - return "$text"; + if (($from_new[$element] > $pager_from_array[$element]) && ($from_new[$element] > 0) && $from_new[$element] < $pager_total[$element]) { + return "$text"; } return " "; } @@ -164,10 +164,10 @@ function pager_last($text, $limit, $element = 0) { * @see pager_previous */ function pager_detail($limit, $element = 0, $format = "%d through %d of %d.") { - global $from_array, $pager_total; + global $pager_from_array, $pager_total; - if ($pager_total[$element] > (int)$from_array[$element] + 1) { - $output = sprintf($format, (int)$from_array[$element] + 1, ((int)$from_array[$element] + $limit <= $pager_total[$element] ? (int)$from_array[$element] + $limit : $pager_total[$element]), $pager_total[$element]); + if ($pager_total[$element] > (int)$pager_from_array[$element] + 1) { + $output = sprintf($format, (int)$pager_from_array[$element] + 1, ((int)$pager_from_array[$element] + $limit <= $pager_total[$element] ? (int)$pager_from_array[$element] + $limit : $pager_total[$element]), $pager_total[$element]); } return $output; @@ -180,16 +180,16 @@ function pager_detail($limit, $element = 0, $format = "%d through %d of %d.") { * @param string $text optional text to display before the page list * @see pager_previous */ -function pager_list($limit, $element = 0, $quantity = 5, $text = "") { - global $from_array, $pager_total; +function pager_list($limit, $element = 0, $quantity = 5, $text = "", $attributes = array()) { + global $pager_from_array, $pager_total; // calculate various markers within this pager piece: // middle used to "center" pages around current page $pager_middle = ceil((int)$quantity / 2); // offset adds "offset" second page - $pager_offset = (int)$from_array[$element] % (int)$limit; + $pager_offset = (int)$pager_from_array[$element] % (int)$limit; // current is the page we are currently paged to - if (($pager_current = (ceil(($from_array[$element] + 1) / $limit))) < 1) { + if (($pager_current = (ceil(($pager_from_array[$element] + 1) / $limit))) < 1) { $pager_current = 1; } // first is the first page listed by this pager piece (re quantity) @@ -231,13 +231,13 @@ function pager_list($limit, $element = 0, $quantity = 5, $text = "") { // finally we're ready to generate the actual pager piece for (; $i <= $pager_last && $i <= $pager_max; $i++) { if ($i < $pager_current) { - $output .= pager_previous($i, $limit, $element, ($pager_current - $i)) ." "; + $output .= pager_previous($i, $limit, $element, ($pager_current - $i), $attributes) ." "; } if ($i == $pager_current) { $output .= "$i "; } if ($i > $pager_current) { - $output .= pager_next($i, $limit, $element, ($i - $pager_current)) ." "; + $output .= pager_next($i, $limit, $element, ($i - $pager_current), $attributes) ." "; } } @@ -259,9 +259,6 @@ function pager_list($limit, $element = 0, $quantity = 5, $text = "") { * Use this function when doing select queries you wish to be able to page. * * TODO: - * - remove database dependency ($db_type) piece - * . use db_query_range from - * . rename db_query_pager() to pager_query() * - examine a better solution for the "no COUNT in $query" requirement (see (output of) {@link pager_help()}) * * @param string $query the database query *without* "LIMIT" in it. examples:
@@ -272,57 +269,33 @@ function pager_list($limit, $element = 0, $quantity = 5, $text = "") {
  *
  * @return  resource  MySQL query result
  */
-function db_query_pager($query, $limit = 10, $element = 0) {
-  global $from, $from_array, $db_type, $pager_total;
+function pager_query($query, $limit = 10, $element = 0) {
+  global $from, $pager_from_array, $db_type, $pager_total;
 
   // count the total number of records in this query:
-  $array = db_fetch_array(db_query(preg_replace("/SELECT.*FROM/i", "SELECT COUNT(*) FROM", $query)));
-  if ($array) {
-    $pager_total[$element] = array_pop($array);
-  }
-  else {
-    $pager_total[$element] = 0;
-  }
+  $pager_total[$element] = db_result(db_query(preg_replace("/SELECT.*FROM/i", "SELECT COUNT(*) FROM", $query)));
 
   // convert comma separated $from to an array, used by other functions:
-  $from_array = explode(",", $from);
+  $pager_from_array = explode(",", $from);
 
-  if ((int)$from_array[$element]) {
-    if ($db_type == "mysql") {
-      // MySQL formatted limit query with offset:
-      $limit_query = $query . " LIMIT " . (int)$from_array[$element] . ", $limit";
-    }
-    else {
-      // pear formatted limit query with offset:
-      $limit_query = $query . " LIMIT $limit OFFSET " . (int)$from_array[$element];
-    }
-  }
-  else {
-    // standard limit query without offset:
-    $limit_query = $query . " LIMIT $limit";
-  }
-  return db_query($limit_query);
+  return db_query_range($query, (int)$pager_from_array[$element], (int)$limit);
 }
 
-function pager_link($from_new) {
-  $from_list = @implode(",", $from_new);
-  if ("$from_list" == "0") {
-    // single pager at zero, so remove the $from
-    return preg_replace(array("/from=*[^&]*/", "/[&]$/", "/[?]$/"), "", request_uri());
-  }
-  if (preg_match("/from=/", request_uri())) {
-    // replace existing from=
-    return preg_replace("/from=*[^&]*/", "from=$from_list", request_uri());
-  }
-  if (preg_match("/[?]/", request_uri())) {
-    // append &from=
-    $href = request_uri() . "&from=$from_list";
+function pager_link($from_new, $attributes = array()) {
+  $url = drupal_parse_url();
+
+  if (count($from_new) == 0 || (count($from_new) == 1 && $from_new[0] == 0)) {
+    unset($url["query"]["from"]);
   }
   else {
-    // append ?from=
-    $href = request_uri() . "?from=$from_list";
+    $url["query"]["from"] = implode(",", $from_new);
   }
-  return $href;
+
+  if (count($attributes)) {
+    $url["query"] = array_merge($url["query"], $attributes);
+  }
+
+  return drupal_url($url["query"], $url["script"]);
 }
 
 function pager_load_array($value, $element, $old_array) {
-- 
cgit v1.2.3