admin-summary.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. if (!defined('WPINC')) {
  3. die;
  4. }
  5. /** @var array $records */
  6. /** @var int $total */
  7. /** @var int $total_pages */
  8. /** @var int $current_page */
  9. /** @var string $current_status */
  10. /** @var int $current_product */
  11. /** @var int $current_order */
  12. /** @var string $current_search */
  13. /** @var int $per_page */
  14. /** @var array $fpp_products */
  15. /** @var string $current_orderby */
  16. /** @var string $current_order_dir */
  17. $base_url = admin_url('edit.php?post_type=product&page=studiou-fpp-summary');
  18. // Build the base filter state that must survive on sort/pagination links
  19. $filter_state = array(
  20. 'post_type' => 'product',
  21. 'page' => 'studiou-fpp-summary',
  22. );
  23. if ($current_status) $filter_state['status'] = $current_status;
  24. if ($current_product) $filter_state['product_id'] = $current_product;
  25. if ($current_order) $filter_state['order_id'] = $current_order;
  26. if ($current_search) $filter_state['s'] = $current_search;
  27. /**
  28. * Produce a <th> cell for a sortable column: toggles asc/desc and preserves filters.
  29. */
  30. $sort_header = function ($column_key, $label) use ($filter_state, $current_orderby, $current_order_dir) {
  31. $is_active = ($current_orderby === $column_key);
  32. $next_dir = ($is_active && $current_order_dir === 'ASC') ? 'DESC' : 'ASC';
  33. if ($is_active && $current_order_dir === 'DESC') {
  34. // If currently DESC, next click should flip to ASC
  35. $next_dir = 'ASC';
  36. } elseif (!$is_active) {
  37. // Fresh click on a non-active column defaults to DESC for date/order, ASC feels odd
  38. $next_dir = ($column_key === 'created_at' || $column_key === 'order_id') ? 'DESC' : 'ASC';
  39. }
  40. $args = $filter_state;
  41. $args['orderby'] = $column_key;
  42. $args['order'] = $next_dir;
  43. $url = add_query_arg($args, admin_url('edit.php'));
  44. $th_class = 'manage-column column-' . esc_attr($column_key) . ' sortable ';
  45. if ($is_active) {
  46. $th_class .= 'sorted ' . strtolower($current_order_dir);
  47. } else {
  48. $th_class .= 'desc';
  49. }
  50. ?>
  51. <th class="<?php echo $th_class; ?>">
  52. <a href="<?php echo esc_url($url); ?>">
  53. <span><?php echo esc_html($label); ?></span>
  54. <span class="sorting-indicator"></span>
  55. </a>
  56. </th>
  57. <?php
  58. };
  59. ?>
  60. <div class="wrap studiou-fpp-admin-wrap">
  61. <h1><?php esc_html_e('Free Photo Files', 'studiou-wc-free-photo-product'); ?></h1>
  62. <div class="studiou-fpp-admin-notice-area"></div>
  63. <!-- Filters -->
  64. <div class="studiou-fpp-filters">
  65. <form method="get" action="<?php echo esc_url(admin_url('edit.php')); ?>">
  66. <input type="hidden" name="post_type" value="product" />
  67. <input type="hidden" name="page" value="studiou-fpp-summary" />
  68. <input type="hidden" name="orderby" value="<?php echo esc_attr($current_orderby); ?>" />
  69. <input type="hidden" name="order" value="<?php echo esc_attr($current_order_dir); ?>" />
  70. <select name="status">
  71. <option value=""><?php esc_html_e('All Statuses', 'studiou-wc-free-photo-product'); ?></option>
  72. <option value="ready" <?php selected($current_status, 'ready'); ?>><?php esc_html_e('Ready', 'studiou-wc-free-photo-product'); ?></option>
  73. <option value="downloaded" <?php selected($current_status, 'downloaded'); ?>><?php esc_html_e('Downloaded', 'studiou-wc-free-photo-product'); ?></option>
  74. <option value="solved" <?php selected($current_status, 'solved'); ?>><?php esc_html_e('Solved', 'studiou-wc-free-photo-product'); ?></option>
  75. </select>
  76. <select name="product_id">
  77. <option value=""><?php esc_html_e('All Products', 'studiou-wc-free-photo-product'); ?></option>
  78. <?php foreach ($fpp_products as $pid => $pname) : ?>
  79. <option value="<?php echo esc_attr($pid); ?>" <?php selected($current_product, $pid); ?>><?php echo esc_html($pname); ?></option>
  80. <?php endforeach; ?>
  81. </select>
  82. <input type="number" name="order_id" min="0" step="1" value="<?php echo $current_order ? esc_attr($current_order) : ''; ?>" placeholder="<?php esc_attr_e('Order #', 'studiou-wc-free-photo-product'); ?>" class="studiou-fpp-filter-order" />
  83. <input type="search" name="s" value="<?php echo esc_attr($current_search); ?>" placeholder="<?php esc_attr_e('Search file name...', 'studiou-wc-free-photo-product'); ?>" />
  84. <button type="submit" class="button"><?php esc_html_e('Filter', 'studiou-wc-free-photo-product'); ?></button>
  85. </form>
  86. </div>
  87. <!-- Bulk actions -->
  88. <div class="studiou-fpp-bulk-actions">
  89. <select id="studiou-fpp-bulk-action">
  90. <option value=""><?php esc_html_e('Bulk Actions', 'studiou-wc-free-photo-product'); ?></option>
  91. <option value="download_zip"><?php esc_html_e('Download ZIP', 'studiou-wc-free-photo-product'); ?></option>
  92. <option value="download_csv"><?php esc_html_e('Download as CSV', 'studiou-wc-free-photo-product'); ?></option>
  93. <option value="status_ready"><?php esc_html_e('Set Status: Ready', 'studiou-wc-free-photo-product'); ?></option>
  94. <option value="status_downloaded"><?php esc_html_e('Set Status: Downloaded', 'studiou-wc-free-photo-product'); ?></option>
  95. <option value="status_solved"><?php esc_html_e('Set Status: Solved', 'studiou-wc-free-photo-product'); ?></option>
  96. <option value="delete"><?php esc_html_e('Delete', 'studiou-wc-free-photo-product'); ?></option>
  97. </select>
  98. <button type="button" class="button" id="studiou-fpp-bulk-apply"><?php esc_html_e('Apply', 'studiou-wc-free-photo-product'); ?></button>
  99. <span class="spinner" id="studiou-fpp-bulk-spinner"></span>
  100. <span class="studiou-fpp-total-count">
  101. <?php echo esc_html(sprintf(
  102. _n('%d file', '%d files', $total, 'studiou-wc-free-photo-product'),
  103. $total
  104. )); ?>
  105. </span>
  106. </div>
  107. <!-- Files table -->
  108. <table class="wp-list-table widefat fixed striped studiou-fpp-files-table">
  109. <thead>
  110. <tr>
  111. <td class="manage-column column-cb check-column">
  112. <input type="checkbox" id="studiou-fpp-select-all" />
  113. </td>
  114. <th class="column-thumbnail"><?php esc_html_e('Preview', 'studiou-wc-free-photo-product'); ?></th>
  115. <th class="column-filename"><?php esc_html_e('File Name', 'studiou-wc-free-photo-product'); ?></th>
  116. <th class="column-product"><?php esc_html_e('Product', 'studiou-wc-free-photo-product'); ?></th>
  117. <?php $sort_header('order_id', __('Order', 'studiou-wc-free-photo-product')); ?>
  118. <th class="column-customer"><?php esc_html_e('Customer', 'studiou-wc-free-photo-product'); ?></th>
  119. <?php $sort_header('status', __('Status', 'studiou-wc-free-photo-product')); ?>
  120. <?php $sort_header('created_at', __('Date', 'studiou-wc-free-photo-product')); ?>
  121. <th class="column-actions"><?php esc_html_e('Actions', 'studiou-wc-free-photo-product'); ?></th>
  122. </tr>
  123. </thead>
  124. <tbody>
  125. <?php if (empty($records)) : ?>
  126. <tr>
  127. <td colspan="9"><?php esc_html_e('No files found.', 'studiou-wc-free-photo-product'); ?></td>
  128. </tr>
  129. <?php else : ?>
  130. <?php foreach ($records as $record) :
  131. $attachment_url = wp_get_attachment_url($record->attachment_id);
  132. $thumb = wp_get_attachment_image_src($record->attachment_id, 'thumbnail');
  133. $thumb_url = $thumb ? $thumb[0] : wp_mime_type_icon($record->attachment_id);
  134. $product_title = get_the_title($record->product_id);
  135. $customer_name = '';
  136. if ($record->customer_id > 0) {
  137. $user = get_userdata($record->customer_id);
  138. $customer_name = $user ? $user->display_name : '#' . $record->customer_id;
  139. } else {
  140. $customer_name = __('Guest', 'studiou-wc-free-photo-product');
  141. }
  142. $order_link = '';
  143. if ($record->order_id > 0) {
  144. $order_url = Studiou_WC_FPP_Admin::get_order_edit_url($record->order_id);
  145. $order_link = '<a href="' . esc_url($order_url) . '">#' . esc_html($record->order_id) . '</a>';
  146. } else {
  147. $order_link = '<span class="studiou-fpp-no-order">—</span>';
  148. }
  149. // Download URL that also marks file as downloaded
  150. $download_url = add_query_arg(array(
  151. 'studiou_fpp_download_file' => 1,
  152. 'file_record_id' => $record->id,
  153. 'attachment_id' => $record->attachment_id,
  154. '_wpnonce' => wp_create_nonce('studiou-fpp-download-file'),
  155. ), admin_url('admin.php'));
  156. ?>
  157. <tr data-file-id="<?php echo esc_attr($record->id); ?>">
  158. <th scope="row" class="check-column">
  159. <input type="checkbox" class="studiou-fpp-file-cb" value="<?php echo esc_attr($record->id); ?>" />
  160. </th>
  161. <td class="column-thumbnail">
  162. <img src="<?php echo esc_url($thumb_url); ?>" alt="" class="studiou-fpp-thumb" />
  163. </td>
  164. <td class="column-filename">
  165. <?php if ($attachment_url) : ?>
  166. <a href="<?php echo esc_url($attachment_url); ?>" target="_blank"><?php echo esc_html($record->file_name); ?></a>
  167. <?php else : ?>
  168. <?php echo esc_html($record->file_name); ?>
  169. <?php endif; ?>
  170. </td>
  171. <td class="column-product">
  172. <a href="<?php echo esc_url(get_edit_post_link($record->product_id)); ?>"><?php echo esc_html($product_title); ?></a>
  173. </td>
  174. <td class="column-order">
  175. <?php echo $order_link; ?>
  176. </td>
  177. <td class="column-customer">
  178. <?php echo esc_html($customer_name); ?>
  179. </td>
  180. <td class="column-status">
  181. <select class="studiou-fpp-status-select" data-file-id="<?php echo esc_attr($record->id); ?>">
  182. <option value="ready" <?php selected($record->status, 'ready'); ?>><?php esc_html_e('Ready', 'studiou-wc-free-photo-product'); ?></option>
  183. <option value="downloaded" <?php selected($record->status, 'downloaded'); ?>><?php esc_html_e('Downloaded', 'studiou-wc-free-photo-product'); ?></option>
  184. <option value="solved" <?php selected($record->status, 'solved'); ?>><?php esc_html_e('Solved', 'studiou-wc-free-photo-product'); ?></option>
  185. </select>
  186. </td>
  187. <td class="column-date">
  188. <?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($record->created_at))); ?>
  189. </td>
  190. <td class="column-actions">
  191. <?php if ($attachment_url) : ?>
  192. <a href="<?php echo esc_url($download_url); ?>" class="button button-small" title="<?php esc_attr_e('Download', 'studiou-wc-free-photo-product'); ?>">
  193. <span class="dashicons dashicons-download" style="line-height:1.4;"></span>
  194. </a>
  195. <?php endif; ?>
  196. <button type="button" class="button button-small studiou-fpp-delete-single" data-file-id="<?php echo esc_attr($record->id); ?>" title="<?php esc_attr_e('Delete', 'studiou-wc-free-photo-product'); ?>">
  197. <span class="dashicons dashicons-trash" style="line-height:1.4;color:#b32d2e;"></span>
  198. </button>
  199. </td>
  200. </tr>
  201. <?php endforeach; ?>
  202. <?php endif; ?>
  203. </tbody>
  204. </table>
  205. <!-- Pagination -->
  206. <?php if ($total_pages > 1) : ?>
  207. <div class="tablenav bottom">
  208. <div class="tablenav-pages">
  209. <span class="displaying-num">
  210. <?php echo esc_html(sprintf(
  211. _n('%d file', '%d files', $total, 'studiou-wc-free-photo-product'),
  212. $total
  213. )); ?>
  214. </span>
  215. <?php
  216. // Preserve filters + active sort across pagination
  217. $pagination_args = $filter_state;
  218. $pagination_args['orderby'] = $current_orderby;
  219. $pagination_args['order'] = $current_order_dir;
  220. $pagination = paginate_links(array(
  221. 'base' => add_query_arg('paged', '%#%', admin_url('edit.php?' . http_build_query($pagination_args))),
  222. 'format' => '',
  223. 'current' => $current_page,
  224. 'total' => $total_pages,
  225. 'prev_text' => '&laquo;',
  226. 'next_text' => '&raquo;',
  227. ));
  228. if ($pagination) {
  229. echo $pagination;
  230. }
  231. ?>
  232. </div>
  233. </div>
  234. <?php endif; ?>
  235. </div>