PluginProbe
Float menu – awesome floating side menu / 6.1
Float menu – awesome floating side menu v6.1
7.2.5 trunk 2.1 2.2 3.0.1 3.1 3.2.2 3.3.1 3.5 3.5.1 3.5.2 3.5.3. 3.5.4 4.0 4.1 4.1.1 4.2 4.3 4.3.1 4.3.2 5.0 5.0.1 5.0.2 5.0.3 5.1 All 57 releases
float-menu / classes / Admin / ListTable.php

ListTable.php in Float menu – awesome floating side menu 6.1, at classes/Admin/ListTable.php

365 lines 12.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class ListTable
5 *
6 * @package WowPlugin
7 * @subpackage Admin
8 * @author Dmytro Lobov <dev@wow-company.com>, Wow-Company
9 * @copyright 2024 Dmytro Lobov
10 * @license GPL-2.0+
11 *
12 * @see https://developer.wordpress.org/reference/classes/wp_list_table/
13 */
14
15 namespace FloatMenuLite\Admin;
16
17 defined( 'ABSPATH' ) || exit;
18
19 use WP_List_Table;
20 use FloatMenuLite\WOWP_Plugin;
21
22 class ListTable extends WP_List_Table {
23
24 public int $per_page = 30;
25
26 public function __construct() {
27 // Set parent defaults
28 parent::__construct( array(
29 'ajax' => false,
30 ) );
31 $this->process_bulk_action();
32 }
33
34 public function column_default( $item, $column_name ) {
35 return $item[ $column_name ];
36 }
37
38 public function search_box( $text, $input_id ): void {
39 $input_id .= '-search-input';
40 if ( ! empty( $_REQUEST['orderby'] ) ) {
41 $orderby = sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) );
42 echo '<input type="hidden" name="orderby" value="' . esc_attr( $orderby ) . '" />';
43 }
44 if ( ! empty( $_REQUEST['order'] ) ) {
45 $order = sanitize_text_field( wp_unslash( $_REQUEST['order'] ) );
46 echo '<input type="hidden" name="order" value="' . esc_attr( $order ) . '" />';
47 }
48 ?>
49 <p class="search-box">
50 <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ) ?>">
51 <?php echo esc_attr( $text ); ?>:
52 </label>
53 <input type="search" id="<?php echo esc_attr( $input_id ) ?>" name="s"
54 value="<?php _admin_search_query(); ?>"/>
55 <?php submit_button( $text, 'button', false, false, array( 'ID' => 'search-submit' ) ); ?>
56 </p>
57 <?php
58 }
59
60 public function column_title( $item ): string {
61 $title = ! empty( $item['title'] ) ? $item['title'] : __( 'Untitled', 'float-menu' );
62 $param = DBManager::get_param_id( $item['ID'] );
63 $actions = [
64 'id' => '#' . $item['ID'],
65 'edit' => '<a href="' . esc_url( Link::edit( $item['ID'] ) ) . '">' . esc_attr__( 'Edit',
66 'float-menu' ) . '</a>',
67 'duplicate' => '<a href="' . esc_url( Link::duplicate( $item['ID'] ) ) . '">' . esc_attr__( 'Duplicate',
68 'float-menu' ) . '</a>',
69 'delete' => '<a href="' . esc_url( Link::remove( $item['ID'] ) ) . '" >' . esc_attr__( 'Delete',
70 'float-menu' ) . '</a>',
71 'export' => '<a href="' . esc_url( Link::export( $item['ID'] ) ) . '" >' . esc_attr__( 'Export',
72 'float-menu' ) . '</a>',
73 ];
74 if ( ! empty( $param['link'] ) ) {
75 $actions['view'] = '<a href="' . esc_url( $param['link'] ) . '" target="_blank">' . esc_attr__( 'View',
76 'float-menu' ) . '</a>';
77 }
78
79
80 return $title . $this->row_actions( $actions );
81 }
82
83 public function prepare_items(): void {
84 $columns = $this->get_columns();
85 $hidden = $this->get_hidden_columns();
86 $sortable = $this->get_sortable_columns();
87 $data = $this->table_data();
88 $perPage = 30;
89 $currentPage = $this->get_pagenum();
90 if ( $data ) {
91 usort( $data, [ &$this, 'sort_data' ] );
92 $data = array_slice( $data, ( ( $currentPage - 1 ) * $perPage ), $perPage );
93 }
94 $totalItems = $this->list_count();
95 $this->_column_headers = [ $columns, $hidden, $sortable ];
96 $this->items = $data;
97 $this->set_pagination_args( [
98 'total_items' => $totalItems,
99 'per_page' => $perPage,
100 'total_pages' => ceil( $totalItems / $perPage ),
101 ] );
102 }
103
104 public function get_columns(): array {
105 return [
106 'cb' => '<input type="checkbox" />',
107 'title' => __( 'Title', 'float-menu' ),
108 'code' => __( 'Shortcode', 'float-menu' ),
109 'tag' => __( 'Tag', 'float-menu' ),
110 'mode' => __( 'Test mode',
111 'float-menu' ) . '<sup class="has-tooltip" data-tooltip="' . __( 'The item will only be displayed for administrators.',
112 'float-menu' ) . '">ℹ</sup>',
113 'status' => __( 'Status',
114 'float-menu' ) . '<sup class="has-tooltip" data-tooltip="' . __( 'The item will only be displayed for administrators.',
115 'float-menu' ) . '">ℹ</sup>',
116 ];
117 }
118
119 public function get_hidden_columns(): array {
120 return [];
121 }
122
123 public function get_sortable_columns(): array {
124 return [
125 'ID' => [ 'ID', false ],
126 ];
127 }
128
129 private function table_data(): array {
130 $data = [];
131 $paged = $this->get_paged();
132 $offset = $this->per_page * ( $paged - 1 );
133
134 $result = $this->get_results();
135
136 $slug = WOWP_Plugin::SLUG;
137 $shortcode = WOWP_Plugin::SHORTCODE;
138
139 if ( empty( $result ) ) {
140 return $data;
141 }
142
143 $main_link = add_query_arg( [
144 'page' => $slug,
145 'tab' => 'settings',
146 'action' => 'update'
147 ], admin_url( 'admin.php' ) );
148 foreach ( $result as $key => $value ) {
149 $title = ! empty( $value->title ) ? $value->title : __( 'UnTitle', 'float-menu' );
150 $tooltip_off = esc_attr__( 'Click for Deactivate.', 'float-menu' );
151 $tooltip_on = esc_attr__( 'Click for Activate.', 'float-menu' );
152 $status_off = '<a href="' . esc_url( Link::activate_url( $value->id ) ) . '" class="wpie-toogle is-off" data-tooltip="' . esc_attr( $tooltip_on ) . '"><span>' . esc_attr__( 'OFF',
153 'float-menu' ) . '</span></a>';
154 $status_on = '<a href="' . esc_url( Link::deactivate_url( $value->id ) ) . '" class="wpie-toogle is-on" data-tooltip="' . esc_attr( $tooltip_off ) . '"><span>' . esc_attr__( 'ON',
155 'float-menu' ) . '</span></a>';
156 $status = ! empty( $value->status ) ? $status_off : $status_on;
157
158 $mode_tooltip_off = esc_attr__( 'Click for OFF.', 'float-menu' );
159 $mode_tooltip_on = esc_attr__( 'Click for ON.', 'float-menu' );
160
161 $mode_off = '<a href="' . esc_url( Link::activate_mode( $value->id ) ) . '" class="wpie-toogle is-off" data-tooltip="' . esc_attr( $mode_tooltip_on ) . '"><span>' . esc_attr__( 'OFF',
162 'float-menu' ) . '</span></a>';
163 $mode_on = '<a href="' . esc_url( Link::deactivate_mode( $value->id ) ) . '" class="wpie-toogle is-on" data-tooltip="' . esc_attr( $mode_tooltip_off ) . '"><span>' . esc_attr__( 'ON',
164 'float-menu' ) . '</span></a>';
165
166 $mode = empty( $value->mode ) ? $mode_off : $mode_on;
167
168 $tag = '';
169 if ( isset( $value->tag ) ) {
170 $tag_url = add_query_arg( [
171 'page' => WOWP_Plugin::SLUG,
172 'tag' => $value->tag
173 ], admin_url( 'admin.php' ) );
174 $tag = '<a href="' . esc_url( $tag_url ) . '">' . esc_attr( $value->tag ) . '</a>';
175 }
176
177 $link = add_query_arg( [ 'id' => $value->id ], $main_link );
178 $data[] = array(
179 'ID' => $value->id,
180 'title' => '<a href="' . esc_url( $link ) . '">' . esc_attr( $title ) . '</a>',
181 'code' => '<input type="text" value="[' . esc_attr( $shortcode ) . ' id=\'' . absint( $value->id ) . '\']" readonly>',
182 'tag' => $tag,
183 'mode' => $mode,
184 'status' => $status,
185 );
186 }
187
188 return $data;
189 }
190
191 public function column_cb( $item ) {
192 return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', 'ID', $item['ID'] );
193 }
194
195 public function get_paged(): int {
196 return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1;
197 }
198
199 public function get_search() {
200 $verify = AdminActions::verify( WOWP_Plugin::PREFIX . '_list_action' );
201
202 if ( ! $verify ) {
203 return false;
204 }
205
206 return ! empty( $_POST['s'] ) ? urldecode( trim( sanitize_text_field( wp_unslash( $_POST['s'] ) ) ) ) : false;
207 }
208
209 public function list_count(): int {
210 $result = $this->get_results();
211
212 if ( empty( $result ) ) {
213 return 0;
214 }
215 $count = count( $result );
216
217 return (int) $count;
218 }
219
220 public function get_results() {
221 global $wpdb;
222
223 $search = $this->get_search();
224
225 $tag_search = ( ! empty( $_REQUEST['tag'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST ['tag'] ) ) : '';
226 $tag_search = ( $tag_search === 'all' ) ? '' : $tag_search;
227
228
229 $result = '';
230
231 $table = $wpdb->prefix . WOWP_Plugin::PREFIX;
232
233 if ( empty( $search ) ) {
234 $result = $wpdb->get_results( "SELECT * FROM {$table} ORDER BY id DESC" );
235 if ( ! empty( $tag_search ) ) {
236 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE tag=%s ORDER BY id DESC",
237 $tag_search ) );
238 }
239 } elseif ( trim( $search ) === 'UnTitle' ) {
240 $result = $wpdb->get_results( "SELECT * FROM {$table} WHERE title='' ORDER BY id DESC" );
241 if ( ! empty( $tag_search ) ) {
242 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title='' AND tag=%s ORDER BY id DESC",
243 $tag_search ) );
244 }
245 } elseif ( is_numeric( $search ) ) {
246 if ( ! empty( $tag_search ) ) {
247 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE id=%d AND tag=%s ORDER BY id DESC",
248 absint( $search ), $tag_search ) );
249 } else {
250 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE id=%d ORDER BY id DESC",
251 absint( $search ) ) );
252 }
253 } else {
254 $wild = '%';
255 $find = sanitize_text_field( $search );
256 $like = $wild . $wpdb->esc_like( $find ) . $wild;
257 if ( ! empty( $tag_search ) ) {
258 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title LIKE %s AND tag=%s ORDER BY id DESC",
259 $like, $tag_search ) );
260 } else {
261 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title LIKE %s ORDER BY id DESC",
262 $like ) );
263 }
264 }
265
266 return $result;
267 }
268
269
270 public function get_bulk_actions(): array {
271 $actions = [
272 'delete' => __( 'Delate', 'float-menu' ),
273 'activate' => __( 'Activate', 'float-menu' ),
274 'deactivate' => __( 'Deactivate', 'float-menu' ),
275 'test_on' => __( 'Test mode ON', 'float-menu' ),
276 'test_off' => __( 'Test mode OFF', 'float-menu' ),
277 ];
278
279 return $actions;
280 }
281
282 public function process_bulk_action() {
283 $ids = isset( $_POST['ID'] ) ? ( map_deep( $_POST['ID'], 'absint' ) ) : false;
284 $action = $this->current_action();
285 if ( ! is_array( $ids ) ) {
286 $ids = [ $ids ];
287 }
288 if ( empty( $action ) ) {
289 return false;
290 }
291
292 $verify = $this->verify();
293
294 if ( ! $verify ) {
295 return false;
296 }
297
298 foreach ( $ids as $id ) {
299 if ( 'delete' === $this->current_action() ) {
300 DBManager::delete( $id );
301 }
302 if ( 'activate' === $this->current_action() ) {
303 Settings::activate_item( $id );
304 }
305 if ( 'deactivate' === $this->current_action() ) {
306 Settings::deactivate_item( $id );
307 }
308 if ( 'test_on' === $this->current_action() ) {
309 Settings::activate_mode( $id );
310 }
311 if ( 'test_off' === $this->current_action() ) {
312 Settings::deactivate_mode( $id );
313 }
314 }
315 }
316
317 protected function extra_tablenav( $which ): void {
318 if ( 'top' === $which ) {
319 $tags = DBManager::get_tags_from_table();
320
321 $tag_search = ( ! empty( $_REQUEST['tag'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST ['tag'] ) ) : '';
322 $tag_search = ( $tag_search === 'all' ) ? '' : $tag_search;
323
324 echo '<div class="alignleft actions"><label for="filter-by-tag" class="screen-reader-text">' . esc_html__( 'Filter by tag',
325 'float-menu' ) . '</label>';
326 echo '<select name="tag" id="filter-by-tag">';
327 echo '<option value="all"' . selected( 'all', $tag_search, false ) . '>' . esc_html__( 'All',
328 'float-menu' ) . '</option>';
329
330 if ( ! empty( $tags ) ) {
331 foreach ( $tags as $tag ) {
332 if ( empty( $tag['tag'] ) ) {
333 continue;
334 }
335 echo '<option value="' . esc_attr( trim( $tag['tag'] ) ) . '"' . selected( $tag['tag'], $tag_search,
336 false ) . '>' . esc_html( $tag['tag'] ) . '</option>';
337 }
338 }
339 echo '</select>';
340 submit_button( __( 'Filter', 'float-menu' ), 'secondary', 'action', false );
341 echo '</div>';
342 }
343 }
344
345 private function sort_data( $a, $b ): int {
346 // If no sort, default to title
347 $orderby = ( ! empty( $_GET['orderby'] ) ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : 'ID';
348 // If no order, default to asc
349 $order = ( ! empty( $_GET['order'] ) ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : 'desc';
350 // Determine sort order
351 $result = strnatcmp( $a[ $orderby ], $b[ $orderby ] );
352
353 // Send final sort direction to usort
354 return ( $order === 'asc' ) ? $result : - $result;
355 }
356
357 private function verify(): bool {
358 $name = WOWP_Plugin::PREFIX . '_list_action';
359 $nonce_action = WOWP_Plugin::PREFIX . '_nonce';
360
361 return ! ( ! isset( $_POST[ $name ] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[ $name ] ) ),
362 $nonce_action ) || ! current_user_can( 'manage_options' ) );
363 }
364
365 }