PluginProbe
Tiered Pricing Table for WooCommerce / 7.1.5
Tiered Pricing Table for WooCommerce v7.1.5
8.0.2 7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 All 91 releases
tier-pricing-table / src / Addons / RequestAQuote / CPT / QuoteRequestAdmin.php

QuoteRequestAdmin.php in Tiered Pricing Table for WooCommerce 7.1.5, at src/Addons/RequestAQuote/CPT/QuoteRequestAdmin.php

550 lines 20.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php namespace TierPricingTable\Addons\RequestAQuote\CPT;
2
3 use TierPricingTable\Addons\RequestAQuote\Models\QuoteRequest;
4 use TierPricingTable\TierPricingTablePlugin;
5
6 class QuoteRequestAdmin {
7
8 public function __construct() {
9 add_action( 'add_meta_boxes', array( $this, 'addMetaBoxes' ) );
10 add_action( 'save_post', array( $this, 'savePost' ), 10, 2 );
11 add_action( 'admin_enqueue_scripts', array( $this, 'adminAssets' ) );
12
13 add_filter( 'manage_' . QuoteRequestCPT::POST_TYPE . '_posts_columns', array( $this, 'setCustomColumns' ) );
14 add_action( 'manage_' . QuoteRequestCPT::POST_TYPE . '_posts_custom_column', array( $this, 'customColumnData' ),
15 10, 2 );
16 add_action( 'restrict_manage_posts', array( $this, 'addProductsFilter' ) );
17 add_action( 'pre_get_posts', array( $this, 'filterByProduct' ) );
18
19 add_filter( 'bulk_actions-edit-' . QuoteRequestCPT::POST_TYPE, array( $this, 'registerBulkActions' ) );
20 add_filter( 'handle_bulk_actions-edit-' . QuoteRequestCPT::POST_TYPE, array( $this, 'processBulkActions' ), 10,
21 3 );
22 add_action( 'admin_notices', array( $this, 'bulkActionNotices' ) );
23 }
24
25 public function adminAssets() {
26 global $post_type;
27 if ( QuoteRequestCPT::POST_TYPE === $post_type ) {
28 wp_enqueue_style( 'tpt-quote-admin', plugins_url( '../assets/css/admin-quote-request.css', __FILE__ ),
29 array(), TierPricingTablePlugin::VERSION );
30 wp_enqueue_script( 'tpt-quote-admin', plugins_url( '../assets/js/admin-quote-request.js', __FILE__ ),
31 array( 'jquery' ), TierPricingTablePlugin::VERSION, true );
32 }
33 }
34
35 public function addMetaBoxes() {
36 add_meta_box( 'tier_pricing_table_quote_details', __( 'Customer Request', 'tier-pricing-table' ),
37 array( $this, 'renderDetailsMetaBox' ), QuoteRequestCPT::POST_TYPE, 'normal', 'high' );
38
39 add_meta_box( 'tier_pricing_table_quote_product', __( 'Product', 'tier-pricing-table' ),
40 array( $this, 'renderProductMetaBox' ), QuoteRequestCPT::POST_TYPE, 'normal', 'high' );
41
42 add_meta_box( 'tier_pricing_table_quote_customer', __( 'User', 'tier-pricing-table' ), array( $this, 'renderCustomerMetaBox' ),
43 QuoteRequestCPT::POST_TYPE, 'side', 'high' );
44
45 add_meta_box( 'tier_pricing_table_quote_actions', __( 'Quote Actions', 'tier-pricing-table' ),
46 array( $this, 'renderActionsMetaBox' ), QuoteRequestCPT::POST_TYPE, 'side', 'high' );
47 }
48
49 public function renderDetailsMetaBox( $post ) {
50 $quote = new QuoteRequest( $post );
51 $customFields = $quote->getCustomFields();
52
53 ?>
54 <div class="tpt-quote-grid">
55 <?php
56 foreach ( $customFields as $key => $fieldData ) {
57 if ( ! is_array( $fieldData ) ) {
58 $fieldData = array(
59 'label' => ucfirst( str_replace( '_', ' ', $key ) ),
60 'value' => $fieldData,
61 );
62 }
63 $label = isset( $fieldData['label'] ) && ! empty( $fieldData['label'] ) ? $fieldData['label'] : ucfirst( str_replace( '_',
64 ' ', $key ) );
65 $value = isset( $fieldData['value'] ) ? $fieldData['value'] : '';
66
67 ?>
68 <div class="tpt-quote-field">
69 <label><?php echo esc_html( $label ); ?></label>
70 <?php
71 if ( isset( $fieldData['type'] ) && $fieldData['type'] === 'file' && ! empty( $value ) && filter_var( $value,
72 FILTER_VALIDATE_URL ) ) :
73 $fileName = basename( parse_url( $value, PHP_URL_PATH ) );
74 ?>
75 <span>
76 <a href="<?php echo esc_url( $value ); ?>" target="_blank"
77 style="color: #2271b1; font-weight: 500; text-decoration: underline;"><?php echo esc_html( $fileName ); ?></a>
78 </span>
79 <?php else : ?>
80 <span><?php echo esc_html( $value ); ?></span>
81 <?php endif; ?>
82 </div>
83 <?php
84 }
85 ?>
86 </div>
87 <?php
88 }
89
90 public function renderProductMetaBox( $post ) {
91 $quote = new QuoteRequest( $post );
92 $productId = $quote->getProductId();
93 $quantity = $quote->getQuantity();
94 $price = $quote->getPrice();
95
96 $product = wc_get_product( $productId );
97
98 if ( ! $product ) {
99 ?>
100 <p><?php esc_html_e( 'Product not found.', 'tier-pricing-table' ); ?></p>
101 <?php
102 return;
103 }
104 ?>
105 <table class="tpt-quote-table">
106 <thead>
107 <tr>
108 <th><?php esc_html_e( 'Product', 'tier-pricing-table' ); ?></th>
109 <th><?php esc_html_e( 'Quantity', 'tier-pricing-table' ); ?></th>
110 <th><?php esc_html_e( 'Unit Price', 'tier-pricing-table' ); ?></th>
111 <th><?php esc_html_e( 'Total', 'tier-pricing-table' ); ?></th>
112 </tr>
113 </thead>
114 <tbody>
115 <tr>
116 <td style="display: flex; align-items: center; gap: 12px;">
117 <div style="width: 48px; height: 48px; border-radius: 4px; overflow: hidden; border: 1px solid #e5e5e5; flex-shrink: 0; display: flex; align-items: center; justify-content: center; background: #fff;">
118 <?php echo wp_kses_post( $product->get_image( array( 48, 48 ) ) ); ?>
119 </div>
120 <div>
121 <strong><a href="<?php echo esc_url( get_edit_post_link( $product->get_id() ) ); ?>"
122 target="_blank"><?php echo wp_kses_post( $product->get_name() ); ?></a></strong>
123 <?php if ( $product->get_sku() ) : ?>
124 <div style="font-size: 12px; color: #646970; margin-top: 4px;">
125 <?php esc_html_e( 'SKU:',
126 'tier-pricing-table' ); ?><?php echo esc_html( $product->get_sku() ); ?>
127 </div>
128 <?php endif; ?>
129 </div>
130 </td>
131 <td>
132 <input type="number" min="1" step="1" name="tier_pricing_table_quote_quantity"
133 value="<?php echo esc_attr( $quantity ? $quantity : 1 ); ?>"
134 style="width: 80px;">
135 </td>
136 <td>
137 <input type="number" step="0.01" name="tier_pricing_table_quote_price"
138 value="<?php echo esc_attr( $price ); ?>"
139 style="width: 100px;">
140 </td>
141 <td>
142 <strong>
143 <?php
144 $total = (float) $price * (int) $quantity;
145 echo wp_kses_post( wc_price( $total ) );
146 ?>
147 </strong>
148 </td>
149 </tr>
150 </tbody>
151 </table>
152
153 <div style="margin-top: 20px; padding-top: 15px; border-top: 1px solid #e5e5e5; display: flex; justify-content: flex-end; align-items: center;">
154 <?php if ( $quote->getConvertedOrderId() ) : ?>
155 <p style="margin:0;">
156 <?php esc_html_e( 'Converted to Order:', 'tier-pricing-table' ); ?>
157 <a href="<?php echo esc_url( get_edit_post_link( $quote->getConvertedOrderId() ) ); ?>">
158 <strong>#<?php echo esc_html( $quote->getConvertedOrderId() ); ?></strong>
159 </a>
160 </p>
161 <?php else : ?>
162 <input type="submit" name="tpt_convert_to_order" class="button button-primary"
163 value="<?php esc_attr_e( 'Convert to Order', 'tier-pricing-table' ); ?>">
164 <?php endif; ?>
165 </div>
166 <?php
167 }
168
169 public function renderActionsMetaBox( $post ) {
170 $quote = new QuoteRequest( $post );
171 wp_nonce_field( 'tier_pricing_table_quote_save_product', 'tier_pricing_table_quote_nonce' );
172 ?>
173 <div class="submitbox" id="submitpost">
174 <div id="minor-publishing">
175 <div style="padding: 10px;">
176 <label for="tier_pricing_table_quote_status"
177 style="font-weight: 600; display: block; margin-bottom: 5px;"><?php esc_html_e( 'Status:',
178 'tier-pricing-table' ); ?></label>
179 <select name="tier_pricing_table_quote_status" id="tier_pricing_table_quote_status" style="width: 100%;">
180 <option value="unread" <?php selected( $quote->getStatus(),
181 'unread' ); ?>><?php esc_html_e( 'Unread', 'tier-pricing-table' ); ?></option>
182 <option value="read" <?php selected( $quote->getStatus(), 'read' ); ?>><?php esc_html_e( 'Read',
183 'tier-pricing-table' ); ?></option>
184 <option value="converted" <?php selected( $quote->getStatus(),
185 'converted' ); ?>><?php esc_html_e( 'Converted', 'tier-pricing-table' ); ?></option>
186 <option value="rejected" <?php selected( $quote->getStatus(),
187 'rejected' ); ?>><?php esc_html_e( 'Rejected', 'tier-pricing-table' ); ?></option>
188 </select>
189 </div>
190 <?php
191 $formId = $quote->getMeta( '_form_id' );
192 if ( $formId ) {
193 $form = \TierPricingTable\Addons\RequestAQuote\Models\RequestQuoteForm::get( (string) $formId );
194 if ( $form ) {
195 $formUrl = admin_url( 'admin.php?page=wc-settings&tab=tiered_pricing_table_settings&section=request-a-quote&form_id=' . $formId );
196 ?>
197 <div style="padding: 10px; border-top: 1px solid #dcdcde;">
198 <label style="font-weight: 600; display: block; margin-bottom: 5px;"><?php esc_html_e( 'Submitted via Form:',
199 'tier-pricing-table' ); ?></label>
200 <a href="<?php echo esc_url( $formUrl ); ?>" target="_blank"
201 style="text-decoration: none; font-weight: 500; display: flex; align-items: center; gap: 4px;">
202 <span class="dashicons dashicons-admin-page"
203 style="font-size: 16px; width: 16px; height: 16px;"></span>
204 <?php echo esc_html( $form->getName() ?: __( 'Unnamed Form',
205 'tier-pricing-table' ) ); ?>
206 </a>
207 </div>
208 <?php
209 }
210 }
211 ?>
212 </div>
213 <div id="major-publishing-actions"
214 style="display: flex; justify-content: space-between; align-items: center;">
215 <div id="delete-action">
216 <a class="submitdelete deletion"
217 href="<?php echo get_delete_post_link( $post->ID ); ?>"><?php esc_html_e( 'Move to Trash' ); ?></a>
218 </div>
219 <div id="publishing-action">
220 <span class="spinner"></span>
221 <input type="submit" name="save" id="publish" class="button button-primary button-large"
222 value="<?php esc_attr_e( 'Save Quote', 'tier-pricing-table' ); ?>">
223 </div>
224 </div>
225 </div>
226 <?php
227 }
228
229 public function renderCustomerMetaBox( $post ) {
230 $quote = new QuoteRequest( $post );
231 $userId = $quote->getUserId();
232 $email = $quote->getCustomerEmail();
233 $customFields = $quote->getCustomFields();
234
235 $name = '';
236 $user = null;
237
238 if ( $userId ) {
239 $user = get_userdata( $userId );
240 if ( $user ) {
241 $name = $user->display_name;
242 $email = $user->user_email ?: $email;
243 }
244 }
245
246 if ( ! $name ) {
247 // Try to find name in custom fields
248 foreach ( $customFields as $k => $field ) {
249 $fieldKey = strtolower( $k );
250 if ( strpos( $fieldKey, 'name' ) !== false || strpos( $fieldKey, 'first_name' ) !== false ) {
251 $name = is_array( $field ) ? ( $field['value'] ?? '' ) : $field;
252 break;
253 }
254 }
255 if ( ! $name ) {
256 $name = __( 'Guest', 'tier-pricing-table' );
257 }
258 }
259
260 $avatarUrl = get_avatar_url( $userId ?: $email, array( 'size' => 160 ) );
261 ?>
262 <div class="tpt-quote-customer-widget" style="text-align: center; padding: 10px 0;">
263 <div class="tpt-avatar-wrapper" style="margin-bottom: 15px;">
264 <?php if ( $userId && $user ) : ?>
265 <img src="<?php echo esc_url( $avatarUrl ); ?>" alt="Avatar"
266 style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover;">
267 <?php else : ?>
268 <div style="width: 80px; height: 80px; border-radius: 50%; background: #f0f0f1; display: inline-flex; align-items: center; justify-content: center; margin: 0 auto; border: 1px solid #c3c4c7;">
269 <span class="dashicons dashicons-admin-users"
270 style="font-size: 40px; width: 40px; height: 40px; color: #8c8f94;"></span>
271 </div>
272 <?php endif; ?>
273 </div>
274
275 <div style="font-size: 16px; font-weight: 600; color: #1d2327; margin-bottom: 5px;">
276 <?php echo esc_html( $name ); ?>
277 </div>
278
279 <?php if ( $email ) : ?>
280 <div style="font-size: 13px; color: #50575e; margin-bottom: 20px;">
281 <a href="mailto:<?php echo esc_attr( $email ); ?>"
282 style="text-decoration: none; color: inherit;"><?php echo esc_html( $email ); ?></a>
283 </div>
284 <?php endif; ?>
285
286 <?php if ( $userId && $user ) : ?>
287 <a href="<?php echo esc_url( get_edit_user_link( $userId ) ); ?>" class="button"
288 style="width: 100%; text-align: center; display: block; padding: 4px 0;">
289 <?php esc_html_e( 'View Profile', 'tier-pricing-table' ); ?>
290 </a>
291 <?php else : ?>
292 <div style="background: #f0f0f1; color: #3c434a; padding: 8px; border-radius: 4px; font-weight: 500; text-align: center; border: 1px solid #c3c4c7; display: flex; justify-content: center; align-items: center; gap: 8px;">
293 <span class="dashicons dashicons-admin-users"
294 style="font-size: 18px; line-height: 1; width: 18px; height: 18px; color: #8c8f94;"></span>
295 <span><?php esc_html_e( 'Guest User', 'tier-pricing-table' ); ?></span>
296 </div>
297 <?php endif; ?>
298 </div>
299 <?php
300 }
301
302 public function savePost( $post_id, $post ) {
303 if ( get_post_type( $post_id ) !== QuoteRequestCPT::POST_TYPE ) {
304 return;
305 }
306
307 if ( ! isset( $_POST['tier_pricing_table_quote_nonce'] ) || ! wp_verify_nonce( $_POST['tier_pricing_table_quote_nonce'],
308 'tier_pricing_table_quote_save_product' ) ) {
309 return;
310 }
311
312 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
313 return;
314 }
315
316 if ( ! current_user_can( 'edit_post', $post_id ) ) {
317 return;
318 }
319
320 $quote = new QuoteRequest( $post_id );
321
322 if ( isset( $_POST['tier_pricing_table_quote_price'] ) ) {
323 $quote->setPrice( wc_format_decimal( $_POST['tier_pricing_table_quote_price'] ) );
324 }
325
326 if ( isset( $_POST['tier_pricing_table_quote_quantity'] ) ) {
327 $quote->setQuantity( (int) $_POST['tier_pricing_table_quote_quantity'] );
328 }
329
330 if ( isset( $_POST['tier_pricing_table_quote_status'] ) ) {
331 $quote->setStatus( sanitize_text_field( $_POST['tier_pricing_table_quote_status'] ) );
332 }
333
334 // Handle Conversion to Order
335 if ( isset( $_POST['tpt_convert_to_order'] ) && ! $quote->getConvertedOrderId() ) {
336 $productId = $quote->getProductId();
337 $quantity = $quote->getQuantity();
338 $price = $quote->getPrice();
339
340 $order = wc_create_order();
341 $order->add_product( wc_get_product( $productId ), $quantity, array(
342 'subtotal' => $price * $quantity,
343 'total' => $price * $quantity,
344 ) );
345
346 $order->calculate_totals();
347
348 // Add customer note
349 // Add customer note
350 $customFields = $quote->getCustomFields();
351 $notes = "Quote Request Notes:\n";
352 foreach ( $customFields as $k => $fieldData ) {
353 if ( ! is_array( $fieldData ) ) {
354 $fieldData = array( 'label' => ucfirst( str_replace( '_', ' ', $k ) ), 'value' => $fieldData );
355 }
356 $label = isset( $fieldData['label'] ) && ! empty( $fieldData['label'] ) ? $fieldData['label'] : ucfirst( str_replace( '_',
357 ' ', $k ) );
358 $value = isset( $fieldData['value'] ) ? $fieldData['value'] : '';
359
360 $notes .= $label . ": " . $value . "\n";
361 }
362 $order->update_meta_data( 'quote_request_notes', $notes );
363 $order->save();
364
365 // Update quote
366 remove_action( 'save_post', array( $this, 'savePost' ), 10, 2 );
367
368 $quote->setConvertedOrderId( $order->get_id() );
369 $quote->setStatus( 'converted' );
370 $quote->save();
371
372 add_filter( 'redirect_post_location', function ( $location ) use ( $order ) {
373 return $order->get_edit_order_url();
374 } );
375
376 return;
377 }
378
379 $quote->save();
380 }
381
382 public function setCustomColumns( $columns ) {
383 $columns = array(
384 'cb' => '<input type="checkbox" />',
385 'title' => __( 'Quote', 'tier-pricing-table' ),
386 'customer' => __( 'Customer', 'tier-pricing-table' ),
387 'product' => __( 'Product', 'tier-pricing-table' ),
388 'status' => __( 'Status', 'tier-pricing-table' ),
389 'date' => __( 'Date', 'tier-pricing-table' ),
390 );
391
392 return $columns;
393 }
394
395 public function customColumnData( $column, $post_id ) {
396 $quote = new QuoteRequest( $post_id );
397
398 switch ( $column ) {
399 case 'customer':
400 $name = $quote->getCustomerName();
401 $email = $quote->getCustomerEmail();
402 ?>
403 <?php echo esc_html( $name ); ?><br>
404 <?php if ( $email ) : ?>
405 <a href="mailto:<?php echo esc_attr( $email ); ?>"><?php echo esc_html( $email ); ?></a>
406 <?php endif; ?>
407 <?php
408 break;
409
410 case 'product':
411 $productId = $quote->getProductId();
412 $quantity = $quote->getQuantity();
413
414 $product = wc_get_product( $productId );
415 if ( $product ) :
416 ?>
417 <a href="<?php echo esc_url( get_edit_post_link( $product->get_id() ) ); ?>"><strong><?php echo wp_kses_post( $product->get_name() ); ?></strong></a>
418 <br>
419 <small><?php esc_html_e( 'Qty:',
420 'tier-pricing-table' ); ?><?php echo esc_html( $quantity ? $quantity : 1 ); ?></small>
421 <?php
422 else :
423 echo '&mdash;';
424 endif;
425 break;
426
427 case 'status':
428 $status = $quote->getStatus();
429 $statusLabels = array(
430 'unread' => __( 'Unread', 'tier-pricing-table' ),
431 'read' => __( 'Read', 'tier-pricing-table' ),
432 'converted' => __( 'Converted', 'tier-pricing-table' ),
433 'rejected' => __( 'Rejected', 'tier-pricing-table' ),
434 );
435 $label = isset( $statusLabels[ $status ] ) ? $statusLabels[ $status ] : $status;
436 ?>
437 <mark class="tpt-quote-status status-<?php echo esc_attr( $status ); ?>">
438 <span><?php echo esc_html( $label ); ?></span></mark>
439 <?php
440 break;
441 }
442 }
443
444 public function addProductsFilter() {
445 global $typenow;
446
447 if ( QuoteRequestCPT::POST_TYPE === $typenow ) {
448 wp_enqueue_script( 'wc-enhanced-select' );
449 wp_enqueue_style( 'woocommerce_admin_styles' );
450
451 $selected = isset( $_GET['tpt_product_filter'] ) ? absint( $_GET['tpt_product_filter'] ) : 0;
452 ?>
453 <select name="tpt_product_filter" id="tpt_product_filter" class="wc-product-search" style="width: 250px;"
454 data-allow_clear="true"
455 data-placeholder="<?php esc_attr_e( 'Filter by product', 'tier-pricing-table' ); ?>"
456 data-action="woocommerce_json_search_products_and_variations">
457 <option value=""><?php esc_html_e( 'Show all products', 'tier-pricing-table' ); ?></option>
458 <?php if ( $selected > 0 ) : ?>
459 <?php $product = wc_get_product( $selected ); ?>
460 <?php if ( $product ) : ?>
461 <option value="<?php echo esc_attr( $selected ); ?>"
462 selected="selected"><?php echo esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ); ?></option>
463 <?php endif; ?>
464 <?php endif; ?>
465 </select>
466 <?php
467 }
468 }
469
470 public function filterByProduct( $query ) {
471 global $pagenow;
472
473 if ( ! is_admin() || ! $query->is_main_query() ) {
474 return;
475 }
476
477 if ( 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && QuoteRequestCPT::POST_TYPE === $_GET['post_type'] && isset( $_GET['tpt_product_filter'] ) && $_GET['tpt_product_filter'] > 0 ) {
478 $meta_query = $query->get( 'meta_query' );
479 if ( ! is_array( $meta_query ) ) {
480 $meta_query = array();
481 }
482
483 $meta_query[] = array(
484 'key' => '_product_id',
485 'value' => absint( $_GET['tpt_product_filter'] ),
486 'compare' => '=',
487 );
488
489 $query->set( 'meta_query', $meta_query );
490 }
491 }
492
493 public function registerBulkActions( $bulk_actions ) {
494 $bulk_actions['tpt_mark_unread'] = __( 'Mark as Unread', 'tier-pricing-table' );
495 $bulk_actions['tpt_mark_read'] = __( 'Mark as Read', 'tier-pricing-table' );
496 $bulk_actions['tpt_mark_rejected'] = __( 'Mark as Rejected', 'tier-pricing-table' );
497
498 return $bulk_actions;
499 }
500
501 public function processBulkActions( $redirect_to, $doaction, $post_ids ) {
502 if ( ! in_array( $doaction, array( 'tpt_mark_unread', 'tpt_mark_read', 'tpt_mark_rejected' ) ) ) {
503 return $redirect_to;
504 }
505
506 $changed = 0;
507 foreach ( $post_ids as $post_id ) {
508 $quote = new QuoteRequest( $post_id );
509 if ( 'tpt_mark_unread' === $doaction ) {
510 $quote->setStatus( 'unread' );
511 } elseif ( 'tpt_mark_read' === $doaction ) {
512 $quote->setStatus( 'read' );
513 } elseif ( 'tpt_mark_rejected' === $doaction ) {
514 $quote->setStatus( 'rejected' );
515 }
516 $quote->save();
517 $changed ++;
518 }
519
520 $redirect_to = add_query_arg( 'tpt_bulk_changed', $changed, $redirect_to );
521 $redirect_to = add_query_arg( 'tpt_bulk_action', $doaction, $redirect_to );
522
523 return $redirect_to;
524 }
525
526 public function bulkActionNotices() {
527 if ( ! empty( $_REQUEST['tpt_bulk_changed'] ) && ! empty( $_REQUEST['tpt_bulk_action'] ) ) {
528 $changed = absint( $_REQUEST['tpt_bulk_changed'] );
529 $action = sanitize_text_field( $_REQUEST['tpt_bulk_action'] );
530
531 if ( 'tpt_mark_unread' === $action ) {
532 // translators: %s: number of quotes.
533 $message = sprintf( _n( '%s quote marked as unread.', '%s quotes marked as unread.', $changed,
534 'tier-pricing-table' ), $changed );
535 } elseif ( 'tpt_mark_read' === $action ) {
536 // translators: %s: number of quotes.
537 $message = sprintf( _n( '%s quote marked as read.', '%s quotes marked as read.', $changed,
538 'tier-pricing-table' ), $changed );
539 } elseif ( 'tpt_mark_rejected' === $action ) {
540 // translators: %s: number of quotes.
541 $message = sprintf( _n( '%s quote marked as rejected.', '%s quotes marked as rejected.', $changed,
542 'tier-pricing-table' ), $changed );
543 } else {
544 return;
545 }
546
547 echo '<div id="message" class="updated notice is-dismissible"><p>' . esc_html( $message ) . '</p></div>';
548 }
549 }
550 }