__construct( $cols ); } /** * PHP 5 constructor * * @package Boone's Sortable Columns * @since 1.0 * * $columns should be an array of arrays. That is, an array of args for each column. See * $defaults below for an explanation of these arrays. */ function __construct( $cols = false ) { $defaults = array( 'name' => false, 'title' => false, 'is_sortable' => true, 'css_class' => false, 'default_order' => 'asc', 'posts_column' => false, 'is_default' => false ); $this->columns = array(); $this->sortable_keys = array(); foreach( $cols as $col ) { // You need at least a name and a title to continue if ( empty( $col['name'] ) || empty( $col['title'] ) ) continue; $r = wp_parse_args( $col, $defaults ); // If the css_class is not set, just use the name param if ( empty( $r['css_class'] ) ) $r['css_class'] = $r['name']; // Check to see whether this is a default. Providing more than one default // will mean that the last one overrides the others if ( !empty( $r['is_default'] ) ) $this->default_orderby = $r['name']; // Compare the default order against a whitelist of 'asc' and 'desc' if ( 'asc' == strtolower( $r['default_order'] ) || 'desc' == strtolower( $r['default_order'] ) ) { $r['default_order'] = strtolower( $r['default_order'] ); } else { $r['default_order'] = 'asc'; } // If it's sortable, add the name to the $sortable_keys array if ( $r['is_sortable'] ) $this->sortable_keys[] = $r['name']; // Convert to an object for maximum prettiness $col_obj = new stdClass; foreach( $r as $key => $value ) { $col_obj->$key = $value; } $this->columns[] = $col_obj; } // Now, set up some values for the loop $this->column_count = count( $this->columns ); $this->current_column = -1; // If a default orderby was not found, just choose the first item in the array if ( empty( $this->default_orderby ) && !empty( $cols[0]['name'] ) ) { $this->default_orderby = $cols[0]['name']; } // Set up the $_GET keys (which are customizable) $this->setup_get_keys(); // Get the pagination parameters out of $_GET $this->setup_get_params(); // Set up the next orders (asc or desc) depending on current state $this->setup_next_orders(); } /** * Sets up the $_GET param keys. * * You can either override this function in your own extended class, or filter the default * values. I have provided both options because I love you so very much. * * @package Boone's Sortable Columns * @since 1.0 */ function setup_get_keys() { $this->get_orderby_key = apply_filters( 'bbg_cpt_sort_orderby_key', 'orderby' ); $this->get_order_key = apply_filters( 'bbg_cpt_sort_order_key', 'order' ); } /** * Gets params out of $_GET global * * Does some basic checks to ensure that the values are integers and that they are non-empty * * @package Boone's Sortable Columns * @since 1.0 */ function setup_get_params() { // Orderby $orderby = isset( $_GET[$this->get_orderby_key] ) ? $_GET[$this->get_orderby_key] : false; // If an orderby param is provided, check to see that it's permitted. // Otherwise set the current orderby to the default if ( $orderby && in_array( $orderby, $this->sortable_keys ) ) { $this->get_orderby = $orderby; } else { $this->get_orderby = $this->default_orderby; } // Order $order = isset( $_GET[$this->get_order_key] ) ? $_GET[$this->get_order_key] : false; // If an order is provided, make sure it's either 'desc' or 'asc' // Otherwise set current order to the orderby's default order if ( $order && ( 'desc' == strtolower( $order ) || 'asc' == strtolower( $order ) ) ) { $order = strtolower( $order ); } else { // Loop through to find the default order for this bad boy // This is not optimized because of the way the array is keyed foreach( $this->columns as $col ) { if ( $col->name == $this->get_orderby ) { $order = $col->default_order; break; } } } // There should only be two options, 'asc' and 'desc'. We'll cut some slack for // uppercase variants $order = 'desc' == strtolower( $order ) ? 'desc' : 'asc'; $this->get_order = $order; } function setup_next_orders() { foreach( $this->columns as $name => $col ) { if ( $col->name == $this->get_orderby ) { $current_order = $this->get_order; } else { $current_order = $col->default_order; } $this->columns[$name]->next_order = 'asc' == $current_order ? 'desc' : 'asc'; } } function have_columns() { // Compare against the column_count - 1 to account for the 0 array index shift if ( $this->column_count && $this->current_column < $this->column_count - 1 ) return true; return false; } function next_column() { $this->current_column++; $this->column = $this->columns[$this->current_column]; return $this->column; } function rewind_columns() { $this->current_column = -1; if ( $this->column_count > 0 ) { $this->column = $this->columns[0]; } } function the_column() { $this->in_the_loop = true; $this->column = $this->next_column(); if ( 0 == $this->current_column ) // loop has just started do_action('loop_start'); } function the_column_css_class( $type = 'echo' ) { // The column-identifying class $class = array( $this->column->css_class ); // Sortable logic if ( $this->column->is_sortable ) { // Add the sorted/sortable class, based on whether this is the current sort if ( $this->column->name == $this->get_orderby ) { $class[] = 'sorted'; $class[] = $this->get_order; } else { $class[] = 'sortable'; $class[] = $this->column->next_order; } } $class = implode( ' ', $class ); if ( 'echo' == $type ) echo $class; else return $class; } function the_column_next_link( $type = 'echo', $html_or_url = 'html' ) { $args = array( $this->get_orderby_key => $this->column->name, $this->get_order_key => $this->column->next_order ); $url = add_query_arg( $args ); // Assemble the html link, if necessary if ( 'html' == $html_or_url ) { $html = sprintf( '%3$s', $this->column->name, $url, $this->the_column_title( 'return' ) ); $link = $html; } else { $link = $url; } if ( 'echo' == $type ) echo $link; else return $link; } function the_column_title( $type = 'echo' ) { $name = $this->column->title; if ( 'echo' == $type ) echo $name; else return $name; } function the_column_th( $type = 'echo' ) { if ( $this->column->is_sortable ) { $td_content = sprintf( '%2$s', $this->the_column_next_link( 'return', 'url' ), $this->the_column_title( 'return' ) ); } else { $td_content = $this->the_column_title( 'return' ); } $html = sprintf( '%2$s', $this->the_column_css_class( 'return' ), $td_content ); if ( 'echo' == $type ) echo $html; else return $html; } } endif; ?>