PluginProbe
Bubble Menu – Floating Button Menu with Sticky Navigation / 4.0.1
Bubble Menu – Floating Button Menu with Sticky Navigation v4.0.1
trunk 1.3 2.0 2.2 2.2.1 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1 3.1.1 4.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.1 4.1.1
bubble-menu / classes / Admin / ListTable.php

ListTable.php in Bubble Menu – Floating Button Menu with Sticky Navigation 4.0.1, at classes/Admin/ListTable.php

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