PluginProbe
Bubble Menu – Floating Button Menu with Sticky Navigation / 4.0
Bubble Menu – Floating Button Menu with Sticky Navigation v4.0
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, at classes/Admin/ListTable.php

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