[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-admin/includes/ -> class-wp-list-table.php (source)

   1  <?php
   2  /**
   3   * Base class for displaying a list of items in an ajaxified HTML table.
   4   *
   5   * @package WordPress
   6   * @subpackage List_Table
   7   * @since 3.1.0
   8   */
   9  
  10  /**
  11   * Base class for displaying a list of items in an ajaxified HTML table.
  12   *
  13   * @package WordPress
  14   * @subpackage List_Table
  15   * @since 3.1.0
  16   * @access private
  17   */
  18  class WP_List_Table {
  19  
  20      /**
  21       * The current list of items
  22       *
  23       * @since 3.1.0
  24       * @var array
  25       * @access protected
  26       */
  27      var $items;
  28  
  29      /**
  30       * Various information about the current table
  31       *
  32       * @since 3.1.0
  33       * @var array
  34       * @access private
  35       */
  36      var $_args;
  37  
  38      /**
  39       * Various information needed for displaying the pagination
  40       *
  41       * @since 3.1.0
  42       * @var array
  43       * @access private
  44       */
  45      var $_pagination_args = array();
  46  
  47      /**
  48       * The current screen
  49       *
  50       * @since 3.1.0
  51       * @var object
  52       * @access protected
  53       */
  54      var $screen;
  55  
  56      /**
  57       * Cached bulk actions
  58       *
  59       * @since 3.1.0
  60       * @var array
  61       * @access private
  62       */
  63      var $_actions;
  64  
  65      /**
  66       * Cached pagination output
  67       *
  68       * @since 3.1.0
  69       * @var string
  70       * @access private
  71       */
  72      var $_pagination;
  73  
  74      /**
  75       * Constructor. The child class should call this constructor from its own constructor
  76       *
  77       * @param array $args An associative array with information about the current table
  78       * @access protected
  79       */
  80  	function __construct( $args = array() ) {
  81          $args = wp_parse_args( $args, array(
  82              'plural' => '',
  83              'singular' => '',
  84              'ajax' => false,
  85              'screen' => null,
  86          ) );
  87  
  88          $this->screen = convert_to_screen( $args['screen'] );
  89  
  90          add_filter( "manage_{$this->screen->id}_columns", array( $this, 'get_columns' ), 0 );
  91  
  92          if ( !$args['plural'] )
  93              $args['plural'] = $this->screen->base;
  94  
  95          $args['plural'] = sanitize_key( $args['plural'] );
  96          $args['singular'] = sanitize_key( $args['singular'] );
  97  
  98          $this->_args = $args;
  99  
 100          if ( $args['ajax'] ) {
 101              // wp_enqueue_script( 'list-table' );
 102              add_action( 'admin_footer', array( $this, '_js_vars' ) );
 103          }
 104      }
 105  
 106      /**
 107       * Checks the current user's permissions
 108       * @uses wp_die()
 109       *
 110       * @since 3.1.0
 111       * @access public
 112       * @abstract
 113       */
 114  	function ajax_user_can() {
 115          die( 'function WP_List_Table::ajax_user_can() must be over-ridden in a sub-class.' );
 116      }
 117  
 118      /**
 119       * Prepares the list of items for displaying.
 120       * @uses WP_List_Table::set_pagination_args()
 121       *
 122       * @since 3.1.0
 123       * @access public
 124       * @abstract
 125       */
 126  	function prepare_items() {
 127          die( 'function WP_List_Table::prepare_items() must be over-ridden in a sub-class.' );
 128      }
 129  
 130      /**
 131       * An internal method that sets all the necessary pagination arguments
 132       *
 133       * @param array $args An associative array with information about the pagination
 134       * @access protected
 135       */
 136  	function set_pagination_args( $args ) {
 137          $args = wp_parse_args( $args, array(
 138              'total_items' => 0,
 139              'total_pages' => 0,
 140              'per_page' => 0,
 141          ) );
 142  
 143          if ( !$args['total_pages'] && $args['per_page'] > 0 )
 144              $args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] );
 145  
 146          // redirect if page number is invalid and headers are not already sent
 147          if ( ! headers_sent() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages'] ) {
 148              wp_redirect( add_query_arg( 'paged', $args['total_pages'] ) );
 149              exit;
 150          }
 151  
 152          $this->_pagination_args = $args;
 153      }
 154  
 155      /**
 156       * Access the pagination args
 157       *
 158       * @since 3.1.0
 159       * @access public
 160       *
 161       * @param string $key
 162       * @return array
 163       */
 164  	function get_pagination_arg( $key ) {
 165          if ( 'page' == $key )
 166              return $this->get_pagenum();
 167  
 168          if ( isset( $this->_pagination_args[$key] ) )
 169              return $this->_pagination_args[$key];
 170      }
 171  
 172      /**
 173       * Whether the table has items to display or not
 174       *
 175       * @since 3.1.0
 176       * @access public
 177       *
 178       * @return bool
 179       */
 180  	function has_items() {
 181          return !empty( $this->items );
 182      }
 183  
 184      /**
 185       * Message to be displayed when there are no items
 186       *
 187       * @since 3.1.0
 188       * @access public
 189       */
 190  	function no_items() {
 191          _e( 'No items found.' );
 192      }
 193  
 194      /**
 195       * Display the search box.
 196       *
 197       * @since 3.1.0
 198       * @access public
 199       *
 200       * @param string $text The search button text
 201       * @param string $input_id The search input id
 202       */
 203  	function search_box( $text, $input_id ) {
 204          if ( empty( $_REQUEST['s'] ) && !$this->has_items() )
 205              return;
 206  
 207          $input_id = $input_id . '-search-input';
 208  
 209          if ( ! empty( $_REQUEST['orderby'] ) )
 210              echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
 211          if ( ! empty( $_REQUEST['order'] ) )
 212              echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
 213          if ( ! empty( $_REQUEST['post_mime_type'] ) )
 214              echo '<input type="hidden" name="post_mime_type" value="' . esc_attr( $_REQUEST['post_mime_type'] ) . '" />';
 215          if ( ! empty( $_REQUEST['detached'] ) )
 216              echo '<input type="hidden" name="detached" value="' . esc_attr( $_REQUEST['detached'] ) . '" />';
 217  ?>
 218  <p class="search-box">
 219      <label class="screen-reader-text" for="<?php echo $input_id ?>"><?php echo $text; ?>:</label>
 220      <input type="search" id="<?php echo $input_id ?>" name="s" value="<?php _admin_search_query(); ?>" />
 221      <?php submit_button( $text, 'button', false, false, array('id' => 'search-submit') ); ?>
 222  </p>
 223  <?php
 224      }
 225  
 226      /**
 227       * Get an associative array ( id => link ) with the list
 228       * of views available on this table.
 229       *
 230       * @since 3.1.0
 231       * @access protected
 232       *
 233       * @return array
 234       */
 235  	function get_views() {
 236          return array();
 237      }
 238  
 239      /**
 240       * Display the list of views available on this table.
 241       *
 242       * @since 3.1.0
 243       * @access public
 244       */
 245  	function views() {
 246          $views = $this->get_views();
 247          /**
 248           * Filter the list of available list table views.
 249           *
 250           * The dynamic portion of the hook name, $this->screen->id, refers
 251           * to the ID of the current screen, usually a string.
 252           *
 253           * @since 3.5.0
 254           *
 255           * @param array $views An array of available list table views.
 256           */
 257          $views = apply_filters( "views_{$this->screen->id}", $views );
 258  
 259          if ( empty( $views ) )
 260              return;
 261  
 262          echo "<ul class='subsubsub'>\n";
 263          foreach ( $views as $class => $view ) {
 264              $views[ $class ] = "\t<li class='$class'>$view";
 265          }
 266          echo implode( " |</li>\n", $views ) . "</li>\n";
 267          echo "</ul>";
 268      }
 269  
 270      /**
 271       * Get an associative array ( option_name => option_title ) with the list
 272       * of bulk actions available on this table.
 273       *
 274       * @since 3.1.0
 275       * @access protected
 276       *
 277       * @return array
 278       */
 279  	function get_bulk_actions() {
 280          return array();
 281      }
 282  
 283      /**
 284       * Display the bulk actions dropdown.
 285       *
 286       * @since 3.1.0
 287       * @access public
 288       */
 289  	function bulk_actions() {
 290          if ( is_null( $this->_actions ) ) {
 291              $no_new_actions = $this->_actions = $this->get_bulk_actions();
 292              /**
 293               * Filter the list table Bulk Actions drop-down.
 294               *
 295               * The dynamic portion of the hook name, $this->screen->id, refers
 296               * to the ID of the current screen, usually a string.
 297               *
 298               * This filter can currently only be used to remove bulk actions.
 299               *
 300               * @since 3.5.0
 301               *
 302               * @param array $actions An array of the available bulk actions.
 303               */
 304              $this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions );
 305              $this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions );
 306              $two = '';
 307          } else {
 308              $two = '2';
 309          }
 310  
 311          if ( empty( $this->_actions ) )
 312              return;
 313  
 314          echo "<select name='action$two'>\n";
 315          echo "<option value='-1' selected='selected'>" . __( 'Bulk Actions' ) . "</option>\n";
 316  
 317          foreach ( $this->_actions as $name => $title ) {
 318              $class = 'edit' == $name ? ' class="hide-if-no-js"' : '';
 319  
 320              echo "\t<option value='$name'$class>$title</option>\n";
 321          }
 322  
 323          echo "</select>\n";
 324  
 325          submit_button( __( 'Apply' ), 'action', false, false, array( 'id' => "doaction$two" ) );
 326          echo "\n";
 327      }
 328  
 329      /**
 330       * Get the current action selected from the bulk actions dropdown.
 331       *
 332       * @since 3.1.0
 333       * @access public
 334       *
 335       * @return string|bool The action name or False if no action was selected
 336       */
 337  	function current_action() {
 338          if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] )
 339              return $_REQUEST['action'];
 340  
 341          if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] )
 342              return $_REQUEST['action2'];
 343  
 344          return false;
 345      }
 346  
 347      /**
 348       * Generate row actions div
 349       *
 350       * @since 3.1.0
 351       * @access protected
 352       *
 353       * @param array $actions The list of actions
 354       * @param bool $always_visible Whether the actions should be always visible
 355       * @return string
 356       */
 357  	function row_actions( $actions, $always_visible = false ) {
 358          $action_count = count( $actions );
 359          $i = 0;
 360  
 361          if ( !$action_count )
 362              return '';
 363  
 364          $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
 365          foreach ( $actions as $action => $link ) {
 366              ++$i;
 367              ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
 368              $out .= "<span class='$action'>$link$sep</span>";
 369          }
 370          $out .= '</div>';
 371  
 372          return $out;
 373      }
 374  
 375      /**
 376       * Display a monthly dropdown for filtering items
 377       *
 378       * @since 3.1.0
 379       * @access protected
 380       */
 381  	function months_dropdown( $post_type ) {
 382          global $wpdb, $wp_locale;
 383  
 384          $months = $wpdb->get_results( $wpdb->prepare( "
 385              SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
 386              FROM $wpdb->posts
 387              WHERE post_type = %s
 388              ORDER BY post_date DESC
 389          ", $post_type ) );
 390  
 391          /**
 392           * Filter the 'Months' drop-down results.
 393           *
 394           * @since 3.7.0
 395           *
 396           * @param object $months    The months drop-down query results.
 397           * @param string $post_type The post type.
 398           */
 399          $months = apply_filters( 'months_dropdown_results', $months, $post_type );
 400  
 401          $month_count = count( $months );
 402  
 403          if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) )
 404              return;
 405  
 406          $m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0;
 407  ?>
 408          <select name='m'>
 409              <option<?php selected( $m, 0 ); ?> value='0'><?php _e( 'Show all dates' ); ?></option>
 410  <?php
 411          foreach ( $months as $arc_row ) {
 412              if ( 0 == $arc_row->year )
 413                  continue;
 414  
 415              $month = zeroise( $arc_row->month, 2 );
 416              $year = $arc_row->year;
 417  
 418              printf( "<option %s value='%s'>%s</option>\n",
 419                  selected( $m, $year . $month, false ),
 420                  esc_attr( $arc_row->year . $month ),
 421                  /* translators: 1: month name, 2: 4-digit year */
 422                  sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month ), $year )
 423              );
 424          }
 425  ?>
 426          </select>
 427  <?php
 428      }
 429  
 430      /**
 431       * Display a view switcher
 432       *
 433       * @since 3.1.0
 434       * @access protected
 435       */
 436  	function view_switcher( $current_mode ) {
 437          $modes = array(
 438              'list'    => __( 'List View' ),
 439              'excerpt' => __( 'Excerpt View' )
 440          );
 441  
 442  ?>
 443          <input type="hidden" name="mode" value="<?php echo esc_attr( $current_mode ); ?>" />
 444          <div class="view-switch">
 445  <?php
 446              foreach ( $modes as $mode => $title ) {
 447                  $class = ( $current_mode == $mode ) ? 'class="current"' : '';
 448                  echo "<a href='" . esc_url( add_query_arg( 'mode', $mode, $_SERVER['REQUEST_URI'] ) ) . "' $class><img id='view-switch-$mode' src='" . esc_url( includes_url( 'images/blank.gif' ) ) . "' width='20' height='20' title='$title' alt='$title' /></a>\n";
 449              }
 450          ?>
 451          </div>
 452  <?php
 453      }
 454  
 455      /**
 456       * Display a comment count bubble
 457       *
 458       * @since 3.1.0
 459       * @access protected
 460       *
 461       * @param int $post_id
 462       * @param int $pending_comments
 463       */
 464  	function comments_bubble( $post_id, $pending_comments ) {
 465          $pending_phrase = sprintf( __( '%s pending' ), number_format( $pending_comments ) );
 466  
 467          if ( $pending_comments )
 468              echo '<strong>';
 469  
 470          echo "<a href='" . esc_url( add_query_arg( 'p', $post_id, admin_url( 'edit-comments.php' ) ) ) . "' title='" . esc_attr( $pending_phrase ) . "' class='post-com-count'><span class='comment-count'>" . number_format_i18n( get_comments_number() ) . "</span></a>";
 471  
 472          if ( $pending_comments )
 473              echo '</strong>';
 474      }
 475  
 476      /**
 477       * Get the current page number
 478       *
 479       * @since 3.1.0
 480       * @access protected
 481       *
 482       * @return int
 483       */
 484  	function get_pagenum() {
 485          $pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0;
 486  
 487          if( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] )
 488              $pagenum = $this->_pagination_args['total_pages'];
 489  
 490          return max( 1, $pagenum );
 491      }
 492  
 493      /**
 494       * Get number of items to display on a single page
 495       *
 496       * @since 3.1.0
 497       * @access protected
 498       *
 499       * @return int
 500       */
 501  	function get_items_per_page( $option, $default = 20 ) {
 502          $per_page = (int) get_user_option( $option );
 503          if ( empty( $per_page ) || $per_page < 1 )
 504              $per_page = $default;
 505  
 506          /**
 507           * Filter the number of items to be displayed on each page of the list table.
 508           *
 509           * The dynamic hook name, $option, refers to the per page option depending
 510           * on the type of list table in use. Possible values may include:
 511           * 'edit_comments_per_page', 'sites_network_per_page', 'site_themes_network_per_page',
 512           * 'themes_netework_per_page', 'users_network_per_page', 'edit_{$post_type}', etc.
 513           *
 514           * @since 2.9.0
 515           *
 516           * @param int $per_page Number of items to be displayed. Default 20.
 517           */
 518          return (int) apply_filters( $option, $per_page );
 519      }
 520  
 521      /**
 522       * Display the pagination.
 523       *
 524       * @since 3.1.0
 525       * @access protected
 526       */
 527  	function pagination( $which ) {
 528          if ( empty( $this->_pagination_args ) )
 529              return;
 530  
 531          extract( $this->_pagination_args, EXTR_SKIP );
 532  
 533          $output = '<span class="displaying-num">' . sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . '</span>';
 534  
 535          $current = $this->get_pagenum();
 536  
 537          $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
 538  
 539          $current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url );
 540  
 541          $page_links = array();
 542  
 543          $disable_first = $disable_last = '';
 544          if ( $current == 1 )
 545              $disable_first = ' disabled';
 546          if ( $current == $total_pages )
 547              $disable_last = ' disabled';
 548  
 549          $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
 550              'first-page' . $disable_first,
 551              esc_attr__( 'Go to the first page' ),
 552              esc_url( remove_query_arg( 'paged', $current_url ) ),
 553              '&laquo;'
 554          );
 555  
 556          $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
 557              'prev-page' . $disable_first,
 558              esc_attr__( 'Go to the previous page' ),
 559              esc_url( add_query_arg( 'paged', max( 1, $current-1 ), $current_url ) ),
 560              '&lsaquo;'
 561          );
 562  
 563          if ( 'bottom' == $which )
 564              $html_current_page = $current;
 565          else
 566              $html_current_page = sprintf( "<input class='current-page' title='%s' type='text' name='paged' value='%s' size='%d' />",
 567                  esc_attr__( 'Current page' ),
 568                  $current,
 569                  strlen( $total_pages )
 570              );
 571  
 572          $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
 573          $page_links[] = '<span class="paging-input">' . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . '</span>';
 574  
 575          $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
 576              'next-page' . $disable_last,
 577              esc_attr__( 'Go to the next page' ),
 578              esc_url( add_query_arg( 'paged', min( $total_pages, $current+1 ), $current_url ) ),
 579              '&rsaquo;'
 580          );
 581  
 582          $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
 583              'last-page' . $disable_last,
 584              esc_attr__( 'Go to the last page' ),
 585              esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
 586              '&raquo;'
 587          );
 588  
 589          $pagination_links_class = 'pagination-links';
 590          if ( ! empty( $infinite_scroll ) )
 591              $pagination_links_class = ' hide-if-js';
 592          $output .= "\n<span class='$pagination_links_class'>" . join( "\n", $page_links ) . '</span>';
 593  
 594          if ( $total_pages )
 595              $page_class = $total_pages < 2 ? ' one-page' : '';
 596          else
 597              $page_class = ' no-pages';
 598  
 599          $this->_pagination = "<div class='tablenav-pages{$page_class}'>$output</div>";
 600  
 601          echo $this->_pagination;
 602      }
 603  
 604      /**
 605       * Get a list of columns. The format is:
 606       * 'internal-name' => 'Title'
 607       *
 608       * @since 3.1.0
 609       * @access protected
 610       * @abstract
 611       *
 612       * @return array
 613       */
 614  	function get_columns() {
 615          die( 'function WP_List_Table::get_columns() must be over-ridden in a sub-class.' );
 616      }
 617  
 618      /**
 619       * Get a list of sortable columns. The format is:
 620       * 'internal-name' => 'orderby'
 621       * or
 622       * 'internal-name' => array( 'orderby', true )
 623       *
 624       * The second format will make the initial sorting order be descending
 625       *
 626       * @since 3.1.0
 627       * @access protected
 628       *
 629       * @return array
 630       */
 631  	function get_sortable_columns() {
 632          return array();
 633      }
 634  
 635      /**
 636       * Get a list of all, hidden and sortable columns, with filter applied
 637       *
 638       * @since 3.1.0
 639       * @access protected
 640       *
 641       * @return array
 642       */
 643  	function get_column_info() {
 644          if ( isset( $this->_column_headers ) )
 645              return $this->_column_headers;
 646  
 647          $columns = get_column_headers( $this->screen );
 648          $hidden = get_hidden_columns( $this->screen );
 649  
 650          $sortable_columns = $this->get_sortable_columns();
 651          /**
 652           * Filter the list table sortable columns for a specific screen.
 653           *
 654           * The dynamic portion of the hook name, $this->screen->id, refers
 655           * to the ID of the current screen, usually a string.
 656           *
 657           * @since 3.5.0
 658           *
 659           * @param array $sortable_columns An array of sortable columns.
 660           */
 661          $_sortable = apply_filters( "manage_{$this->screen->id}_sortable_columns", $sortable_columns );
 662  
 663          $sortable = array();
 664          foreach ( $_sortable as $id => $data ) {
 665              if ( empty( $data ) )
 666                  continue;
 667  
 668              $data = (array) $data;
 669              if ( !isset( $data[1] ) )
 670                  $data[1] = false;
 671  
 672              $sortable[$id] = $data;
 673          }
 674  
 675          $this->_column_headers = array( $columns, $hidden, $sortable );
 676  
 677          return $this->_column_headers;
 678      }
 679  
 680      /**
 681       * Return number of visible columns
 682       *
 683       * @since 3.1.0
 684       * @access public
 685       *
 686       * @return int
 687       */
 688  	function get_column_count() {
 689          list ( $columns, $hidden ) = $this->get_column_info();
 690          $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) );
 691          return count( $columns ) - count( $hidden );
 692      }
 693  
 694      /**
 695       * Print column headers, accounting for hidden and sortable columns.
 696       *
 697       * @since 3.1.0
 698       * @access protected
 699       *
 700       * @param bool $with_id Whether to set the id attribute or not
 701       */
 702  	function print_column_headers( $with_id = true ) {
 703          list( $columns, $hidden, $sortable ) = $this->get_column_info();
 704  
 705          $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
 706          $current_url = remove_query_arg( 'paged', $current_url );
 707  
 708          if ( isset( $_GET['orderby'] ) )
 709              $current_orderby = $_GET['orderby'];
 710          else
 711              $current_orderby = '';
 712  
 713          if ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] )
 714              $current_order = 'desc';
 715          else
 716              $current_order = 'asc';
 717  
 718          if ( ! empty( $columns['cb'] ) ) {
 719              static $cb_counter = 1;
 720              $columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All' ) . '</label>'
 721                  . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
 722              $cb_counter++;
 723          }
 724  
 725          foreach ( $columns as $column_key => $column_display_name ) {
 726              $class = array( 'manage-column', "column-$column_key" );
 727  
 728              $style = '';
 729              if ( in_array( $column_key, $hidden ) )
 730                  $style = 'display:none;';
 731  
 732              $style = ' style="' . $style . '"';
 733  
 734              if ( 'cb' == $column_key )
 735                  $class[] = 'check-column';
 736              elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) )
 737                  $class[] = 'num';
 738  
 739              if ( isset( $sortable[$column_key] ) ) {
 740                  list( $orderby, $desc_first ) = $sortable[$column_key];
 741  
 742                  if ( $current_orderby == $orderby ) {
 743                      $order = 'asc' == $current_order ? 'desc' : 'asc';
 744                      $class[] = 'sorted';
 745                      $class[] = $current_order;
 746                  } else {
 747                      $order = $desc_first ? 'desc' : 'asc';
 748                      $class[] = 'sortable';
 749                      $class[] = $desc_first ? 'asc' : 'desc';
 750                  }
 751  
 752                  $column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
 753              }
 754  
 755              $id = $with_id ? "id='$column_key'" : '';
 756  
 757              if ( !empty( $class ) )
 758                  $class = "class='" . join( ' ', $class ) . "'";
 759  
 760              echo "<th scope='col' $id $class $style>$column_display_name</th>";
 761          }
 762      }
 763  
 764      /**
 765       * Display the table
 766       *
 767       * @since 3.1.0
 768       * @access public
 769       */
 770  	function display() {
 771          extract( $this->_args );
 772  
 773          $this->display_tablenav( 'top' );
 774  
 775  ?>
 776  <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0">
 777      <thead>
 778      <tr>
 779          <?php $this->print_column_headers(); ?>
 780      </tr>
 781      </thead>
 782  
 783      <tfoot>
 784      <tr>
 785          <?php $this->print_column_headers( false ); ?>
 786      </tr>
 787      </tfoot>
 788  
 789      <tbody id="the-list"<?php if ( $singular ) echo " data-wp-lists='list:$singular'"; ?>>
 790          <?php $this->display_rows_or_placeholder(); ?>
 791      </tbody>
 792  </table>
 793  <?php
 794          $this->display_tablenav( 'bottom' );
 795      }
 796  
 797      /**
 798       * Get a list of CSS classes for the <table> tag
 799       *
 800       * @since 3.1.0
 801       * @access protected
 802       *
 803       * @return array
 804       */
 805  	function get_table_classes() {
 806          return array( 'widefat', 'fixed', $this->_args['plural'] );
 807      }
 808  
 809      /**
 810       * Generate the table navigation above or below the table
 811       *
 812       * @since 3.1.0
 813       * @access protected
 814       */
 815  	function display_tablenav( $which ) {
 816          if ( 'top' == $which )
 817              wp_nonce_field( 'bulk-' . $this->_args['plural'] );
 818  ?>
 819      <div class="tablenav <?php echo esc_attr( $which ); ?>">
 820  
 821          <div class="alignleft actions bulkactions">
 822              <?php $this->bulk_actions(); ?>
 823          </div>
 824  <?php
 825          $this->extra_tablenav( $which );
 826          $this->pagination( $which );
 827  ?>
 828  
 829          <br class="clear" />
 830      </div>
 831  <?php
 832      }
 833  
 834      /**
 835       * Extra controls to be displayed between bulk actions and pagination
 836       *
 837       * @since 3.1.0
 838       * @access protected
 839       */
 840  	function extra_tablenav( $which ) {}
 841  
 842      /**
 843       * Generate the <tbody> part of the table
 844       *
 845       * @since 3.1.0
 846       * @access protected
 847       */
 848  	function display_rows_or_placeholder() {
 849          if ( $this->has_items() ) {
 850              $this->display_rows();
 851          } else {
 852              list( $columns, $hidden ) = $this->get_column_info();
 853              echo '<tr class="no-items"><td class="colspanchange" colspan="' . $this->get_column_count() . '">';
 854              $this->no_items();
 855              echo '</td></tr>';
 856          }
 857      }
 858  
 859      /**
 860       * Generate the table rows
 861       *
 862       * @since 3.1.0
 863       * @access protected
 864       */
 865  	function display_rows() {
 866          foreach ( $this->items as $item )
 867              $this->single_row( $item );
 868      }
 869  
 870      /**
 871       * Generates content for a single row of the table
 872       *
 873       * @since 3.1.0
 874       * @access protected
 875       *
 876       * @param object $item The current item
 877       */
 878  	function single_row( $item ) {
 879          static $row_class = '';
 880          $row_class = ( $row_class == '' ? ' class="alternate"' : '' );
 881  
 882          echo '<tr' . $row_class . '>';
 883          $this->single_row_columns( $item );
 884          echo '</tr>';
 885      }
 886  
 887      /**
 888       * Generates the columns for a single row of the table
 889       *
 890       * @since 3.1.0
 891       * @access protected
 892       *
 893       * @param object $item The current item
 894       */
 895  	function single_row_columns( $item ) {
 896          list( $columns, $hidden ) = $this->get_column_info();
 897  
 898          foreach ( $columns as $column_name => $column_display_name ) {
 899              $class = "class='$column_name column-$column_name'";
 900  
 901              $style = '';
 902              if ( in_array( $column_name, $hidden ) )
 903                  $style = ' style="display:none;"';
 904  
 905              $attributes = "$class$style";
 906  
 907              if ( 'cb' == $column_name ) {
 908                  echo '<th scope="row" class="check-column">';
 909                  echo $this->column_cb( $item );
 910                  echo '</th>';
 911              }
 912              elseif ( method_exists( $this, 'column_' . $column_name ) ) {
 913                  echo "<td $attributes>";
 914                  echo call_user_func( array( $this, 'column_' . $column_name ), $item );
 915                  echo "</td>";
 916              }
 917              else {
 918                  echo "<td $attributes>";
 919                  echo $this->column_default( $item, $column_name );
 920                  echo "</td>";
 921              }
 922          }
 923      }
 924  
 925      /**
 926       * Handle an incoming ajax request (called from admin-ajax.php)
 927       *
 928       * @since 3.1.0
 929       * @access public
 930       */
 931  	function ajax_response() {
 932          $this->prepare_items();
 933  
 934          extract( $this->_args );
 935          extract( $this->_pagination_args, EXTR_SKIP );
 936  
 937          ob_start();
 938          if ( ! empty( $_REQUEST['no_placeholder'] ) )
 939              $this->display_rows();
 940          else
 941              $this->display_rows_or_placeholder();
 942  
 943          $rows = ob_get_clean();
 944  
 945          $response = array( 'rows' => $rows );
 946  
 947          if ( isset( $total_items ) )
 948              $response['total_items_i18n'] = sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) );
 949  
 950          if ( isset( $total_pages ) ) {
 951              $response['total_pages'] = $total_pages;
 952              $response['total_pages_i18n'] = number_format_i18n( $total_pages );
 953          }
 954  
 955          die( json_encode( $response ) );
 956      }
 957  
 958      /**
 959       * Send required variables to JavaScript land
 960       *
 961       * @access private
 962       */
 963  	function _js_vars() {
 964          $args = array(
 965              'class'  => get_class( $this ),
 966              'screen' => array(
 967                  'id'   => $this->screen->id,
 968                  'base' => $this->screen->base,
 969              )
 970          );
 971  
 972          printf( "<script type='text/javascript'>list_args = %s;</script>\n", json_encode( $args ) );
 973      }
 974  }


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu