class-wc-admin-webhooks-table-list.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. <?php
  2. /**
  3. * WooCommerce Webhooks Table List
  4. *
  5. * @package WooCommerce\Admin
  6. * @version 3.3.0
  7. */
  8. defined( 'ABSPATH' ) || exit;
  9. if ( ! class_exists( 'WP_List_Table' ) ) {
  10. require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
  11. }
  12. /**
  13. * Webooks table list class.
  14. */
  15. class WC_Admin_Webhooks_Table_List extends WP_List_Table {
  16. /**
  17. * Initialize the webhook table list.
  18. */
  19. public function __construct() {
  20. parent::__construct(
  21. array(
  22. 'singular' => 'webhook',
  23. 'plural' => 'webhooks',
  24. 'ajax' => false,
  25. )
  26. );
  27. }
  28. /**
  29. * No items found text.
  30. */
  31. public function no_items() {
  32. esc_html_e( 'No webhooks found.', 'woocommerce' );
  33. }
  34. /**
  35. * Get list columns.
  36. *
  37. * @return array
  38. */
  39. public function get_columns() {
  40. return array(
  41. 'cb' => '<input type="checkbox" />',
  42. 'title' => __( 'Name', 'woocommerce' ),
  43. 'status' => __( 'Status', 'woocommerce' ),
  44. 'topic' => __( 'Topic', 'woocommerce' ),
  45. 'delivery_url' => __( 'Delivery URL', 'woocommerce' ),
  46. );
  47. }
  48. /**
  49. * Column cb.
  50. *
  51. * @param WC_Webhook $webhook Webhook instance.
  52. * @return string
  53. */
  54. public function column_cb( $webhook ) {
  55. return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', $this->_args['singular'], $webhook->get_id() );
  56. }
  57. /**
  58. * Return title column.
  59. *
  60. * @param WC_Webhook $webhook Webhook instance.
  61. * @return string
  62. */
  63. public function column_title( $webhook ) {
  64. $edit_link = admin_url( 'admin.php?page=wc-settings&amp;tab=advanced&amp;section=webhooks&amp;edit-webhook=' . $webhook->get_id() );
  65. $output = '';
  66. // Title.
  67. $output .= '<strong><a href="' . esc_url( $edit_link ) . '" class="row-title">' . esc_html( $webhook->get_name() ) . '</a></strong>';
  68. // Get actions.
  69. $actions = array(
  70. /* translators: %s: webhook ID. */
  71. 'id' => sprintf( __( 'ID: %d', 'woocommerce' ), $webhook->get_id() ),
  72. 'edit' => '<a href="' . esc_url( $edit_link ) . '">' . esc_html__( 'Edit', 'woocommerce' ) . '</a>',
  73. /* translators: %s: webhook name */
  74. 'delete' => '<a class="submitdelete" aria-label="' . esc_attr( sprintf( __( 'Delete "%s" permanently', 'woocommerce' ), $webhook->get_name() ) ) . '" href="' . esc_url(
  75. wp_nonce_url(
  76. add_query_arg(
  77. array(
  78. 'delete' => $webhook->get_id(),
  79. ), admin_url( 'admin.php?page=wc-settings&tab=advanced&section=webhooks' )
  80. ), 'delete-webhook'
  81. )
  82. ) . '">' . esc_html__( 'Delete permanently', 'woocommerce' ) . '</a>',
  83. );
  84. $actions = apply_filters( 'webhook_row_actions', $actions, $webhook );
  85. $row_actions = array();
  86. foreach ( $actions as $action => $link ) {
  87. $row_actions[] = '<span class="' . esc_attr( $action ) . '">' . $link . '</span>';
  88. }
  89. $output .= '<div class="row-actions">' . implode( ' | ', $row_actions ) . '</div>';
  90. return $output;
  91. }
  92. /**
  93. * Return status column.
  94. *
  95. * @param WC_Webhook $webhook Webhook instance.
  96. * @return string
  97. */
  98. public function column_status( $webhook ) {
  99. return $webhook->get_i18n_status();
  100. }
  101. /**
  102. * Return topic column.
  103. *
  104. * @param WC_Webhook $webhook Webhook instance.
  105. * @return string
  106. */
  107. public function column_topic( $webhook ) {
  108. return $webhook->get_topic();
  109. }
  110. /**
  111. * Return delivery URL column.
  112. *
  113. * @param WC_Webhook $webhook Webhook instance.
  114. * @return string
  115. */
  116. public function column_delivery_url( $webhook ) {
  117. return $webhook->get_delivery_url();
  118. }
  119. /**
  120. * Get the status label for webhooks.
  121. *
  122. * @param string $status_name Status name.
  123. * @param int $amount Amount of webhooks.
  124. * @return array
  125. */
  126. private function get_status_label( $status_name, $amount ) {
  127. $statuses = wc_get_webhook_statuses();
  128. if ( isset( $statuses[ $status_name ] ) ) {
  129. return array(
  130. 'singular' => sprintf( '%s <span class="count">(%s)</span>', esc_html( $statuses[ $status_name ] ), $amount ),
  131. 'plural' => sprintf( '%s <span class="count">(%s)</span>', esc_html( $statuses[ $status_name ] ), $amount ),
  132. 'context' => '',
  133. 'domain' => 'woocommerce',
  134. );
  135. }
  136. return array(
  137. 'singular' => sprintf( '%s <span class="count">(%s)</span>', esc_html( $status_name ), $amount ),
  138. 'plural' => sprintf( '%s <span class="count">(%s)</span>', esc_html( $status_name ), $amount ),
  139. 'context' => '',
  140. 'domain' => 'woocommerce',
  141. );
  142. }
  143. /**
  144. * Table list views.
  145. *
  146. * @return array
  147. */
  148. protected function get_views() {
  149. $status_links = array();
  150. $data_store = WC_Data_Store::load( 'webhook' );
  151. $num_webhooks = $data_store->get_count_webhooks_by_status();
  152. $total_webhooks = array_sum( (array) $num_webhooks );
  153. $statuses = array_keys( wc_get_webhook_statuses() );
  154. $class = empty( $_REQUEST['status'] ) ? ' class="current"' : ''; // WPCS: input var okay. CSRF ok.
  155. /* translators: %s: count */
  156. $status_links['all'] = "<a href='admin.php?page=wc-settings&amp;tab=advanced&amp;section=webhooks'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_webhooks, 'posts', 'woocommerce' ), number_format_i18n( $total_webhooks ) ) . '</a>';
  157. foreach ( $statuses as $status_name ) {
  158. $class = '';
  159. if ( empty( $num_webhooks[ $status_name ] ) ) {
  160. continue;
  161. }
  162. if ( isset( $_REQUEST['status'] ) && sanitize_key( wp_unslash( $_REQUEST['status'] ) ) === $status_name ) { // WPCS: input var okay, CSRF ok.
  163. $class = ' class="current"';
  164. }
  165. $label = $this->get_status_label( $status_name, $num_webhooks[ $status_name ] );
  166. $status_links[ $status_name ] = "<a href='admin.php?page=wc-settings&amp;tab=advanced&amp;section=webhooks&amp;status=$status_name'$class>" . sprintf( translate_nooped_plural( $label, $num_webhooks[ $status_name ] ), number_format_i18n( $num_webhooks[ $status_name ] ) ) . '</a>';
  167. }
  168. return $status_links;
  169. }
  170. /**
  171. * Get bulk actions.
  172. *
  173. * @return array
  174. */
  175. protected function get_bulk_actions() {
  176. return array(
  177. 'delete' => __( 'Delete permanently', 'woocommerce' ),
  178. );
  179. }
  180. /**
  181. * Process bulk actions.
  182. */
  183. public function process_bulk_action() {
  184. $action = $this->current_action();
  185. $webhooks = isset( $_REQUEST['webhook'] ) ? array_map( 'absint', (array) $_REQUEST['webhook'] ) : array(); // WPCS: input var okay, CSRF ok.
  186. if ( ! current_user_can( 'manage_woocommerce' ) ) {
  187. wp_die( esc_html__( 'You do not have permission to edit Webhooks', 'woocommerce' ) );
  188. }
  189. if ( 'delete' === $action ) {
  190. WC_Admin_Webhooks::bulk_delete( $webhooks );
  191. }
  192. }
  193. /**
  194. * Generate the table navigation above or below the table.
  195. * Included to remove extra nonce input.
  196. *
  197. * @param string $which The location of the extra table nav markup: 'top' or 'bottom'.
  198. */
  199. protected function display_tablenav( $which ) {
  200. echo '<div class="tablenav ' . esc_attr( $which ) . '">';
  201. if ( $this->has_items() ) {
  202. echo '<div class="alignleft actions bulkactions">';
  203. $this->bulk_actions( $which );
  204. echo '</div>';
  205. }
  206. $this->extra_tablenav( $which );
  207. $this->pagination( $which );
  208. echo '<br class="clear" />';
  209. echo '</div>';
  210. }
  211. /**
  212. * Search box.
  213. *
  214. * @param string $text Button text.
  215. * @param string $input_id Input ID.
  216. */
  217. public function search_box( $text, $input_id ) {
  218. if ( empty( $_REQUEST['s'] ) && ! $this->has_items() ) { // WPCS: input var okay, CSRF ok.
  219. return;
  220. }
  221. $input_id = $input_id . '-search-input';
  222. $search_query = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : ''; // WPCS: input var okay, CSRF ok.
  223. echo '<p class="search-box">';
  224. echo '<label class="screen-reader-text" for="' . esc_attr( $input_id ) . '">' . esc_html( $text ) . ':</label>';
  225. echo '<input type="search" id="' . esc_attr( $input_id ) . '" name="s" value="' . esc_attr( $search_query ) . '" />';
  226. submit_button(
  227. $text, '', '', false,
  228. array(
  229. 'id' => 'search-submit',
  230. )
  231. );
  232. echo '</p>';
  233. }
  234. /**
  235. * Prepare table list items.
  236. */
  237. public function prepare_items() {
  238. $per_page = $this->get_items_per_page( 'woocommerce_webhooks_per_page' );
  239. $current_page = $this->get_pagenum();
  240. // Query args.
  241. $args = array(
  242. 'limit' => $per_page,
  243. 'offset' => $per_page * ( $current_page - 1 ),
  244. );
  245. // Handle the status query.
  246. if ( ! empty( $_REQUEST['status'] ) ) { // WPCS: input var okay, CSRF ok.
  247. $args['status'] = sanitize_key( wp_unslash( $_REQUEST['status'] ) ); // WPCS: input var okay, CSRF ok.
  248. }
  249. if ( ! empty( $_REQUEST['s'] ) ) { // WPCS: input var okay, CSRF ok.
  250. $args['search'] = sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ); // WPCS: input var okay, CSRF ok.
  251. }
  252. // Get the webhooks.
  253. $data_store = WC_Data_Store::load( 'webhook' );
  254. $webhooks = $data_store->search_webhooks( $args );
  255. $this->items = array_map( 'wc_get_webhook', $webhooks );
  256. // Get total items.
  257. $args['limit'] = -1;
  258. $args['offset'] = 0;
  259. $total_items = count( $data_store->search_webhooks( $args ) );
  260. // Set the pagination.
  261. $this->set_pagination_args(
  262. array(
  263. 'total_items' => $total_items,
  264. 'per_page' => $per_page,
  265. 'total_pages' => ceil( $total_items / $per_page ),
  266. )
  267. );
  268. }
  269. }