PNG %k25u25%fgd5n!
<?php
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) exit;
/**
* Class that outputs an HTML table.
*
* Important note!
* This class is marked as private, which means that we do NOT recommended using it.
* This class is subject to change without warning in any future SliceWP release.
* If you would still like to make use of the class, you should make a copy to use and distribute with your own project, or else use it at your own risk.
*
* @access private
*
*/
class SliceWP_List_Table {
/**
* A string identifying the table.
*
* @access protected
* @var string
*
*/
protected $id = '';
/**
* The base URL where the table is outputted.
*
* @access protected
* @var string
*
*/
protected $screen_base_url = '';
/**
* The items to be shown in the table.
*
* @access protected
* @var array
*
*/
protected $items = array();
/**
* All items in the collection, not just items shown.
*
* @access protected
* @var int
*
*/
protected $items_total = 0;
/**
* How many items to show per page.
*
* @access protected
* @var int
*
*/
protected $items_per_page = 0;
/**
* The table's columns.
*
* @access protected
* @var array
*
*/
protected $table_columns = array();
/**
* The current page being displayed.
*
* @access protected
* @var int
*
*/
protected $current_page = 0;
/**
* The message to show when no items are in the table.
*
* @access protected
* @var string
*
*/
protected $no_items = '';
/**
* Array of filters that should be shown before the table.
*
* @access protected
* @var array
*
*/
protected $table_filters = array();
/**
* Boolean that specifies if the table should show the items details panels.
*
* @access protected
* @var bool
*
*/
protected $should_show_items_details = false;
/**
* Array of extra arguments.
*
* @access protected
* @var array
*
*/
protected $args = array();
/**
* Constructor.
*
*/
public function __construct( $args = array() ) {
$args = ( is_object( $args ) ? get_object_vars( $args ) : $args );
foreach ( $args as $key => $value ) {
if ( ! property_exists( $this, $key ) ) {
continue;
}
$this->$key = $value;
}
// Set the screen URL.
$this->screen_base_url = ( ! empty( $this->screen_base_url ) ? $this->screen_base_url : strtok( set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ), '?' ) );
// Set items per page.
$user_preferences = slicewp_get_user_preferences();
$this->items_per_page = ( empty( $this->items_per_page ) ? ( ! empty( $user_preferences['list_table_items_per_page'] ) ? absint( $user_preferences['list_table_items_per_page'] ) : 10 ) : $this->items_per_page );
// Set the current page number.
$page_number_arg_slug = ( ! empty( $this->id ) ? 'page_number_' . $this->id : 'page_number' );
$this->current_page = ( empty( $this->current_page ) ? ( ! empty( $_GET[$page_number_arg_slug] ) ? absint( $_GET[$page_number_arg_slug] ) : 1 ) : $this->current_page );
// Set if we should show the items details.
$this->should_show_items_details = $this->should_show_items_details();
}
/**
* Getter.
*
* @param string $property
*
*/
public function get( $property ) {
if ( method_exists( $this, 'get_' . $property ) ) {
return $this->{'get_' . $property}();
} else {
return ( property_exists( $this, $property ) ? $this->$property : null );
}
}
/**
* Setter.
*
* @param string $property
* @param string $value
*
*/
public function set( $property, $value ) {
if ( method_exists( $this, 'set_' . $property ) ) {
$this->{'set_' . $property}( $value );
} else {
$this->$property = $value;
}
}
/**
* Returns the object attributes and their values as an array.
*
*/
public function to_array() {
return get_object_vars( $this );
}
/**
* Outputs HTML table and all related elements.
*
*/
public function output() {
$this->output_table();
}
/**
* Returns the table columns after passing the value through filters for extendability.
*
* @param array
*
*/
protected function get_filtered_table_columns() {
$table_columns = $this->table_columns;
/**
* Filter the table columns generally.
*
* @param array $table_columns
*
*/
$table_columns = apply_filters( 'slicewp_list_table_columns', $table_columns );
if ( ! empty( $this->id ) ) {
/**
* Filter the table columns targetted by table unique ID.
*
* @param array $table_columns
*
*/
$table_columns = apply_filters( 'slicewp_list_table_columns_' . $this->id, $table_columns );
}
return $table_columns;
}
/**
* Outputs the HTML of the table.
*
*/
public function output_table() {
$this->output_table_before();
echo '<table class="slicewp-list-table">';
$this->output_table_header();
$this->output_table_body();
echo '</table>';
$this->output_table_after();
}
/**
* Outputs the table header.
*
*/
public function output_table_header() {
$table_columns = $this->get_filtered_table_columns();
if ( empty( $table_columns ) ) {
return;
}
echo '<thead>';
echo '<tr>';
foreach ( $table_columns as $column_slug => $column_name ) {
echo '<th class="slicewp-column-' . esc_attr( $column_slug ) . '">' . $column_name . '</th>';
}
echo '</tr>';
echo '</thead>';
}
/**
* Outputs the table body.
*
*/
public function output_table_body() {
if ( ! $this->should_show_items_details ) {
echo '<tbody>';
}
if ( ! empty( $this->items ) ) {
$items = $this->prepare_items_for_output( $this->items );
foreach ( $items as $key => $item ) {
/**
* Filters the $item array generally, right before outputting it.
*
* @param array $item
*
*/
$item = apply_filters( 'slicewp_list_table_row_item', $item );
if ( ! empty( $this->id ) ) {
/**
* Filters the $item array targetted by table unique ID, right before outputting it.
*
* @param array $item
*
*/
$item = apply_filters( 'slicewp_list_table_row_item_' . $this->id, $item );
}
$this->output_table_row( $item );
}
} else {
echo '<tr>';
echo '<td colspan="' . count( $this->get_filtered_table_columns() ) . '">';
$this->output_no_items();
echo '</td>';
echo '</tr>';
}
if ( ! $this->should_show_items_details ) {
echo '</tbody>';
}
}
/**
* Outputs the table row for the given item data.
*
* @param array $item
*
*/
public function output_table_row( $item ) {
if ( $this->should_show_items_details ) {
echo '<tbody>';
}
// Get table details.
ob_start();
$this->output_table_row_item_details( $item );
$table_row_item_details = ob_get_clean();
if ( ! empty( $table_row_item_details ) ) {
$item['item_details'] = true;
}
// Output table row.
echo '<tr>';
foreach ( $this->get_filtered_table_columns() as $column_slug => $column_name ) {
$this->output_table_row_column( $column_slug, $item );
}
echo '</tr>';
// Output table row item details.
if ( ! empty( $table_row_item_details ) ) {
echo '<tr class="slicewp-list-table-item-details-row">';
echo '<td colspan="' . count( $this->get_filtered_table_columns() ) . '">';
echo '<div>';
echo '<div>';
echo $table_row_item_details;
echo '</div>';
echo '</div>';
echo '</td>';
echo '</tr>';
}
if ( $this->should_show_items_details ) {
echo '</tbody>';
}
}
/**
* Outputs the table row item details for the given item data.
*
* @param array $item
*
*/
public function output_table_row_item_details( $item ) {
if ( ! empty( $this->id ) ) {
/**
* Action to add extra item details to this table.
*
* @param array $item
*
*/
do_action( 'slicewp_list_table_output_item_details_' . $this->id, $item );
}
}
/**
* Outputs the given row column.
*
* @param string $column_slug
* @param array $item
*
*/
public function output_table_row_column( $column_slug, $item ) {
echo '<td class="slicewp-column-' . esc_attr( $column_slug ) . '">';
if ( method_exists( $this, 'column_' . $column_slug ) ) {
echo $this->{'column_' . $column_slug}( $item );
} else {
echo $this->column_default( $column_slug, $item );
}
echo '</td>';
}
/**
* Returns the default output for the given row column.
*
* @param string $column_slug
* @param array $item
*
* @return string
*
*/
public function column_default( $column_slug, $item ) {
return ( ! empty( $item[$column_slug] ) ? $item[$column_slug] : '' );
}
/**
* Column "actions".
*
* @param array $item
*
* @return string
*
*/
public function column_actions( $item ) {
return ( ! empty( $item['item_details'] ) ? '<a href="#" class="slicewp-toggle-item-details">' . __( 'Details', 'slicewp' ) . slicewp_get_svg( 'outline-chevron-down' ) . '</a>' : '' );
}
/**
* Outputs the message shown when no items exist.
*
*/
public function output_no_items() {
echo ( ! empty( $this->no_items ) ? $this->no_items : __( 'No results found.', 'slicewp' ) );
}
/**
* Outputs elements before the table.
*
*/
public function output_table_before() {
echo '<div class="slicewp-list-table-before">';
if ( ! empty( $this->table_filters ) ) {
$this->output_table_filters();
}
echo '</div>';
}
/**
* Outputs elements after the table.
*
*/
public function output_table_after() {
echo '<div class="slicewp-list-table-after">';
if ( $this->items_total > 10 ) {
$this->output_per_page_selector();
}
$this->output_table_pagination();
echo '</div>';
}
/**
* Outputs the table filters.
*
*/
public function output_table_filters() {
echo '<div class="slicewp-list-table-filters">';
echo '<form method="GET">';
$parsed_url = parse_url( $this->screen_base_url );
parse_str( $parsed_url['query'], $query_vars );
foreach ( $query_vars as $key => $value ) {
echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $value ) . '" />';
}
foreach ( $this->table_filters as $filter_slug ) {
if ( method_exists( $this, 'output_table_filter_' . $filter_slug ) ) {
$this->{'output_table_filter_' . $filter_slug}();
}
}
echo '<button class="slicewp-button-primary" type="submit">' . __( 'Apply', 'slicewp' ) . '</button>';
echo '</form>';
echo '</div>';
}
/**
* Outputs the table date range picker.
*
*/
public function output_table_filter_date_range_picker() {
echo slicewp_element_date_range_picker();
}
/**
* Outputs the per page selector.
*
*/
public function output_per_page_selector() {
$per_page_options = slicewp_get_list_table_items_per_page_options();
echo '<div class="slicewp-list-table-per-page-selector">';
echo '<form method="POST" action="">';
echo '<select name="list_table_items_per_page">';
foreach ( $per_page_options as $option ) {
echo '<option value="' . absint( $option ) . '" ' . ( $this->items_per_page == $option ? 'selected="selected"' : '' ) . '>' . esc_html( $option ) . '</option>';
}
echo '</select>';
echo '<span>' . __( 'results per page', 'slicewp' ) . '</span>';
echo '<input type="hidden" name="slicewp_action" value="update_user_preferences_list_table_items_per_page" />';
wp_nonce_field( 'slicewp_update_user_preferences_list_table_items_per_page', 'slicewp_token', false );
echo '</form>';
echo '</div>';
}
/**
* Outputs the pagination elements.
*
*/
public function output_table_pagination() {
if ( count( $this->items ) == 0 ) {
return;
}
$total_pages = ceil( $this->items_total / $this->items_per_page );
echo '<div class="slicewp-list-table-pagination">';
if ( $this->items_total <= count( $this->items ) ) {
if ( $this->items_total == 1 ) {
echo '<span>' . __( '1 result', 'slicewp' ) . '</span>';
} else {
echo '<span>' . sprintf( __( '%d results', 'slicewp' ), $this->items_total ) . '</span>';
}
} else {
$first_item_count = ( $this->current_page - 1 ) * $this->items_per_page + 1;
$last_item_count = ( $this->current_page * $this->items_per_page < $this->items_total ? $first_item_count + $this->items_per_page - 1 : $this->items_total );
$parsed_url = parse_url( $this->screen_base_url );
parse_str( $parsed_url['query'], $query_vars );
$screen_url = add_query_arg( array_diff_key( $_GET, $query_vars ), $this->screen_base_url );
echo '<span>' . sprintf( __( 'Showing %s-%s of %s results', 'slicewp' ), '<strong>' . $first_item_count . '</strong>', '<strong>' . $last_item_count . '</strong>', '<strong>' . $this->items_total . '</strong>' ) . '</span>';
echo '<div class="slicewp-pagination-links">';
$page_number_arg_slug = ( ! empty( $this->id ) ? 'page_number_' . $this->id : 'page_number' );
if ( $this->current_page == 1 ) {
echo '<span class="slicewp-pagination-link">' . slicewp_get_svg( 'outline-chevron-double-left' ) . '</span>';
} else {
echo '<a class="slicewp-pagination-link" href="' . esc_url( add_query_arg( array( $page_number_arg_slug => 1 ), $screen_url ) ) . '" title="' . __( 'First page', 'slicewp' ) . '">' . slicewp_get_svg( 'outline-chevron-double-left' ) . '</a>';
}
if ( $this->current_page == 1 ) {
echo '<span class="slicewp-pagination-link">' . slicewp_get_svg( 'outline-chevron-left' ) . '</span>';
} else {
echo '<a class="slicewp-pagination-link" href="' . esc_url( add_query_arg( array( $page_number_arg_slug => $this->current_page - 1 ), $screen_url ) ) . '" title="' . __( 'Previous page', 'slicewp' ) . '">' . slicewp_get_svg( 'outline-chevron-left' ) . '</a>';
}
if ( $this->current_page == $total_pages ) {
echo '<span class="slicewp-pagination-link">' . slicewp_get_svg( 'outline-chevron-right' ) . '</span>';
} else {
echo '<a class="slicewp-pagination-link" href="' . esc_url( add_query_arg( array( $page_number_arg_slug => $this->current_page + 1 ), $screen_url ) ) . '" title="' . __( 'Next page', 'slicewp' ) . '">' . slicewp_get_svg( 'outline-chevron-right' ) . '</a>';
}
if ( $this->current_page == $total_pages ) {
echo '<span class="slicewp-pagination-link">' . slicewp_get_svg( 'outline-chevron-double-right' ) . '</span>';
} else {
echo '<a class="slicewp-pagination-link" href="' . esc_url( add_query_arg( array( $page_number_arg_slug => $total_pages ), $screen_url ) ) . '" title="' . __( 'Last page', 'slicewp' ) . '">' . slicewp_get_svg( 'outline-chevron-double-right' ) . '</a>';
}
echo '</div>';
}
echo '</div>';
}
/**
* Prepares the items for output.
* Needs to return an array of arrays. Will parse provided data to make sure the output is as required.
*
* @param array $items
*
* @return array
*
*/
protected function prepare_items_for_output( $items ) {
foreach ( $items as $key => $item ) {
if ( is_array( $item ) ) {
continue;
}
if ( is_object( $item ) ) {
$items[$key] = slicewp_object_to_array( $item );
}
}
return $items;
}
/**
* Determines whether to show the details for the table items globally per table.
*
* @return bool
*
*/
protected function should_show_items_details() {
$show = false;
if ( ! empty( $this->id ) ) {
/**
* Filter to modify the displaying of the items details, for the table with the set id.
*
* @param bool $show
* @param array $item
*
*/
$show = apply_filters( 'slicewp_list_table_should_show_items_details_' . $this->id, $show );
}
return $show;
}
}