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
);
}
}