PluginProbe
Float menu – awesome floating side menu / 6.0.3
Float menu – awesome floating side menu v6.0.3
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.0.3, at classes/Admin/ListTable.php

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