0 ? get_userdata( $client_id ) : false; if ( ! $client ) { echo '

' . esc_html__( 'That client does not exist.', 'easy-invoice' ) . '

'; return; } $statement = ClientLedger::statement( $client_id, $from, $to ); include EASY_INVOICE_PLUGIN_DIR . 'templates/admin/statement-page.php'; } /** * Serve the statement as a PDF. * * @return void */ public static function handlePdf(): void { $client_id = isset( $_GET['client_id'] ) ? absint( $_GET['client_id'] ) : 0; $nonce = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, self::ACTION_PDF . '_' . $client_id ) ) { wp_die( esc_html__( 'Security check failed.', 'easy-invoice' ), '', [ 'response' => 403 ] ); } if ( ! easy_invoice_user_can( 'ei_view_invoices' ) ) { wp_die( esc_html__( 'You do not have permission to do that.', 'easy-invoice' ), '', [ 'response' => 403 ] ); } $client = $client_id > 0 ? get_userdata( $client_id ) : false; if ( ! $client ) { wp_die( esc_html__( 'That client does not exist.', 'easy-invoice' ), '', [ 'response' => 404 ] ); } if ( ! PdfRenderer::isAvailable() ) { wp_die( esc_html__( 'Server-side PDF rendering is unavailable because the PDF library is missing.', 'easy-invoice' ), '', [ 'response' => 501, 'back_link' => true ] ); } // phpcs:disable WordPress.Security.NonceVerification.Recommended -- covered by the nonce above. $from = isset( $_GET['from'] ) ? sanitize_text_field( wp_unslash( $_GET['from'] ) ) : ''; $to = isset( $_GET['to'] ) ? sanitize_text_field( wp_unslash( $_GET['to'] ) ) : ''; // phpcs:enable $statement = ClientLedger::statement( $client_id, $from, $to ); ob_start(); include EASY_INVOICE_PLUGIN_DIR . 'templates/pdf/statement.php'; $html = (string) ob_get_clean(); $pdf = PdfRenderer::fromHtml( $html ); if ( is_wp_error( $pdf ) ) { wp_die( esc_html( $pdf->get_error_message() ), '', [ 'response' => 500, 'back_link' => true ] ); } $name = sanitize_file_name( 'statement-' . ( $client->display_name ?: $client->user_login ) . '.pdf' ); if ( ob_get_length() ) { @ob_end_clean(); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } nocache_headers(); header( 'Content-Type: application/pdf' ); header( 'Content-Disposition: attachment; filename="' . $name . '"' ); header( 'Content-Length: ' . strlen( $pdf ) ); header( 'X-Content-Type-Options: nosniff' ); echo $pdf; // phpcs:ignore WordPress.Security.EscapeOutput -- binary document. exit; } /** * URL of the statement screen for a client. * * @param int $client_id Client ID. * @return string */ public static function pageUrl( int $client_id ): string { return add_query_arg( [ 'page' => self::PAGE_SLUG, 'client_id' => $client_id, ], admin_url( 'admin.php' ) ); } /** * URL that downloads the statement PDF. * * @param int $client_id Client ID. * @param string $from Start date. * @param string $to End date. * @return string */ public static function pdfUrl( int $client_id, string $from = '', string $to = '' ): string { return wp_nonce_url( add_query_arg( array_filter( [ 'action' => self::ACTION_PDF, 'client_id' => $client_id, 'from' => $from, 'to' => $to, ] ), admin_url( 'admin-post.php' ) ), self::ACTION_PDF . '_' . $client_id ); } }