post_type; try { $document = $is_quote ? new \EasyInvoice\Models\Quote( $post ) : new \EasyInvoice\Models\Invoice( $post ); $pdf = $is_quote ? PdfRenderer::renderQuote( $document ) : PdfRenderer::renderInvoice( $document ); } catch ( \Throwable $e ) { error_log( 'Easy Invoice: server-side PDF failed, falling back to the browser — ' . $e->getMessage() ); return; } if ( is_wp_error( $pdf ) || ! is_string( $pdf ) || '' === $pdf ) { if ( is_wp_error( $pdf ) ) { error_log( 'Easy Invoice: server-side PDF failed, falling back to the browser — ' . $pdf->get_error_message() ); } return; } self::stream( $pdf, self::filename( $document, $is_quote ) ); } /** * How the download button produces its PDF: 'browser' or 'server'. * * @return string */ public static function downloadMethod(): string { $method = (string) get_option( 'easy_invoice_pdf_download_method', 'browser' ); /** * Filter how the Download as PDF button produces its file. * * @param string $method 'browser' (capture the page as shown) or 'server' (dompdf). */ $method = (string) apply_filters( 'easy_invoice_pdf_download_method', $method ); return 'server' === $method ? 'server' : 'browser'; } /** * Send the bytes as a download and stop. * * @param string $pdf PDF bytes. * @param string $filename Download filename. * @return void */ private static function stream( string $pdf, string $filename ): void { // Any stray output — a notice, a plugin's whitespace — would corrupt the // file, and a corrupt PDF is worse than a slow one. 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="' . $filename . '"' ); header( 'Content-Length: ' . strlen( $pdf ) ); header( 'X-Content-Type-Options: nosniff' ); echo $pdf; // phpcs:ignore WordPress.Security.EscapeOutput -- binary document. exit; } /** * Download filename for a document. * * @param object $document Invoice or Quote model. * @param bool $is_quote Whether this is a quote. * @return string */ private static function filename( $document, bool $is_quote ): string { $number = ''; if ( is_callable( [ $document, 'getNumber' ] ) ) { $number = trim( (string) $document->getNumber() ); } if ( '' === $number ) { $number = $is_quote ? 'quote' : 'invoice'; } return sanitize_file_name( $number . '.pdf' ); } }