Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Form PDF Settings to be previewed before saving #1563

Merged
merged 1 commit into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/Helper/Helper_Abstract_Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -2272,7 +2272,12 @@ public function toggle_callback( $args ) {
<div class="gform-settings-description gform-kitchen-sink"><?php echo wp_kses_post( $args['desc'] ); ?></div>

<span class="gform-settings-input__container">
<input type="checkbox" id="gfpdf_settings[<?php echo esc_attr( $args['id'] ); ?>]" name="gfpdf_settings[<?php echo esc_attr( $args['id'] ); ?>]" value="Yes" <?php echo checked( $value, 'Yes', false ); ?> />
<input type="checkbox"
id="gfpdf_settings[<?php echo esc_attr( $args['id'] ); ?>]"
name="gfpdf_settings[<?php echo esc_attr( $args['id'] ); ?>]"
class="gfpdf-input-toggle"
value="Yes"
<?php checked( $value, 'Yes' ); ?> />
<label class="gform-field__toggle-container" for="gfpdf_settings[<?php echo esc_attr( $args['id'] ); ?>]">
<?php if ( ! empty( $name ) ): ?>
<span class="screen-reader-text"><?php echo esc_html( $name ); ?></span>
Expand Down
3 changes: 2 additions & 1 deletion src/Helper/Helper_Data.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,9 @@ public function get_localised_script_data( Helper_Abstract_Options $options, Hel

'searchPlaceholder' => esc_html__( 'Search the Gravity PDF Knowledgebase...', 'gravity-forms-pdf-extended' ),
'searchResultHeadingText' => esc_html__( 'Gravity PDF Documentation', 'gravity-forms-pdf-extended' ),
'noResultText' => esc_html__( 'It doesn\'t look like there are any topics related to your issue.', 'gravity-forms-pdf-extended' ),
'noResultText' => esc_html__( "It doesn't look like there are any topics related to your issue.", 'gravity-forms-pdf-extended' ),
'getSearchResultError' => esc_html__( 'An error occurred. Please try again', 'gravity-forms-pdf-extended' ),
'getPreviewResultError' => esc_html__( 'An error occurred. Please try again', 'gravity-forms-pdf-extended' ),

'requiresGravityPdfVersion' => esc_html__( 'Requires Gravity PDF v%s', 'gravity-forms-pdf-extended' ),
'templateNotCompatibleWithGravityPdfVersion' => esc_html__( 'This PDF template is not compatible with your version of Gravity PDF. This template required Gravity PDF v%s.', 'gravity-forms-pdf-extended' ),
Expand Down
16 changes: 3 additions & 13 deletions src/Helper/Helper_Options_Fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,19 +251,8 @@ public function get_registered_fields() {
'required' => true,
'desc' => __( 'Add a descriptive label to help you differentiate between multiple PDF settings.', 'gravity-forms-pdf-extended' ),
'schema' => [
'arg_options' => [
'validate_callback' => function( $param, $request, $key ) {
if ( ! empty( $param ) ) {
return true;
}

return new WP_Error(
'rest_invalid_param',
__( 'PDF name must be a non-empty string.', 'gravity-forms-pdf-extended' ),
[ 'status' => 400 ]
);
},
],
'default' => __( 'PDF', 'gravity-forms-pdf-extended' ),
'minLength' => 1,
],
],

Expand Down Expand Up @@ -327,6 +316,7 @@ public function get_registered_fields() {
'schema' => [
'default' => __( 'document', 'gravity-forms-pdf-extended' ),
'description' => sprintf( __( 'Set the filename for the generated PDF (excluding the .pdf extension). Mergetags are supported, and invalid characters %s are automatically converted to an underscore.', 'gravity-forms-pdf-extended' ), '/ \ " * ? | : < >' ),
'minLength' => 1,
'arg_options' => [
'sanitize_callback' => function( $param, $request, $key ) {
$param = $this->misc->remove_extension_from_string( $param, '.pdf' );
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Model_Form_Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ public function get_template_name_from_current_page() {
}
}

return $template;
return apply_filters( 'gfpdf_template_for_current_page', $template );
}

/**
Expand Down
138 changes: 75 additions & 63 deletions src/Model/Model_PDF.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,71 +270,9 @@
return $path_to_pdf;
}

/* Verify the PDF can be sent to the client */
if ( headers_sent( $filename, $linenumber ) ) {
$this->log->error(
'Server headers already sent',
[
'filename' => $filename,
'linenumber' => $linenumber,
]
);

return new WP_Error( 'headers_sent', __( 'The PDF cannot be displayed because the server headers have already been sent.', 'gravity-forms-pdf-extended' ) );
}

/* Force any active buffers to close and delete its content */
while ( ob_get_level() > 0 ) {
ob_end_clean();
}

do_action( 'gfpdf_post_view_or_download_pdf', $path_to_pdf, $form, $entry, $settings, $action );

/* Send the PDF to the client */
header( 'Content-Type: application/pdf' );

/*
* Set the filename, supporting the new utf-8 syntax + backwards compatibility
* Refer to RFC 8187 https://www.rfc-editor.org/rfc/rfc8187.html
*/
header(
sprintf(
'Content-Disposition: %1$s; filename="%2$s"; filename*=utf-8\'\'%2$s',
$action === 'view' ? 'inline' : 'attachment',
rawurlencode( basename( $path_to_pdf ) ),
)
);

/* only add the length if the server is not using compression */
if ( empty( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
header( sprintf( 'Content-Length: %d', filesize( $path_to_pdf ) ) );
}

/* Tell client to download the file */
if ( $action === 'download' ) {
header( 'Content-Description: File Transfer' );
header( 'Content-Transfer-Encoding: binary' );
}

/* Set appropriate headers for local browser caching */
$last_modified_time = filemtime( $path_to_pdf );
$etag = md5( $path_to_pdf ); /* the file path includes a unique hash that automatically changes when a PDF does */

header( sprintf( 'Last-Modified: %s GMT', gmdate( 'D, d M Y H:i:s', $last_modified_time ) ) );
header( sprintf( 'Etag: %s', $etag ) );
header( 'Cache-Control: no-cache, private' );
header( 'Pragma: no-cache' );
header( 'Expires: 0' );

/* Tell client they can display the PDF from the local cache if it is still current */
if ( ! empty( $_SERVER['HTTP_IF_NONE_MATCH'] ) && $_SERVER['HTTP_IF_NONE_MATCH'] === $etag ) {
header( 'HTTP/1.1 304 Not Modified' );
exit;
}

readfile( $path_to_pdf ); /* phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_readfile */

exit;
$this->send_pdf_to_browser( $path_to_pdf, $action );

Check warning on line 275 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L275

Added line #L275 was not covered by tests
}

/**
Expand Down Expand Up @@ -2658,4 +2596,78 @@

return $hydrated_form;
}

/**
* Send a PDF file to the browser
*
* @param string $path_to_pdf Absolute path to PDF on disk
* @param string $action Either "view" or "download"
*
* @since 6.12
*/
public function send_pdf_to_browser( $path_to_pdf, $action = 'view' ) {
/* Verify the PDF can be sent to the client */
if ( headers_sent( $filename, $linenumber ) ) {
$this->log->error(
'Server headers already sent',
[
'filename' => $filename,
'linenumber' => $linenumber,
]
);

return new WP_Error( 'headers_sent', __( 'The PDF cannot be displayed because the server headers have already been sent.', 'gravity-forms-pdf-extended' ) );
}

/* Force any active buffers to close and delete its content */
while ( ob_get_level() > 0 ) {
ob_end_clean();

Check warning on line 2624 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L2623-L2624

Added lines #L2623 - L2624 were not covered by tests
}

/* Send the PDF to the client */
header( 'Content-Type: application/pdf' );

Check warning on line 2628 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L2628

Added line #L2628 was not covered by tests

/*
* Set the filename, supporting the new utf-8 syntax + backwards compatibility
* Refer to RFC 8187 https://www.rfc-editor.org/rfc/rfc8187.html
*/
header(
sprintf(
'Content-Disposition: %1$s; filename="%2$s"; filename*=utf-8\'\'%2$s',
$action === 'view' ? 'inline' : 'attachment',
rawurlencode( basename( $path_to_pdf ) ),
)

Check warning on line 2639 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L2634-L2639

Added lines #L2634 - L2639 were not covered by tests
);

/* only add the length if the server is not using compression */
if ( empty( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
header( sprintf( 'Content-Length: %d', filesize( $path_to_pdf ) ) );

Check warning on line 2644 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L2643-L2644

Added lines #L2643 - L2644 were not covered by tests
}

/* Tell client to download the file */
if ( $action !== 'view' ) {
header( 'Content-Description: File Transfer' );
header( 'Content-Transfer-Encoding: binary' );

Check warning on line 2650 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L2648-L2650

Added lines #L2648 - L2650 were not covered by tests
}

/* Set appropriate headers for local browser caching */
$last_modified_time = filemtime( $path_to_pdf );
$etag = md5( $path_to_pdf ); /* the file path includes a unique hash that automatically changes when a PDF does */

Check warning on line 2655 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L2654-L2655

Added lines #L2654 - L2655 were not covered by tests

header( sprintf( 'Last-Modified: %s GMT', gmdate( 'D, d M Y H:i:s', $last_modified_time ) ) );
header( sprintf( 'Etag: %s', $etag ) );
header( 'Cache-Control: no-cache, private' );
header( 'Pragma: no-cache' );
header( 'Expires: 0' );

Check warning on line 2661 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L2657-L2661

Added lines #L2657 - L2661 were not covered by tests

/* Tell client they can display the PDF from the local cache if it is still current */
if ( ! empty( $_SERVER['HTTP_IF_NONE_MATCH'] ) && $_SERVER['HTTP_IF_NONE_MATCH'] === $etag ) {
header( 'HTTP/1.1 304 Not Modified' );
exit;

Check warning on line 2666 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L2664-L2666

Added lines #L2664 - L2666 were not covered by tests
}

readfile( $path_to_pdf ); /* phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_readfile */

Check warning on line 2669 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L2669

Added line #L2669 was not covered by tests

exit;

Check warning on line 2671 in src/Model/Model_PDF.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Model_PDF.php#L2671

Added line #L2671 was not covered by tests
}
}
Loading