'order_note', 'plural' => 'order_notes', 'ajax' => false, ]); $this->customer = $customer; $this->start_date = $start_date; $this->end_date = $end_date; } /** * Get columns method must return an array where the key is the column slug (ID) and the value is the column title. */ public function get_columns() { return [ 'order_id' => __('Order ID', 'advanced-customer-reports-woo'), 'date' => __('Date', 'advanced-customer-reports-woo'), 'time' => __('Time', 'advanced-customer-reports-woo'), 'note' => __('Note', 'advanced-customer-reports-woo') ]; } public function prepare_items() { global $wpdb; $this->_column_headers = [$this->get_columns(), [], []]; $this->items = []; $perpage = 20; if (empty($this->customer['found'])) { $this->set_pagination_args(['total_items' => 0, 'per_page' => $perpage]); return; } $max_orders = acreports_get_max_report_orders(); $args = array_merge([ 'limit' => $max_orders ? $max_orders : -1, 'orderby' => 'ID', 'order' => 'DESC', 'return' => 'ids', 'date_after' => $this->start_date ? $this->start_date . ' 00:00:00' : '', 'date_before' => $this->end_date ? $this->end_date . ' 23:59:59' : '', ], acreports_get_customer_order_query_args($this->customer)); $order_ids = array_map('absint', (array) wc_get_orders($args)); if (empty($order_ids)) { $this->set_pagination_args(['total_items' => 0, 'per_page' => $perpage]); return; } $id_placeholders = implode(', ', array_fill(0, count($order_ids), '%d')); $where = "WHERE comment_post_ID IN ({$id_placeholders}) AND comment_type = 'order_note'"; // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber -- $where holds only %d placeholders, one per order ID, and the IDs are bound by prepare(). $totalitems = (int) $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->comments} {$where}", $order_ids )); $this->set_pagination_args([ 'total_items' => $totalitems, 'per_page' => $perpage ]); $paged = $this->get_pagenum(); $offset = ($paged - 1) * $perpage; $this->items = $wpdb->get_results($wpdb->prepare( "SELECT comment_post_ID, comment_date, comment_content FROM {$wpdb->comments} {$where} ORDER BY comment_ID DESC LIMIT %d, %d", array_merge($order_ids, [$offset, $perpage]) )); // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber } public function column_default($item, $column_name) { // WP_List_Table echoes whatever this returns without escaping it, and // note content can come from the customer at checkout. switch ($column_name) { case 'order_id': $order_id = absint($item->comment_post_ID); return "" . esc_html($order_id) . ""; case 'date': $date = date_create_from_format('Y-m-d H:i:s', $item->comment_date); return $date ? esc_html(date_format($date, 'M j, Y')) : ''; case 'time': $date = date_create_from_format('Y-m-d H:i:s', $item->comment_date); return $date ? esc_html(date_format($date, 'H:i:s')) : ''; case 'note': return wp_kses_post($item->comment_content); default: return ''; } } public function no_items() { esc_html_e('No order notes found.', 'advanced-customer-reports-woo'); } } function setup_advanced_customer_reports_page() { add_submenu_page( null, // Parent slug - 'null' makes it hidden __('Advanced Customer Reports', 'advanced-customer-reports-woo'), // Page title __('Advanced Customer Reports', 'advanced-customer-reports-woo'), // Menu title acreports_get_required_capability(), // Capability 'acreports-order-activity', // Menu slug 'advanced_customer_reports_page_content' // Function to display the page content ); } add_action('admin_menu', 'setup_advanced_customer_reports_page'); function advanced_customer_reports_page_content() { // The hidden menu entry already gates this on the report capability; checked again // here so the callback is never safe to reach by another route. if (!acreports_current_user_can_view_reports()) { wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'advanced-customer-reports-woo'), 403); } $username = isset($_GET['username']) ? sanitize_text_field(wp_unslash($_GET['username'])) : ''; $customer_email = isset($_GET['customer_email']) ? sanitize_email(wp_unslash($_GET['customer_email'])) : ''; $start_date = isset($_GET['start_date']) ? sanitize_text_field(wp_unslash($_GET['start_date'])) : ''; $end_date = isset($_GET['end_date']) ? sanitize_text_field(wp_unslash($_GET['end_date'])) : ''; $search_value = '' !== $username ? $username : $customer_email; echo '

' . esc_html__('Advanced Customer Reports: Order Activity', 'advanced-customer-reports-woo') . '

'; echo '

' . esc_html__('View a log of order notes for all orders created by a specific customer.', 'advanced-customer-reports-woo') . '

'; // Go back to admin.php?page=advanced-customer-reports if($search_value) { $back_args = array_filter(array( 'page' => 'advanced-customer-reports', 'username' => $username, 'customer_email' => $customer_email, )); echo '← ' . esc_html__('Go back to customer report', 'advanced-customer-reports-woo') . ''; } else { echo '← ' . esc_html__('Go back to customer reports', 'advanced-customer-reports-woo') . ''; } // Line echo '


'; // Search form echo '
'; echo ''; echo ''; // Start Date echo ''; // End Date echo ''; // Search button echo ''; echo '
'; if (!empty($search_value)) { $customer = acreports_resolve_customer_context(array( 'customer_email' => $customer_email, 'identifier' => $username, )); if (empty($customer['found'])) { echo '

' . esc_html__('No customer found for that search.', 'advanced-customer-reports-woo') . '

'; echo '
'; return; } $list_table = new Order_Notes_List_Table($customer, $start_date, $end_date); $list_table->prepare_items(); if (empty($list_table->items)) { echo '

' . esc_html__('No order notes found for this customer.', 'advanced-customer-reports-woo') . '

'; } else { $list_table->display(); } } echo ''; }