'case', 'plural' => 'cases', 'ajax' => false, ] ); } /** * Get the list of columns. * * @return array */ public function get_columns(): array { return [ 'preview' => __( 'Preview', 'aarambha-case-management' ), 'case_number' => __( 'Case #', 'aarambha-case-management' ), 'customer_name' => __( 'Customer', 'aarambha-case-management' ), 'customer_email' => __( 'Email', 'aarambha-case-management' ), 'phone' => __( 'Phone', 'aarambha-case-management' ), 'subject' => __( 'Subject', 'aarambha-case-management' ), 'attachment_count' => __( 'Files', 'aarambha-case-management' ), 'created_at' => __( 'Created', 'aarambha-case-management' ), 'status' => __( 'Status', 'aarambha-case-management' ), ]; } /** * Default column renderer. * * @param array $item Row data. * @param string $column_name Column key. * @return string */ public function column_default( $item, $column_name ) { return $item[ $column_name ] ?? ''; } /** * Render the preview column. * * @param array $item Row data. * @return string */ public function column_preview( $item ): string { $attachment_id = (int) $item['preview_attachment']; if ( ! $attachment_id ) { return '—'; } if ( wp_attachment_is_image( $attachment_id ) ) { return wp_get_attachment_image( $attachment_id, [ 60, 60 ] ); } return ''; } /** * Render the case number column, with a view row action. * * @param array $item Row data. * @return string */ public function column_case_number( $item ): string { $url = add_query_arg( [ 'page' => 'aarambha-case-management-details', 'id' => $item['id'], ], admin_url( 'admin.php' ) ); $actions = [ 'view' => sprintf( '%s', esc_url( $url ), esc_html__( 'View', 'aarambha-case-management' ) ), ]; return sprintf( '%2$s%3$s', esc_url( $url ), esc_html( $item['case_number'] ), $this->row_actions( $actions ) ); } /** * Render the status column. * * @param array $item Row data. * @return string */ public function column_status( $item ): string { $status = strtolower( $item['status'] ); return sprintf( '%2$s', esc_attr( $status ), esc_html( ucfirst( $status ) ) ); } /** * Get sortable columns. * * @return array */ public function get_sortable_columns(): array { return [ 'case_number' => [ 'case_number', true ], 'customer_name' => [ 'customer_name', false ], 'status' => [ 'status', false ], 'created_at' => [ 'created_at', true ], ]; } /** * Prepare the table items: fetch, sort, and paginate cases. * * Note: orderby/order are read-only display parameters (sort direction * for a listing screen), not a state-changing action, so no nonce is * required here. Values are whitelisted/sanitized before use. * * @return void */ public function prepare_items(): void { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only sort param, not a state-changing request. $orderby = sanitize_key( $_GET['orderby'] ?? 'created_at' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only sort param, not a state-changing request. $order = strtoupper( sanitize_text_field( $_GET['order'] ?? 'DESC' ) ); $sortable = array_keys( $this->get_sortable_columns() ); if ( ! in_array( $orderby, $sortable, true ) ) { $orderby = 'created_at'; } if ( ! in_array( $order, [ 'ASC', 'DESC' ], true ) ) { $order = 'DESC'; } $per_page = 10; $current_page = $this->get_pagenum(); $repository = new CaseRepository(); $total_items = $repository->count(); $this->items = $repository->find_all( $orderby, $order, $per_page, $current_page ); $this->set_pagination_args( [ 'total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => max( 1, (int) ceil( $total_items / $per_page ) ), ] ); $this->_column_headers = [ $this->get_columns(), [], $this->get_sortable_columns(), ]; } }