tab-queue.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <?php
  2. /**
  3. * Queue tab.
  4. *
  5. * @package studiou-wc-mail-queue
  6. * @copyright 2026 QUADARAX
  7. * @author Dalibor Votruba <dvotruba@quadarax.com>
  8. * @license GPL-2.0-or-later
  9. */
  10. defined( 'ABSPATH' ) || exit;
  11. // phpcs:ignore WordPress.Security.NonceVerification.Recommended
  12. $wcmq_filter = isset( $_GET['state'] ) ? sanitize_key( wp_unslash( $_GET['state'] ) ) : '';
  13. if ( ! in_array( $wcmq_filter, array( 'pending', 'sending', 'sent', 'failed' ), true ) ) {
  14. $wcmq_filter = '';
  15. }
  16. $wcmq_paged = Studiou_WCMQ_Admin::current_page();
  17. $wcmq_total = Studiou_WCMQ_DB::count_rows( $wcmq_filter );
  18. $wcmq_offset = ( $wcmq_paged - 1 ) * Studiou_WCMQ_Admin::PER_PAGE;
  19. $wcmq_rows = Studiou_WCMQ_DB::get_rows( $wcmq_filter, Studiou_WCMQ_Admin::PER_PAGE, $wcmq_offset );
  20. $wcmq_states = array(
  21. '' => __( 'All', 'studiou-wc-mail-queue' ),
  22. 'pending' => __( 'Pending', 'studiou-wc-mail-queue' ),
  23. 'sending' => __( 'Sending', 'studiou-wc-mail-queue' ),
  24. 'sent' => __( 'Sent', 'studiou-wc-mail-queue' ),
  25. 'failed' => __( 'Failed', 'studiou-wc-mail-queue' ),
  26. );
  27. ?>
  28. <ul class="subsubsub">
  29. <?php foreach ( $wcmq_states as $wcmq_slug => $wcmq_label ) : ?>
  30. <li>
  31. <a href="<?php echo esc_url( Studiou_WCMQ_Admin::tab_url( 'queue', $wcmq_slug ? array( 'state' => $wcmq_slug ) : array() ) ); ?>"
  32. class="<?php echo $wcmq_filter === $wcmq_slug ? 'current' : ''; ?>">
  33. <?php echo esc_html( $wcmq_label ); ?>
  34. </a>
  35. </li>
  36. <?php endforeach; ?>
  37. </ul>
  38. <div class="clear"></div>
  39. <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" class="studiou-wcmq-queue-form">
  40. <?php wp_nonce_field( Studiou_WCMQ_Admin::NONCE ); ?>
  41. <input type="hidden" name="action" value="studiou_wcmq_queue_action" />
  42. <div class="tablenav top">
  43. <div class="alignleft actions">
  44. <select name="wcmq_action">
  45. <option value=""><?php esc_html_e( 'Bulk actions', 'studiou-wc-mail-queue' ); ?></option>
  46. <option value="retry"><?php esc_html_e( 'Retry now', 'studiou-wc-mail-queue' ); ?></option>
  47. <option value="delete"><?php esc_html_e( 'Delete', 'studiou-wc-mail-queue' ); ?></option>
  48. </select>
  49. <button type="submit" class="button" id="studiou-wcmq-apply"><?php esc_html_e( 'Apply', 'studiou-wc-mail-queue' ); ?></button>
  50. </div>
  51. </div>
  52. <table class="wp-list-table widefat fixed striped">
  53. <thead>
  54. <tr>
  55. <td class="check-column"><input type="checkbox" id="studiou-wcmq-check-all" /></td>
  56. <th><?php esc_html_e( 'ID', 'studiou-wc-mail-queue' ); ?></th>
  57. <th><?php esc_html_e( 'Email type', 'studiou-wc-mail-queue' ); ?></th>
  58. <th><?php esc_html_e( 'Order', 'studiou-wc-mail-queue' ); ?></th>
  59. <th><?php esc_html_e( 'Recipient', 'studiou-wc-mail-queue' ); ?></th>
  60. <th><?php esc_html_e( 'State', 'studiou-wc-mail-queue' ); ?></th>
  61. <th><?php esc_html_e( 'Tries', 'studiou-wc-mail-queue' ); ?></th>
  62. <th><?php esc_html_e( 'Scheduled', 'studiou-wc-mail-queue' ); ?></th>
  63. <th><?php esc_html_e( 'Sent', 'studiou-wc-mail-queue' ); ?></th>
  64. <th><?php esc_html_e( 'Last error', 'studiou-wc-mail-queue' ); ?></th>
  65. </tr>
  66. </thead>
  67. <tbody>
  68. <?php if ( empty( $wcmq_rows ) ) : ?>
  69. <tr><td colspan="10"><?php esc_html_e( 'The queue is empty.', 'studiou-wc-mail-queue' ); ?></td></tr>
  70. <?php else : ?>
  71. <?php foreach ( $wcmq_rows as $wcmq_row ) : ?>
  72. <tr>
  73. <th scope="row" class="check-column">
  74. <input type="checkbox" name="rows[]" value="<?php echo (int) $wcmq_row->id; ?>" />
  75. </th>
  76. <td><?php echo (int) $wcmq_row->id; ?></td>
  77. <td><code><?php echo esc_html( $wcmq_row->context ); ?></code></td>
  78. <td>
  79. <?php
  80. // Never hardcode the HPOS URL: `page=wc-orders` is not a
  81. // registered admin page when order storage is legacy posts.
  82. // WC_Order::get_edit_order_url() resolves both, and returns
  83. // nothing useful for an order deleted since enqueue.
  84. $wcmq_order_id = (int) $wcmq_row->order_id;
  85. $wcmq_edit_url = '';
  86. if ( $wcmq_order_id > 0 && function_exists( 'wc_get_order' ) ) {
  87. $wcmq_order = wc_get_order( $wcmq_order_id );
  88. if ( $wcmq_order instanceof WC_Order ) {
  89. $wcmq_edit_url = $wcmq_order->get_edit_order_url();
  90. }
  91. }
  92. if ( $wcmq_edit_url ) {
  93. printf( '<a href="%s">#%d</a>', esc_url( $wcmq_edit_url ), $wcmq_order_id );
  94. } elseif ( $wcmq_order_id > 0 ) {
  95. // Order no longer exists.
  96. printf( '<span title="%s">#%d</span>', esc_attr__( 'Order no longer exists', 'studiou-wc-mail-queue' ), $wcmq_order_id );
  97. } else {
  98. echo '&mdash;';
  99. }
  100. ?>
  101. </td>
  102. <td><?php echo esc_html( $wcmq_row->recipient ); ?></td>
  103. <td>
  104. <span class="studiou-wcmq-state studiou-wcmq-state-<?php echo esc_attr( $wcmq_row->state ); ?>">
  105. <?php echo esc_html( $wcmq_row->state ); ?>
  106. </span>
  107. </td>
  108. <td>
  109. <?php
  110. echo (int) $wcmq_row->attempts;
  111. if ( (int) $wcmq_row->reclaims > 0 ) {
  112. printf(
  113. ' <abbr title="%s">(+%d)</abbr>',
  114. esc_attr__( 'Crash recoveries', 'studiou-wc-mail-queue' ),
  115. (int) $wcmq_row->reclaims
  116. );
  117. }
  118. ?>
  119. </td>
  120. <td><?php echo wp_kses_post( Studiou_WCMQ_Admin::format_time( $wcmq_row->scheduled_at ) ); ?></td>
  121. <td><?php echo wp_kses_post( Studiou_WCMQ_Admin::format_time( $wcmq_row->sent_at ) ); ?></td>
  122. <td class="studiou-wcmq-error"><?php echo esc_html( (string) $wcmq_row->last_error ); ?></td>
  123. </tr>
  124. <?php endforeach; ?>
  125. <?php endif; ?>
  126. </tbody>
  127. </table>
  128. <?php
  129. Studiou_WCMQ_Admin::render_pagination(
  130. 'queue',
  131. $wcmq_total,
  132. $wcmq_paged,
  133. $wcmq_filter ? array( 'state' => $wcmq_filter ) : array()
  134. );
  135. ?>
  136. </form>