set_total ($wpdb->get_var ("SELECT COUNT(*) FROM wp_posts").$pager->to_conditions ()); * $rows = $wpdb->get_results ("SELECT * FROM wp_posts".$pager->to_limits ("post_type=page")); * * Searching is achieved by specifying the columns that can be searched: * * $rows = $wpdb->get_results ("SELECT * FROM wp_posts".$pager->to_limits ("post_type=page", array ('post_content', 'post_excerpt'))); * * Additionally you can output column headings with correct URLs: * sortable ('post_username', 'Username') ?> * * @package default **/ class AT_Pager { var $url = null; var $current_page = 1; var $per_page = 25; var $total = 0; var $order_by = null; var $order_original = null; var $order_direction = null; var $order_tags = array (); var $steps = array (); var $search = null; var $filters = array (); var $id; /** * Construct a pager object using the $_GET data, the current URL, and default preferences * * @param array $data Array of values, typically from $_GET * @param string $url The current URL * @param string $orderby Default database column to order data by * @param string $direction Default direction of ordering (DESC or ASC) * @param string $id An ID for the pager to separate it from other pagers (typically the plugin name) * @return void **/ function AT_Pager ($data, $url, $orderby = '', $direction = 'DESC', $id = 'default', $tags = '') { // Remove all pager params from the url $this->id = $id; $this->url = $url; if (isset ($data['curpage'])) $this->current_page = intval ($data['curpage']); if ($orderby != '') $this->order_by = $orderby; if (isset ($data['orderby'])) $this->order_by = $data['orderby']; if (!empty ($tags)) { $this->order_tags = $tags; if (isset ($this->order_tags[$this->order_by])) $this->order_by = $this->order_tags[$this->order_by]; } $this->order_direction = $direction; $this->order_original = $orderby; if (isset ($data['order'])) $this->order_direction = $data['order']; $this->search = isset($data['search']) ? $data['search'] : ''; $this->steps = array (10, 25, 50, 100, 250); } /** * Set the total number of entries that match the conditions * * @param int $total Count * @return void **/ function set_total ($total) { $this->total = $total; if ($this->current_page <= 0 || $this->current_page > $this->total_pages ()) $this->current_page = 1; } /** * Return the current page offset * * @return int Current page offset **/ function offset () { return ($this->current_page - 1) * $this->per_page; } /** * @todo explain * @return void **/ // XXX function is_secondary_sort () { return substr ($this->order_by, 0, 1) == '_' ? true : false; } /** * Returns a set of conditions without any limits. This is suitable for a COUNT SQL * * @param string $conditions WHERE conditions * @param array $searches Array of columns to search on * @param array $filters Array of columns to filter on * @return string SQL **/ function to_conditions ($conditions, $searches = '', $filters = '') { $sql = ''; if ($conditions != '') $sql .= ' WHERE '.$conditions; // Add on search conditions if (is_array ($searches) && $this->search != '') { if ($sql == '') $sql .= ' WHERE ('; else $sql .= ' AND ('; $searchbits = array (); foreach ($searches AS $search) $searchbits[] = "$search LIKE \"%{$this->search}%\""; $sql .= implode (' OR ', $searchbits); $sql .= ')'; } // Add filters if (is_array ($filters) && !empty ($this->filters)) { $searchbits = array (); foreach ($filters AS $filter) { if (isset ($this->filters[$filter])) { if ($this->filters[$filter] != '') $searchbits[] = sprintf ("%s = '%s'", $filter, $this->filters[$filter]); } } if (count ($searchbits) > 0) { if ($sql == '') $sql .= ' WHERE ('; else $sql .= ' AND ('; $sql .= implode (' AND ', $searchbits); $sql .= ')'; } } return $sql; } /** * Returns a set of conditions with limits. * * @param string $conditions WHERE conditions * @param array $searches Array of columns to search on * @param array $filters Array of columns to filter on * @return string SQL **/ function to_limits ($conditions = '', $searches = '', $filters = '', $group_by = '') { $sql = $this->to_conditions ($conditions, $searches, $filters); if ($group_by) $sql .= ' '.$group_by.' '; if (strlen ($this->order_by) > 0) { if (!$this->is_secondary_sort ()) $sql .= " ORDER BY ".$this->order_by.' '.$this->order_direction; else $sql .= " ORDER BY ".$this->order_original.' '.$this->order_direction; } if ($this->per_page > 0) $sql .= ' LIMIT '.$this->offset ().','.$this->per_page; return $sql; } /** * Return the url with all the params added back * * @param int Page offset * @param string $orderby Optional order * @return string URL **/ function url ($offset, $orderby = '') { // Position if (strpos ($this->url, 'curpage=') !== false) $url = preg_replace ('/curpage=\d*/', 'curpage='.$offset, $this->url); else $url = $this->url.'&curpage='.$offset; // Order if ($orderby != '') { if (strpos ($url, 'orderby=') !== false) $url = preg_replace ('/orderby=\w*/', 'orderby='.$orderby, $url); else $url = $url.'&orderby='.$orderby; if (!empty ($this->order_tags) && isset ($this->order_tags[$orderby])) $dir = $this->order_direction == 'ASC' ? 'DESC' : 'ASC'; else if ($this->order_by == $orderby) $dir = $this->order_direction == 'ASC' ? 'DESC' : 'ASC'; else $dir = $this->order_direction; if (strpos ($url, 'order=') !== false) $url = preg_replace ('/order=\w*/', 'order='.$dir, $url); else $url = $url.'&order='.$dir; } return str_replace ('&go=go', '', $url); } /** * Return current page * * @return int **/ function current_page () { return $this->current_page; } /** * Return total number of pages * * @return int **/ function total_pages () { if ($this->per_page == 0) return 1; return ceil ($this->total / $this->per_page); } /** * Determine if we have a next page * * @return boolean **/ function have_next_page () { if ($this->current_page < $this->total_pages ()) return true; return false; } /** * Determine if we have a previous page * * @return boolean **/ function have_previous_page () { if ($this->current_page > 1) return true; return false; } function sortable_class ($column, $class = true) { if ($column == $this->order_by) { if ($class) printf (' class="sorted"'); else echo ' sorted'; } } /** * Return a string suitable for a sortable column heading * * @param string $column Column to search upon * @param string $text Text to display for the column * @param boolean $image Whether to show a direction image * @return string URL **/ function sortable ($column, $text, $image = true) { $img = ''; $url = $this->url ($this->current_page, $column); if (isset ($this->order_tags[$column])) $column = $this->order_tags[$column]; if ($column == $this->order_by) { if (defined ('WP_PLUGIN_URL')) $dir = WP_PLUGIN_URL.'/'.basename (dirname (dirname (__FILE__))); else $dir = get_bloginfo ('wpurl').'/wp-content/plugins/'.basename (dirname (dirname (__FILE__))); if (strpos ($url, 'ASC') !== false) $img = 'dir'; else $img = 'dir'; if ($image == false) $img = ''; } return ''.$text.''.$img; } /** * Returns an array of page numbers => link, given the current page (next and previous etc) * * @return array Array of page links **/ function area_pages () { // First page $allow_dot = true; $pages = array (); if ($this->total_pages () > 1) { $previous = __ ('Previous', 'redirection'); $next = __ ('Next', 'redirection'); if ($this->have_previous_page ()) $pages[] = ''.$previous.' |'; else $pages[] = $previous.' |'; for ($pos = 1; $pos <= $this->total_pages (); $pos++) { if ($pos == $this->current_page) { $pages[] = ''.$pos.''; $allow_dot = true; } else if ($pos == 1 || abs ($this->current_page - $pos) <= 2 || $pos == $this->total_pages ()) $pages[] = ''.$pos.""; else if ($allow_dot) { $allow_dot = false; $pages[] = '…'; } } if ($this->have_next_page ()) $pages[] = '| '.$next.''; else $pages[] = '| '.$next; } return $pages; } /** * @todo * @return boolean **/ function filtered ($field, $value) { if (isset ($this->filters[$field]) && $this->filters[$field] == $value) return true; return false; } /** * Display a SELECT box suitable for a per-page * * @return void **/ function per_page ($plugin = '') { ?> ' . __( 'Displaying %s–%s of %s' ) . '', number_format_i18n (($this->current_page () - 1) * $this->per_page + 1), number_format_i18n ($this->current_page () * $this->per_page > $this->total ? $this->total : $this->current_page () * $this->per_page), number_format_i18n ($this->total)); $links = paginate_links (array ('base' => str_replace ('99', '%#%', $this->url (99)), 'format' => '%#%', 'current' => $this->current_page (), 'total' => $this->total_pages (), 'end_size' => 3, 'mid_size' => 2, 'prev_next' => true)); return $text.$links; } } ?>