PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/the-events-calendar/vendor/tickets/src/Tribe/Attendees_Table.php

https://gitlab.com/ezgonzalez/integral
PHP | 496 lines | 255 code | 74 blank | 167 comment | 30 complexity | fca391d479d212f4dcf7a5f2945c3262 MD5 | raw file
  1. <?php
  2. if ( ! class_exists( 'WP_List_Table' ) ) {
  3. require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
  4. }
  5. /**
  6. * Class Tribe__Tickets__Attendees_Table
  7. *
  8. * See documentation for WP_List_Table
  9. */
  10. class Tribe__Tickets__Attendees_Table extends WP_List_Table {
  11. // Store a possible Event
  12. public $event = false;
  13. /**
  14. * Class constructor
  15. *
  16. * @param array $args additional arguments/overrides
  17. *
  18. * @see WP_List_Table::__construct()
  19. */
  20. public function __construct( $args = array() ) {
  21. $args = wp_parse_args( $args, array(
  22. 'singular' => 'attendee',
  23. 'plural' => 'attendees',
  24. 'ajax' => true,
  25. ) );
  26. // Fetch the event Object
  27. if ( ! empty( $_GET['event_id'] ) ) {
  28. $this->event = get_post( $_GET['event_id'] );
  29. }
  30. parent::__construct( apply_filters( 'tribe_events_tickets_attendees_table_args', $args ) );
  31. }
  32. /**
  33. * Display the search box.
  34. * We don't want Core's search box, because we implemented our own jQuery based filter,
  35. * so this function overrides the parent's one and returns empty.
  36. *
  37. * @param string $text The search button text
  38. * @param string $input_id The search input id
  39. */
  40. public function search_box( $text, $input_id ) {
  41. return;
  42. }
  43. /**
  44. * Display the pagination.
  45. * We are not paginating the attendee list, so it returns empty.
  46. */
  47. public function pagination( $which ) {
  48. return '';
  49. }
  50. /**
  51. * Checks the current user's permissions
  52. */
  53. public function ajax_user_can() {
  54. return current_user_can( get_post_type_object( $this->screen->post_type )->cap->edit_posts );
  55. }
  56. /**
  57. * Get a list of columns. The format is:
  58. * 'internal-name' => 'Title'
  59. *
  60. * @return array
  61. */
  62. public function get_columns() {
  63. $columns = array(
  64. 'cb' => '<input type="checkbox" />',
  65. 'order_id' => esc_html__( 'Order #', 'event-tickets' ),
  66. 'order_status' => esc_html__( 'Order Status', 'event-tickets' ),
  67. 'purchaser_name' => esc_html__( 'Purchaser name', 'event-tickets' ),
  68. 'purchaser_email' => esc_html__( 'Purchaser email', 'event-tickets' ),
  69. 'ticket' => esc_html__( 'Ticket type', 'event-tickets' ),
  70. 'attendee_id' => esc_html__( 'Ticket #', 'event-tickets' ),
  71. 'security' => esc_html__( 'Security Code', 'event-tickets' ),
  72. 'check_in' => esc_html__( 'Check in', 'event-tickets' ),
  73. );
  74. return $columns;
  75. }
  76. /**
  77. * Handler for the columns that don't have a specific column_{name} handler function.
  78. *
  79. * @param $item
  80. * @param $column
  81. *
  82. * @return string
  83. */
  84. public function column_default( $item, $column ) {
  85. $value = empty( $item[ $column ] ) ? '' : $item[ $column ];
  86. return apply_filters( 'tribe_events_tickets_attendees_table_column', $value, $item, $column );
  87. }
  88. /**
  89. * Handler for the ticket number column
  90. *
  91. * @param array $item
  92. *
  93. * @return int|string
  94. */
  95. public function column_attendee_id( $item ) {
  96. $attendee_id = empty( $item['attendee_id'] ) ? '' : $item['attendee_id'];
  97. if ( $attendee_id === '' ) {
  98. return '';
  99. }
  100. $unique_id = get_post_meta( $attendee_id, '_unique_id', true );
  101. if ( $unique_id === '' ) {
  102. $unique_id = $attendee_id;
  103. }
  104. /**
  105. * Filters the ticket number; defaults to the ticket unique ID.
  106. *
  107. * @param string $unique_id A unique string identifier for the ticket.
  108. * @param array $item The item entry.
  109. */
  110. return apply_filters( 'tribe_events_tickets_attendees_table_attendee_id_column', $unique_id, $item );
  111. }
  112. /**
  113. * Handler for the checkbox column
  114. *
  115. * @param $item
  116. *
  117. * @return string
  118. */
  119. public function column_cb( $item ) {
  120. return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', esc_attr( $this->_args['singular'] ), esc_attr( $item['attendee_id'] . '|' . $item['provider'] ) );
  121. }
  122. /**
  123. * Handler for the order id column
  124. *
  125. * @param $item
  126. *
  127. * @return string
  128. */
  129. public function column_order_id( $item ) {
  130. //back compat
  131. if ( empty( $item['order_id_link'] ) ) {
  132. $item['order_id_link'] = sprintf( '<a class="row-title" href="%s">%s</a>', esc_url( get_edit_post_link( $item['order_id'], true ) ), esc_html( $item['order_id'] ) );
  133. }
  134. return $item['order_id_link'];
  135. }
  136. /**
  137. * Handler for the order status column
  138. *
  139. * @param $item
  140. *
  141. * @return string
  142. */
  143. public function column_order_status( $item ) {
  144. $icon = '';
  145. $warning = false;
  146. // Check if the order_warning flag has been set (to indicate the order has been cancelled, refunded etc)
  147. if ( isset( $item['order_warning'] ) && $item['order_warning'] ) {
  148. $warning = true;
  149. }
  150. // If the warning flag is set, add the appropriate icon
  151. if ( $warning ) {
  152. $icon = sprintf( "<span class='warning'><img src='%s'/></span> ", esc_url( Tribe__Tickets__Main::instance()->plugin_url . 'src/resources/images/warning.png' ) );
  153. }
  154. // Look for an order_status_label, fall back on the actual order_status string @todo remove fallback in 3.4.3
  155. if ( empty( $item['order_status'] ) ) {
  156. $item['order_status'] = '';
  157. }
  158. $label = isset( $item['order_status_label'] ) ? $item['order_status_label'] : ucwords( $item['order_status'] );
  159. return $icon . $label;
  160. }
  161. /**
  162. * Handler for the ticket column
  163. *
  164. * @since 4.1
  165. *
  166. * @param array $item Item whose ticket data should be output
  167. *
  168. * @return string
  169. */
  170. public function column_ticket( $item ) {
  171. ob_start();
  172. ?>
  173. <div class="event-tickets-ticket-name">
  174. <?php echo esc_html( $item['ticket'] ); ?>
  175. </div>
  176. <?php
  177. /**
  178. * Hook to allow for the insertion of additional content in the ticket table cell
  179. *
  180. * @var $item Attendee row item
  181. */
  182. do_action( 'event_tickets_attendees_table_ticket_column', $item );
  183. $output = ob_get_clean();
  184. return $output;
  185. }
  186. /**
  187. * Handler for the check in column
  188. *
  189. * @param $item
  190. *
  191. * @return string
  192. */
  193. public function column_check_in( $item ) {
  194. $default_checkin_stati = array();
  195. $provider = $item['provider_slug'];
  196. $order_id = $item['order_id'];
  197. /**
  198. * Filters the order stati that will allow for a ticket to be checked in for all commerce providers.
  199. *
  200. * @since 4.1
  201. *
  202. * @param array $default_checkin_stati An array of default order stati that will make a ticket eligible for check-in.
  203. * @param string $provider The ticket provider slug.
  204. * @param int $order_id The order post ID.
  205. */
  206. $check_in_stati = apply_filters( 'event_tickets_attendees_checkin_stati', $default_checkin_stati, $provider, $order_id );
  207. /**
  208. * Filters the order stati that will allow for a ticket to be checked in for a specific commerce provider.
  209. *
  210. * @since 4.1
  211. *
  212. * @param array $default_checkin_stati An array of default order stati that will make a ticket eligible for check-in.
  213. * @param int $order_id The order post ID.
  214. */
  215. $check_in_stati = apply_filters( "event_tickets_attendees_{$provider}_checkin_stati", $check_in_stati, $order_id );
  216. if (
  217. ! empty( $item['order_status'] )
  218. && ! empty( $item['order_id_link_src'] )
  219. && is_array( $check_in_stati )
  220. && ! in_array( $item['order_status'], $check_in_stati )
  221. ) {
  222. $button_template = '<a href="%s" class="button-secondary tickets-checkin">%s</a>';
  223. return sprintf( $button_template, $item['order_id_link_src'], __( 'View order', 'event-tickets' ) );
  224. }
  225. if ( empty( $this->event ) ) {
  226. $checkin = sprintf( '<a href="#" data-attendee-id="%d" data-provider="%s" class="button-secondary tickets_checkin">%s</a>', esc_attr( $item['attendee_id'] ), esc_attr( $item['provider'] ), esc_html__( 'Check in', 'event-tickets' ) );
  227. $uncheckin = sprintf( '<span class="delete"><a href="#" data-attendee-id="%d" data-provider="%s" class="tickets_uncheckin">%s</a></span>', esc_attr( $item['attendee_id'] ), esc_attr( $item['provider'] ), esc_html__( 'Undo Check in', 'event-tickets' ) );
  228. } else {
  229. // add the additional `data-event-id` attribute if this is an event
  230. $checkin = sprintf( '<a href="#" data-attendee-id="%d" data-event-id="%d" data-provider="%s" class="button-secondary tickets_checkin">%s</a>', esc_attr( $item['attendee_id'] ), esc_attr($this->event->ID), esc_attr( $item['provider'] ), esc_html__( 'Check in', 'event-tickets' ) );
  231. $uncheckin = sprintf( '<span class="delete"><a href="#" data-attendee-id="%d" data-event-id="%d" data-provider="%s" class="tickets_uncheckin">%s</a></span>', esc_attr( $item['attendee_id'] ), esc_attr($this->event->ID), esc_attr( $item['provider'] ), esc_html__( 'Undo Check in', 'event-tickets' ) );
  232. }
  233. return $checkin . $uncheckin;
  234. }
  235. /**
  236. * Generates content for a single row of the table
  237. *
  238. * @param object $item The current item
  239. */
  240. public function single_row( $item ) {
  241. static $row_class = '';
  242. $row_class = ( $row_class == '' ? ' alternate ' : '' );
  243. $checked = '';
  244. if ( intval( $item['check_in'] ) === 1 ) {
  245. $checked = ' tickets_checked ';
  246. }
  247. echo '<tr class="' . sanitize_html_class( $row_class ) . esc_attr( $checked ) . '">';
  248. $this->single_row_columns( $item );
  249. echo '</tr>';
  250. /**
  251. * Hook to allow for the insertion of data after an attendee table row
  252. *
  253. * @var $item Attendee data
  254. */
  255. do_action( 'event_tickets_attendees_table_after_row', $item );
  256. }
  257. /**
  258. * Extra controls to be displayed between bulk actions and pagination.
  259. *
  260. * Used for the Print, Email and Export buttons, and for the jQuery based search.
  261. *
  262. * @param string $which (top|bottom)
  263. * @see WP_List_Table::display()
  264. */
  265. public function extra_tablenav( $which ) {
  266. $export_url = add_query_arg(
  267. array(
  268. 'attendees_csv' => true,
  269. 'attendees_csv_nonce' => wp_create_nonce( 'attendees_csv_nonce' ),
  270. )
  271. );
  272. /**
  273. * Include TB_iframe JS
  274. */
  275. add_thickbox();
  276. $email_link = Tribe__Settings::instance()->get_url( array(
  277. 'page' => 'tickets-attendees',
  278. 'action' => 'email',
  279. 'event_id' => $this->event->ID,
  280. 'TB_iframe' => true,
  281. 'width' => 410,
  282. 'height' => 300,
  283. 'parent' => 'admin.php',
  284. ) );
  285. $nav = array(
  286. 'left' => array(
  287. 'print' => sprintf( '<input type="button" name="print" class="print button action" value="%s">', esc_attr__( 'Print', 'event-tickets' ) ),
  288. 'email' => '<a class="email button action thickbox" href="' . esc_url( $email_link ) . '">' . esc_attr__( 'Email', 'event-tickets' ) . '</a>',
  289. 'export' => sprintf( '<a href="%s" class="export button action">%s</a>', esc_url( $export_url ), esc_html__( 'Export', 'event-tickets' ) ),
  290. ),
  291. 'right' => array(),
  292. );
  293. if ( 'top' == $which ) {
  294. $nav['right']['filter_box'] = sprintf( '%s: <input type="text" name="filter_attendee" id="filter_attendee" value="">', esc_html__( 'Filter by purchaser name, ticket #, order # or security code', 'event-tickets' ) );
  295. }
  296. $nav = apply_filters( 'tribe_events_tickets_attendees_table_nav', $nav, $which );
  297. ?>
  298. <div class="alignleft actions"><?php echo implode( $nav['left'] ); ?></div>
  299. <div class="alignright"><?php echo implode( $nav['right'] ) ?></div>
  300. <?php
  301. }
  302. /**
  303. * Get an associative array ( option_name => option_title ) with the list
  304. * of bulk actions available on this table.
  305. *
  306. * @return array
  307. */
  308. public function get_bulk_actions() {
  309. $actions = array(
  310. 'check_in' => esc_attr__( 'Check in', 'event-tickets' ),
  311. 'uncheck_in' => esc_attr__( 'Undo Check in', 'event-tickets' ),
  312. 'delete_attendee' => esc_attr__( 'Delete', 'event-tickets' ),
  313. );
  314. return (array) apply_filters( 'tribe_events_tickets_attendees_table_bulk_actions', $actions );
  315. }
  316. /**
  317. * Handler for the different bulk actions
  318. */
  319. public function process_bulk_action() {
  320. switch ( $this->current_action() ) {
  321. case 'check_in':
  322. $this->bulk_check_in();
  323. break;
  324. case 'uncheck_in':
  325. $this->bulk_uncheck_in();
  326. break;
  327. case 'delete_attendee':
  328. $this->bulk_delete();
  329. break;
  330. default:
  331. do_action( 'tribe_events_tickets_attendees_table_process_bulk_action', $this->current_action() );
  332. break;
  333. }
  334. }
  335. protected function bulk_check_in() {
  336. if ( ! isset( $_POST['attendee'] ) ) {
  337. return;
  338. }
  339. foreach ( (array) $_POST['attendee'] as $attendee ) {
  340. list( $id, $addon ) = $this->attendee_reference( $attendee );
  341. if ( false === $id ) {
  342. continue;
  343. }
  344. $addon->checkin( $id );
  345. }
  346. }
  347. protected function bulk_uncheck_in() {
  348. if ( ! isset( $_POST['attendee'] ) ) {
  349. return;
  350. }
  351. foreach ( (array) $_POST['attendee'] as $attendee ) {
  352. list( $id, $addon ) = $this->attendee_reference( $attendee );
  353. if ( false === $id ) {
  354. continue;
  355. }
  356. $addon->uncheckin( $id );
  357. }
  358. }
  359. protected function bulk_delete() {
  360. if ( ! isset( $_POST['attendee'] ) ) {
  361. return;
  362. }
  363. foreach ( (array) $_POST['attendee'] as $attendee ) {
  364. list( $id, $addon ) = $this->attendee_reference( $attendee );
  365. if ( false === $id ) {
  366. continue;
  367. }
  368. $addon->delete_ticket( null, $id );
  369. }
  370. }
  371. /**
  372. * Returns the attendee ID and instance of the specific ticketing solution or "addon" used
  373. * to handle it.
  374. *
  375. * This is used in the context of bulk actions where each attendee table entry is identified
  376. * by a string of the pattern {id}|{ticket_class} - where possible this method turns that into
  377. * an array consisting of the attendee object ID and the relevant ticketing object.
  378. *
  379. * If this cannot be determined, both array elements will be set to false.
  380. *
  381. * @param $reference
  382. *
  383. * @return array
  384. */
  385. protected function attendee_reference( $reference ) {
  386. $failed = array( false, false );
  387. if ( false === strpos( $reference, '|' ) ) {
  388. return $failed;
  389. }
  390. $parts = explode( '|', $reference );
  391. if ( count( $parts ) < 2 ) {
  392. return $failed;
  393. }
  394. $id = absint( $parts[0] );
  395. if ( $id <= 0 ) {
  396. return $failed;
  397. }
  398. $addon = call_user_func( array( $parts[1], 'get_instance' ) );
  399. if ( ! is_subclass_of( $addon, 'Tribe__Tickets__Tickets' ) ) {
  400. return $failed;
  401. }
  402. return array( $id, $addon );
  403. }
  404. /**
  405. * Prepares the list of items for displaying.
  406. */
  407. public function prepare_items() {
  408. $this->process_bulk_action();
  409. $event_id = isset( $_GET['event_id'] ) ? $_GET['event_id'] : 0;
  410. $items = Tribe__Tickets__Tickets::get_event_attendees( $event_id );
  411. $this->items = $items;
  412. $total_items = count( $this->items );
  413. $per_page = $total_items;
  414. $this->set_pagination_args(
  415. array(
  416. 'total_items' => $total_items,
  417. 'per_page' => $per_page,
  418. 'total_pages' => 1,
  419. )
  420. );
  421. }
  422. }