, Wow-Company * @copyright 2024 Dmytro Lobov * @license GPL-2.0+ * * @see https://developer.wordpress.org/reference/classes/wp_list_table/ */ namespace FloatMenuLite\Admin; defined( 'ABSPATH' ) || exit; use WP_List_Table; use FloatMenuLite\WOWP_Plugin; class ListTable extends WP_List_Table { public int $per_page = 30; public function __construct() { // Set parent defaults parent::__construct( array( 'ajax' => false, ) ); $this->process_bulk_action(); } public function column_default( $item, $column_name ) { return $item[ $column_name ]; } // phpcs:disable WordPress.Security.NonceVerification.Recommended public function search_box( $text, $input_id ): void { $input_id .= '-search-input'; if ( ! empty( $_REQUEST['orderby'] ) ) { $orderby = sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ); echo ''; } if ( ! empty( $_REQUEST['order'] ) ) { $order = sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ); echo ''; } ?> '#' . $item['ID'], 'edit' => '' . esc_attr__( 'Edit', 'float-menu' ) . '', 'duplicate' => '' . esc_attr__( 'Duplicate', 'float-menu' ) . '', 'delete' => '' . esc_attr__( 'Delete', 'float-menu' ) . '', 'export' => '' . esc_attr__( 'Export', 'float-menu' ) . '', ]; if ( ! empty( $param['link'] ) ) { $actions['view'] = '' . esc_attr__( 'View', 'float-menu' ) . ''; } return $title . $this->row_actions( $actions ); } public function prepare_items(): void { $columns = $this->get_columns(); $hidden = $this->get_hidden_columns(); $sortable = $this->get_sortable_columns(); $data = $this->table_data(); $perPage = 30; $currentPage = $this->get_pagenum(); if ( $data ) { usort( $data, [ &$this, 'sort_data' ] ); $data = array_slice( $data, ( ( $currentPage - 1 ) * $perPage ), $perPage ); } $totalItems = $this->list_count(); $this->_column_headers = [ $columns, $hidden, $sortable ]; $this->items = $data; $this->set_pagination_args( [ 'total_items' => $totalItems, 'per_page' => $perPage, 'total_pages' => ceil( $totalItems / $perPage ), ] ); } public function get_columns(): array { return [ 'cb' => '', 'title' => __( 'Title', 'float-menu' ), 'code' => __( 'Shortcode', 'float-menu' ), 'tag' => __( 'Tag', 'float-menu' ), 'mode' => __( 'Test mode', 'float-menu' ) . '', 'status' => __( 'Status', 'float-menu' ) . '', ]; } public function get_hidden_columns(): array { return []; } public function get_sortable_columns(): array { return [ 'ID' => [ 'ID', false ], ]; } private function table_data(): array { $data = []; $paged = $this->get_paged(); $offset = $this->per_page * ( $paged - 1 ); $result = $this->get_results(); $slug = WOWP_Plugin::SLUG; $shortcode = WOWP_Plugin::SHORTCODE; if ( empty( $result ) ) { return $data; } $main_link = add_query_arg( [ 'page' => $slug, 'tab' => 'settings', 'action' => 'update' ], admin_url( 'admin.php' ) ); foreach ( $result as $key => $value ) { $title = ! empty( $value->title ) ? $value->title : __( 'UnTitle', 'float-menu' ); $tooltip_off = esc_attr__( 'Click for Deactivate.', 'float-menu' ); $tooltip_on = esc_attr__( 'Click for Activate.', 'float-menu' ); $status_off = '' . esc_attr__( 'OFF', 'float-menu' ) . ''; $status_on = '' . esc_attr__( 'ON', 'float-menu' ) . ''; $status = ! empty( $value->status ) ? $status_off : $status_on; $mode_tooltip_off = esc_attr__( 'Click for OFF.', 'float-menu' ); $mode_tooltip_on = esc_attr__( 'Click for ON.', 'float-menu' ); $mode_off = '' . esc_attr__( 'OFF', 'float-menu' ) . ''; $mode_on = '' . esc_attr__( 'ON', 'float-menu' ) . ''; $mode = empty( $value->mode ) ? $mode_off : $mode_on; $tag = ''; if ( isset( $value->tag ) ) { $tag_url = add_query_arg( [ 'page' => WOWP_Plugin::SLUG, 'tag' => $value->tag ], admin_url( 'admin.php' ) ); $tag = '' . esc_attr( $value->tag ) . ''; } $link = add_query_arg( [ 'id' => $value->id ], $main_link ); $data[] = array( 'ID' => $value->id, 'title' => '' . esc_attr( $title ) . '', 'code' => '', 'tag' => $tag, 'mode' => $mode, 'status' => $status, ); } return $data; } public function column_cb( $item ) { return sprintf( '', 'ID', $item['ID'] ); } public function get_paged(): int { return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended } public function get_search() { $verify = AdminActions::verify( WOWP_Plugin::PREFIX . '_list_action' ); if ( ! $verify ) { return false; } // phpcs:disable WordPress.Security.NonceVerification.Missing -- Nonce verification is handled elsewhere. return ! empty( $_POST['s'] ) ? urldecode( trim( sanitize_text_field( wp_unslash( $_POST['s'] ) ) ) ) : false; // phpcs:enable } public function list_count(): int { $result = $this->get_results(); if ( empty( $result ) ) { return 0; } $count = count( $result ); return (int) $count; } public function get_results() { global $wpdb; $search = $this->get_search(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $tag_search = ( ! empty( $_REQUEST['tag'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST ['tag'] ) ) : ''; $tag_search = ( $tag_search === 'all' ) ? '' : $tag_search; $result = ''; $table = esc_sql($wpdb->prefix . WOWP_Plugin::PREFIX); // Table name is sanitized elsewhere. if ( empty( $search ) ) { // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->get_results( "SELECT * FROM {$table} ORDER BY id DESC" ); if ( ! empty( $tag_search ) ) { // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE tag=%s ORDER BY id DESC", $tag_search ) ); } } elseif ( trim( $search ) === 'UnTitle' ) { // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->get_results( "SELECT * FROM {$table} WHERE title='' ORDER BY id DESC" ); if ( ! empty( $tag_search ) ) { // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title='' AND tag=%s ORDER BY id DESC", $tag_search ) ); } } elseif ( is_numeric( $search ) ) { if ( ! empty( $tag_search ) ) { // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE id=%d AND tag=%s ORDER BY id DESC", absint( $search ), $tag_search ) ); } else { // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE id=%d ORDER BY id DESC", absint( $search ) ) ); } } else { $wild = '%'; $find = sanitize_text_field( $search ); $like = $wild . $wpdb->esc_like( $find ) . $wild; if ( ! empty( $tag_search ) ) { // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title LIKE %s AND tag=%s ORDER BY id DESC", $like, $tag_search ) ); } else { // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title LIKE %s ORDER BY id DESC", $like ) ); } } return $result; } public function get_bulk_actions(): array { $actions = [ 'delete' => __( 'Delate', 'float-menu' ), 'activate' => __( 'Activate', 'float-menu' ), 'deactivate' => __( 'Deactivate', 'float-menu' ), 'test_on' => __( 'Test mode ON', 'float-menu' ), 'test_off' => __( 'Test mode OFF', 'float-menu' ), ]; return $actions; } public function process_bulk_action() { $verify = AdminActions::verify( WOWP_Plugin::PREFIX . '_list_action' ); if ( ! $verify ) { return false; } // phpcs:ignore WordPress.Security.NonceVerification.Missing $ids = isset( $_POST['ID'] ) ? ( map_deep( $_POST['ID'], 'absint' ) ) : false; $action = $this->current_action(); if ( ! is_array( $ids ) ) { $ids = [ $ids ]; } if ( empty( $action ) ) { return false; } foreach ( $ids as $id ) { if ( 'delete' === $this->current_action() ) { DBManager::delete( $id ); } if ( 'activate' === $this->current_action() ) { Settings::activate_item( $id ); } if ( 'deactivate' === $this->current_action() ) { Settings::deactivate_item( $id ); } if ( 'test_on' === $this->current_action() ) { Settings::activate_mode( $id ); } if ( 'test_off' === $this->current_action() ) { Settings::deactivate_mode( $id ); } } } protected function extra_tablenav( $which ): void { if ( 'top' === $which ) { $tags = DBManager::get_tags_from_table(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $tag_search = ( ! empty( $_REQUEST['tag'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['tag'] ) ) : ''; $tag_search = ( $tag_search === 'all' ) ? '' : $tag_search; echo '
'; echo ''; submit_button( __( 'Filter', 'float-menu' ), 'secondary', 'action', false ); echo '
'; } } private function sort_data( $a, $b ): int { // If no sort, default to title // phpcs:ignore WordPress.Security.NonceVerification.Recommended $orderby = ( ! empty( $_GET['orderby'] ) ) ? sanitize_text_field( wp_unslash($_GET['orderby']) ) : 'ID'; // If no order, default to asc // phpcs:ignore WordPress.Security.NonceVerification.Recommended $order = ( ! empty( $_GET['order'] ) ) ? sanitize_text_field( wp_unslash($_GET['order']) ) : 'desc'; // Determine sort order $result = strnatcmp( $a[ $orderby ], $b[ $orderby ] ); // Send final sort direction to usort return ( $order === 'asc' ) ? $result : - $result; } }