class-bulk-actions-manager.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. // Handles custom bulk actions for orders.
  3. defined('ABSPATH') || exit;
  4. class Bulk_Actions_Manager {
  5. public function __construct() {
  6. add_filter('bulk_actions-woocommerce_page_wc-orders', array($this, 'register_bulk_actions'));
  7. add_filter('handle_bulk_actions-woocommerce_page_wc-orders', array($this, 'handle_bulk_actions'), 10, 3);
  8. }
  9. public function register_bulk_actions($bulk_actions) {
  10. $bulk_actions['prepare_to_printing_export'] = __('Prepare to Printing Export', 'studiou-wc-ord-print-statuses');
  11. $bulk_actions['set_status_to_prepare_to_printing'] = __('Set Status to Prepare to Printing', 'studiou-wc-ord-print-statuses');
  12. $bulk_actions['set_status_to_in_printing'] = __('Set Status to In Printing', 'studiou-wc-ord-print-statuses');
  13. return $bulk_actions;
  14. }
  15. public function handle_bulk_actions($redirect_to, $action, $post_ids) {
  16. $known = array(
  17. 'prepare_to_printing_export',
  18. 'set_status_to_prepare_to_printing',
  19. 'set_status_to_in_printing',
  20. );
  21. if (!in_array($action, $known, true)) {
  22. return $redirect_to;
  23. }
  24. if (!current_user_can('edit_shop_orders')) {
  25. wp_die(esc_html__('You do not have sufficient permissions to perform this action.', 'studiou-wc-ord-print-statuses'));
  26. }
  27. $post_ids = array_filter(array_map('intval', (array) $post_ids));
  28. if (empty($post_ids)) {
  29. return $redirect_to;
  30. }
  31. switch ($action) {
  32. case 'prepare_to_printing_export':
  33. return $this->prepare_to_printing_export($post_ids, $redirect_to);
  34. case 'set_status_to_prepare_to_printing':
  35. return $this->set_status_to_prepare_to_printing($post_ids, $redirect_to);
  36. case 'set_status_to_in_printing':
  37. return $this->set_status_to_in_printing($post_ids, $redirect_to);
  38. }
  39. return $redirect_to;
  40. }
  41. /**
  42. * Atomic order: pull rows, build the CSV in memory, then flip statuses, then
  43. * stream the file. If the export query returns nothing, statuses are still
  44. * advanced (the spec requires it) but the user is told no CSV was produced.
  45. */
  46. private function prepare_to_printing_export($post_ids, $redirect_to) {
  47. $orders_data = Studiou_DB_Manager::get_orders_for_printing($post_ids);
  48. $csv_data = !empty($orders_data) ? $this->generate_csv($orders_data) : '';
  49. $updated = Studiou_DB_Manager::set_orders_to_prepare_printing($post_ids);
  50. UtilsLog::message(
  51. sprintf(
  52. _n(
  53. '%d order moved to "Prepare to Printing".',
  54. '%d orders moved to "Prepare to Printing".',
  55. $updated,
  56. 'studiou-wc-ord-print-statuses'
  57. ),
  58. $updated
  59. ),
  60. 'success'
  61. );
  62. if ($csv_data === '') {
  63. UtilsLog::message(
  64. __('No exportable line items were found for the selected orders. CSV was not generated.', 'studiou-wc-ord-print-statuses'),
  65. 'warning'
  66. );
  67. return $redirect_to;
  68. }
  69. $this->output_csv($csv_data, 'prepare_to_printing_export.csv'); // exits
  70. }
  71. private function set_status_to_prepare_to_printing($post_ids, $redirect_to) {
  72. $updated = Studiou_DB_Manager::set_orders_to_prepare_printing($post_ids);
  73. UtilsLog::message(
  74. sprintf(
  75. _n(
  76. '%d order moved to "Prepare to Printing".',
  77. '%d orders moved to "Prepare to Printing".',
  78. $updated,
  79. 'studiou-wc-ord-print-statuses'
  80. ),
  81. $updated
  82. ),
  83. 'success'
  84. );
  85. return add_query_arg('bulk_action', 'marked_prepare_to_printing', $redirect_to);
  86. }
  87. private function set_status_to_in_printing($post_ids, $redirect_to) {
  88. $updated = Studiou_DB_Manager::set_orders_to_in_printing($post_ids);
  89. UtilsLog::message(
  90. sprintf(
  91. _n(
  92. '%d order moved to "In Printing".',
  93. '%d orders moved to "In Printing".',
  94. $updated,
  95. 'studiou-wc-ord-print-statuses'
  96. ),
  97. $updated
  98. ),
  99. 'success'
  100. );
  101. return add_query_arg('bulk_action', 'marked_in_printing', $redirect_to);
  102. }
  103. private function generate_csv($data) {
  104. $output = fopen('php://temp', 'w+');
  105. fputcsv($output, array_keys((array) $data[0]), ',');
  106. foreach ($data as $row) {
  107. fputcsv($output, (array) $row, ',');
  108. }
  109. rewind($output);
  110. $csv = stream_get_contents($output);
  111. fclose($output);
  112. return $csv;
  113. }
  114. /**
  115. * Stream CSV with UTF-8 BOM so Excel on Windows reads diacritics correctly.
  116. */
  117. private function output_csv($csv_data, $filename) {
  118. if (!headers_sent()) {
  119. nocache_headers();
  120. header('Content-Type: text/csv; charset=utf-8');
  121. header('Content-Disposition: attachment; filename="' . $filename . '"');
  122. }
  123. echo "\xEF\xBB\xBF" . $csv_data; // UTF-8 BOM
  124. exit;
  125. }
  126. }