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

357 lines 11.9 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' => '<div class="wpie-field">
174 <label class="wpie-field__label has-icon">
175 <span class="has-tooltip is-pointer on-right can-copy" data-tooltip="Copy"><span class="dashicons dashicons-shortcode is-pointer" ></span></span>
176 <input type="text" value="[' . esc_attr( $shortcode ) . ' id=\'' . absint( $value->id ) . '\']" readonly>
177 </label>
178 </div>',
179 'tag' => $tag,
180 'mode' => $mode,
181 'status' => $status,
182 );
183 }
184
185 return $data;
186 }
187
188 public function column_cb( $item ) {
189 return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', 'ID', $item['ID'] );
190 }
191
192 public function get_paged(): int {
193 return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1;
194 }
195
196 public function get_search() {
197 $verify = AdminActions::verify( WOWP_Plugin::PREFIX . '_list_action' );
198
199 if ( ! $verify ) {
200 return false;
201 }
202
203 return ! empty( $_POST['s'] ) ? urldecode( trim( sanitize_text_field( wp_unslash( $_POST['s'] ) ) ) ) : false;
204 }
205
206 public function list_count(): int {
207 $result = $this->get_results();
208
209 if ( empty( $result ) ) {
210 return 0;
211 }
212 $count = count( $result );
213
214
215 return (int) $count;
216 }
217
218 public function get_results() {
219 global $wpdb;
220
221 $search = $this->get_search();
222
223 $tag_search = ( ! empty( $_REQUEST['tag'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST ['tag'] ) ) : '';
224 $tag_search = ( $tag_search === 'all' ) ? '' : $tag_search;
225
226
227 $result = '';
228
229 $table = $wpdb->prefix . WOWP_Plugin::PREFIX;
230
231 if ( empty( $search ) ) {
232 $result = $wpdb->get_results( "SELECT * FROM {$table} ORDER BY id DESC" );
233 if ( ! empty( $tag_search ) ) {
234 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE tag=%s ORDER BY id DESC",
235 $tag_search ) );
236 }
237 } elseif ( trim( $search ) === 'UnTitle' ) {
238 $result = $wpdb->get_results( "SELECT * FROM {$table} WHERE title='' ORDER BY id DESC" );
239 if ( ! empty( $tag_search ) ) {
240 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title='' AND tag=%s ORDER BY id DESC",
241 $tag_search ) );
242 }
243 } elseif ( is_numeric( $search ) ) {
244 if ( ! empty( $tag_search ) ) {
245 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE id=%d AND tag=%s ORDER BY id DESC",
246 absint( $search ), $tag_search ) );
247 } else {
248 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE id=%d ORDER BY id DESC",
249 absint( $search ) ) );
250 }
251 } else {
252 $wild = '%';
253 $find = sanitize_text_field( $search );
254 $like = $wild . $wpdb->esc_like( $find ) . $wild;
255 if ( ! empty( $tag_search ) ) {
256 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title LIKE %s AND tag=%s ORDER BY id DESC",
257 $like, $tag_search ) );
258 } else {
259 $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title LIKE %s ORDER BY id DESC",
260 $like ) );
261 }
262 }
263
264 return $result;
265 }
266
267
268 public function get_bulk_actions(): array {
269 $actions = [
270 'delete' => __( 'Delate', 'bubble-menu' ),
271 'activate' => __( 'Activate', 'bubble-menu' ),
272 'deactivate' => __( 'Deactivate', 'bubble-menu' ),
273 'test_on' => __( 'Test mode ON', 'bubble-menu' ),
274 'test_off' => __( 'Test mode OFF', 'bubble-menu' ),
275 ];
276
277 return $actions;
278 }
279
280 public function process_bulk_action(): bool {
281
282 $verify = AdminActions::verify( WOWP_Plugin::PREFIX . '_list_action' );
283
284 if ( ! $verify ) {
285 return false;
286 }
287
288 $ids = isset( $_POST['ID'] ) ? ( map_deep( $_POST['ID'], 'absint' ) ) : false;
289 $action = $this->current_action();
290 if ( ! is_array( $ids ) ) {
291 $ids = [ $ids ];
292 }
293 if ( empty( $action ) ) {
294 return false;
295 }
296
297 foreach ( $ids as $id ) {
298 if ( 'delete' === $this->current_action() ) {
299 DBManager::delete( $id );
300 }
301 if ( 'activate' === $this->current_action() ) {
302 DBManager::update( [ 'status' => '' ], [ 'ID' => $id ], [ '%d' ] );
303 }
304 if ( 'deactivate' === $this->current_action() ) {
305 DBManager::update( [ 'status' => '1' ], [ 'ID' => $id ], [ '%d' ] );
306 }
307 if ( 'test_on' === $this->current_action() ) {
308 DBManager::update( [ 'mode' => '1' ], [ 'ID' => $id ], [ '%d' ] );
309 }
310 if ( 'test_off' === $this->current_action() ) {
311 DBManager::update( [ 'mode' => '' ], [ 'ID' => $id ], [ '%d' ] );
312 }
313 }
314
315 return true;
316 }
317
318 protected function extra_tablenav( $which ) {
319 if ( 'top' === $which ) {
320 $tags = DBManager::get_tags_from_table();
321
322 $tag_search = ( ! empty( $_REQUEST['tag'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST ['tag'] ) ) : '';
323 $tag_search = ( $tag_search === 'all' ) ? '' : $tag_search;
324
325 echo '<div class="alignleft actions"><label for="filter-by-tag" class="screen-reader-text">' . esc_html__( 'Filter by tag',
326 'bubble-menu' ) . '</label>';
327 echo '<select name="tag" id="filter-by-tag">';
328 echo '<option value="all"' . selected( 'all', $tag_search, false ) . '>' . esc_html__( 'All',
329 'bubble-menu' ) . '</option>';
330
331 if ( ! empty( $tags ) ) {
332 foreach ( $tags as $tag ) {
333 if ( empty( $tag['tag'] ) ) {
334 continue;
335 }
336 echo '<option value="' . esc_attr( trim( $tag['tag'] ) ) . '"' . selected( $tag['tag'], $tag_search,
337 false ) . '>' . esc_html( $tag['tag'] ) . '</option>';
338 }
339 }
340 echo '</select>';
341 submit_button( __( 'Filter', 'bubble-menu' ), 'secondary', 'action', false );
342 echo '</div>';
343 }
344 }
345
346 private function sort_data( $a, $b ): int {
347 // If no sort, default to title
348 $orderby = ( ! empty( $_GET['orderby'] ) ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : 'ID';
349 // If no order, default to asc
350 $order = ( ! empty( $_GET['order'] ) ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : 'desc';
351 // Determine sort order
352 $result = strnatcmp( $a[ $orderby ], $b[ $orderby ] );
353
354 // Send final sort direction to usort
355 return ( $order === 'asc' ) ? $result : - $result;
356 }
357 }