PluginProbe
Awesome Support – WordPress HelpDesk & Support Plugin / trunk
Awesome Support – WordPress HelpDesk & Support Plugin vtrunk
6.4.0 trunk 3.0.0 3.0.1 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 All 95 releases
awesome-support / includes / admin / functions-list-table.php

functions-list-table.php in Awesome Support – WordPress HelpDesk & Support Plugin trunk, at includes/admin/functions-list-table.php

391 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Awesome Support/Admin/Functions/List Table
4 * @author AwesomeSupport <contact@getawesomesupport.com>
5 * @license GPL-2.0+
6 * @link https://getawesomesupport.com
7 * @copyright 2015-2017 AwesomeSupport
8 */
9
10 // If this file is called directly, abort.
11 if ( ! defined( 'WPINC' ) ) {
12 die;
13 }
14
15 add_action( 'pre_get_posts', 'wpas_hide_others_tickets', 10, 1 );
16 /**
17 * Hide tickets not assigned to current user.
18 *
19 * Admins and agents can be set to only see their own tickets.
20 * In this case, we modify the main query to only get the tickets
21 * the current user is assigned to.
22 *
23 * @since 3.0.0
24 *
25 * @param object $query WordPress main query.
26 *
27 * @return boolean True if the main query was modified, false otherwise
28 */
29 function wpas_hide_others_tickets( $query ) {
30
31 /* Make sure this is the main query */
32 if ( ! $query->is_main_query() ) {
33 return false;
34 }
35
36 /* Make sure this is the admin screen */
37 if ( ! is_admin() ) {
38 return false;
39 }
40
41 $post_type = isset( $_GET['post_type'] ) ? sanitize_text_field( wp_unslash( $_GET['post_type'] ) ) : '';
42
43 /* Make sure we only alter our post type */
44 if ( 'ticket' !== $post_type ) {
45 return false;
46 }
47
48 global $current_user;
49
50 /* Don't filter auto-draft, draft or trashed tickets - they don't need assignee meta filtering */
51 $post_status = isset( $_GET['post_status'] ) ? sanitize_text_field( wp_unslash( $_GET['post_status'] ) ) : '';
52 if ( in_array( $post_status, array( 'auto-draft', 'draft', 'trash' ), true ) ) {
53 return false;
54 }
55
56
57 // We need to update the original meta_query and not replace it to avoid filtering issues.
58 $meta_query = $query->get( 'meta_query' );
59
60 if ( ! is_array( $meta_query ) ) {
61 $meta_query = array_filter( (array) $meta_query );
62 }
63
64 $agents_meta_query = wpas_ticket_listing_assignee_meta_query_args( $current_user->ID );
65
66 if( !empty( $agents_meta_query ) ) {
67 $meta_query[] = $agents_meta_query;
68 $query->set( 'meta_query', $meta_query );
69 }
70
71 return true;
72
73 }
74
75 /**
76 * Limit the list of tickets to open.
77 *
78 * When tickets are filtered by post status it makes no sense
79 * to display tickets that are already closed. We hereby limit
80 * the list to open tickets.
81 *
82 * @since 3.1.3
83 *
84 * @param object $query WordPress main query.
85 *
86 * @return boolean True if the tickets were filtered, false otherwise
87 */
88 function wpas_limit_open( $query ) {
89
90 /* Make sure this is the main query */
91 if ( ! $query->is_main_query() ) {
92 return false;
93 }
94
95 /* Make sure this is the admin screen */
96 if ( ! is_admin() ) {
97 return false;
98 }
99
100 $post_type = isset( $_GET['post_type'] ) ? sanitize_text_field( wp_unslash( $_GET['post_type'] ) ) : '';
101 $post_status = isset( $_GET['post_status'] ) ? sanitize_text_field( wp_unslash( $_GET['post_status'] ) ) : '';
102
103 /* Make sure we only alter our post type */
104 if ( 'ticket' !== $post_type ) {
105 return false;
106 }
107
108 /* Don't filter auto-draft, draft or trashed tickets - they don't need _wpas_status meta filtering */
109 if ( in_array( $post_status, array( 'auto-draft', 'draft', 'trash' ), true ) ) {
110 return false;
111 }
112
113 if ( array_key_exists( $post_status, wpas_get_post_status() ) || empty( $post_status ) && true === (bool) wpas_get_option( 'hide_closed', false ) ) {
114
115 // We need to update the original meta_query and not replace it to avoid filtering issues.
116 $meta_query = $query->get( 'meta_query' );
117
118 if ( ! is_array( $meta_query ) ) {
119 $meta_query = array_filter( (array) $meta_query );
120 }
121
122 $meta_query[] = array(
123 'key' => '_wpas_status',
124 'value' => 'open',
125 'compare' => '=',
126 'type' => 'CHAR',
127 );
128
129 $query->set( 'meta_query', $meta_query );
130
131 return true;
132
133 } else {
134 return false;
135 }
136
137 }
138
139 add_filter( 'post_row_actions', 'wpas_ticket_action_row', 10, 2 );
140 /**
141 * Add items in action row.
142 *
143 * Add a quick option to open or close a ticket
144 * directly from the tickets list.
145 *
146 * @since 3.0.0
147 *
148 * @param array $actions List of existing options.
149 * @param object $post Current post object.
150 *
151 * @return array List of options with ours added
152 */
153 function wpas_ticket_action_row( $actions, $post ) {
154
155 if ( 'ticket' === $post->post_type ) {
156
157 /* For auto-draft and draft tickets, only allow Edit and Trash */
158 if ( in_array( get_post_status( $post->ID ), array( 'auto-draft', 'draft' ), true ) ) {
159 return array_intersect_key( $actions, array_flip( array( 'edit', 'trash' ) ) );
160 }
161
162 $status = wpas_get_ticket_status( $post->ID );
163
164 if ( 'open' === $status ) {
165 $actions['closeticket'] = '<a href="' . wpas_get_close_ticket_url( $post->ID ) . '">' . __( 'Close', 'awesome-support' ) . '</a>';
166 } elseif ( 'closed' === $status ) {
167 $actions['openticket'] = '<a href="' . wpas_get_open_ticket_url( $post->ID ) . '">' . __( 'Open', 'awesome-support' ) . '</a>';
168 }
169 }
170
171 return $actions;
172 }
173
174 add_filter( 'views_edit-ticket', 'wpas_fix_tickets_count' );
175 /**
176 * Fix the ticket count in the ticket list screen
177 *
178 * The ticket count is wrong because it doesn't includes
179 * the possible restrictions on user roles.
180 *
181 * @since 3.2
182 *
183 * @param array $views All available views in the ticket list screen.
184 *
185 * @return array All views with accurate count
186 */
187 function wpas_fix_tickets_count( $views ) {
188
189 global $wp_query;
190
191 $ticket_status = wpas_get_post_status(); // Our declared ticket status.
192 $status = 'open';
193 $post_status = isset( $_GET['post_status'] ) ? sanitize_text_field( wp_unslash( $_GET['post_status'] ) ) : '';
194
195 // Maybe apply filters.
196 if ( ! empty( $post_status ) ) {
197 switch ( $post_status ) {
198 case 'closed':
199 $status = 'closed';
200 break;
201 case '':
202 $status = 'any';
203 break;
204 }
205 }
206
207 // Add Closed view to the list
208 if ( ! isset( $views['closed'] ) ) {
209 $views['closed'] = __( 'Closed', 'awesome-support' );
210 }
211
212 foreach ( $views as $view => $label ) {
213
214 if ( array_key_exists( $view, $ticket_status ) || 'all' === $view || 'closed' === $view ) {
215
216 if ( 'closed' === $view ) {
217 $count = wpas_get_ticket_count_by_status( '', 'closed' );
218 } else {
219 $count = 'all' === $view ? wpas_get_ticket_count_by_status( '', $status ) : wpas_get_ticket_count_by_status( $view, $status );
220 }
221
222 $regex = '.*?(\\(.*\\))';
223 $replace = '';
224
225 if ( preg_match_all( '/' . $regex . '/is', $label, $matches ) ) {
226 $replace = $matches[1][0];
227 }
228
229 $label = trim( wp_strip_all_tags( str_replace( $replace, '', $label ) ) );
230
231 if ( 'closed' === $view ) {
232 $class = isset( $_GET['status'] ) && 'closed' === $_GET['status'] ? ' class="current"' : '';
233 $link_query_args = array( 'post_type' => 'ticket', 'status' => 'closed' );
234 } else {
235 $is_current = ( isset( $wp_query->query_vars['post_status'] ) && $wp_query->query_vars['post_status'] === $view ) || ( 'all' === $view && null === $wp_query->query_vars['post_status'] && ! isset( $_GET['status'] ) );
236 $class = $is_current ? ' class="current"' : '';
237 $link_query_args = 'all' === $view ? array( 'post_type' => 'ticket' ) : array( 'post_type' => 'ticket', 'post_status' => $view );
238 }
239
240 $link = esc_url( add_query_arg( $link_query_args, admin_url( 'edit.php' ) ) );
241 $views[ $view ] = sprintf( '<a href="%1$s"%2$s>%3$s <span class="count">(%4$d)</span></a>', $link, $class, $label, $count );
242
243 }
244 }
245
246 /* Add Auto-draft view */
247 global $wpdb;
248 $auto_draft_count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = 'ticket' AND post_status = 'auto-draft'" );
249 if ( $auto_draft_count > 0 ) {
250 $ad_class = ( isset( $_GET['post_status'] ) && 'auto-draft' === $_GET['post_status'] ) ? ' class="current"' : '';
251 $ad_link = esc_url( add_query_arg( array( 'post_type' => 'ticket', 'post_status' => 'auto-draft' ), admin_url( 'edit.php' ) ) );
252 $views['auto-draft'] = sprintf( '<a href="%1$s"%2$s>%3$s <span class="count">(%4$d)</span></a>', $ad_link, $ad_class, __( 'Auto-draft', 'awesome-support' ), $auto_draft_count );
253 }
254
255 return $views;
256
257 }
258
259
260 add_filter( 'bulk_actions-edit-ticket', 'wpas_manage_ticket_bulk_actions', 11, 1 );
261
262 /**
263 * Remove bulk edit action from ticket listing page
264 *
265 * @param array $bulk_actions
266 * @return array
267 */
268 function wpas_manage_ticket_bulk_actions( $bulk_actions ) {
269
270 if( isset( $bulk_actions['edit'] ) ) {
271 unset( $bulk_actions['edit'] );
272 }
273
274 $bulk_actions['wpas_bulk_close'] = __( 'Close', 'awesome-support' );
275 $bulk_actions['wpas_bulk_reopen'] = __( 'Reopen', 'awesome-support' );
276
277 /* Add Delete Permanently option when viewing auto-drafts */
278 $current_status = isset( $_GET['post_status'] ) ? sanitize_text_field( wp_unslash( $_GET['post_status'] ) ) : '';
279 if ( 'auto-draft' === $current_status && current_user_can( 'delete_tickets' ) ) {
280 $bulk_actions['wpas_bulk_delete'] = __( 'Delete Permanently', 'awesome-support' );
281 }
282
283 return $bulk_actions;
284 }
285
286
287 add_filter( 'post_row_actions', 'wpas_add_print_quick_action', 10, 2 );
288 /**
289 * Add print quick action to tickets list table
290 *
291 * @since 5.1.1
292 *
293 * @param array $actions
294 * @param object $post
295 *
296 * @return array
297 */
298 function wpas_add_print_quick_action( $actions, $post ) {
299
300 if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'ticket' && ! in_array( get_post_status( $post->ID ), array( 'auto-draft', 'draft', 'trash' ), true ) ) {
301 $actions['wpas_print'] = sprintf( '<a href="#" class="wpas-admin-quick-action-print" data-id="%s">%s</a>', $post->ID, __( 'Print', 'awesome-support' ) );
302 }
303
304 return $actions;
305
306 }
307
308
309 add_filter( 'bulk_actions-edit-ticket', 'wpas_add_print_bulk_action' );
310 /**
311 * Add print tickets bulk action to tickets list table
312 *
313 * @since 5.1.1
314 *
315 * @param array $actions
316 *
317 * @return array
318 */
319 function wpas_add_print_bulk_action( $actions ) {
320
321 if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'ticket' ) {
322 $actions['wpas_print_tickets'] = __( 'Print Tickets', 'awesome-support' );
323 }
324
325 return $actions;
326 }
327
328 add_filter( 'handle_bulk_actions-edit-ticket', 'wpas_handle_ticket_bulk_actions', 10, 3 );
329 /**
330 * Handle custom bulk actions for tickets list table.
331 */
332 function wpas_handle_ticket_bulk_actions( $redirect_to, $action, $post_ids ) {
333 if ( ! in_array( $action, array( 'wpas_bulk_close', 'wpas_bulk_reopen', 'wpas_bulk_delete' ), true ) ) {
334 return $redirect_to;
335 }
336
337 $count = 0;
338
339 foreach ( $post_ids as $post_id ) {
340 if ( 'wpas_bulk_close' === $action ) {
341 if ( 'closed' !== wpas_get_ticket_status( $post_id ) ) {
342 wpas_close_ticket( $post_id, 0, true );
343 $count++;
344 }
345 } elseif ( 'wpas_bulk_reopen' === $action ) {
346 if ( 'closed' === wpas_get_ticket_status( $post_id ) ) {
347 wpas_reopen_ticket( $post_id );
348 $count++;
349 }
350 } elseif ( 'wpas_bulk_delete' === $action ) {
351 if ( current_user_can( 'delete_tickets' ) && 'auto-draft' === get_post_status( $post_id ) ) {
352 wp_delete_post( $post_id, true ); // true = force delete, skip trash
353 $count++;
354 }
355 }
356 }
357
358 $redirect_to = add_query_arg( array(
359 'wpas_bulk_action' => $action,
360 'wpas_bulk_count' => $count,
361 ), $redirect_to );
362
363 return $redirect_to;
364 }
365
366 add_action( 'admin_notices', 'wpas_ticket_bulk_actions_admin_notice' );
367 /**
368 * Display notices for custom bulk actions.
369 */
370 function wpas_ticket_bulk_actions_admin_notice() {
371 if ( ! empty( $_GET['wpas_bulk_action'] ) && isset( $_GET['wpas_bulk_count'] ) ) {
372 $action = sanitize_key( $_GET['wpas_bulk_action'] );
373 $count = intval( $_GET['wpas_bulk_count'] );
374
375 if ( 'wpas_bulk_close' === $action ) {
376 $message = sprintf( _n( '%s ticket has been closed.', '%s tickets have been closed.', $count, 'awesome-support' ), $count );
377 } elseif ( 'wpas_bulk_reopen' === $action ) {
378 $message = sprintf( _n( '%s ticket has been reopened.', '%s tickets have been reopened.', $count, 'awesome-support' ), $count );
379 } elseif ( 'wpas_bulk_delete' === $action ) {
380 $message = sprintf( _n( '%s auto-draft ticket has been permanently deleted.', '%s auto-draft tickets have been permanently deleted.', $count, 'awesome-support' ), $count );
381 }
382
383 if ( isset( $message ) ) {
384 ?>
385 <div class="notice notice-success is-dismissible">
386 <p><?php echo esc_html( $message ); ?></p>
387 </div>
388 <?php
389 }
390 }
391 }