0

in my functions.php file I've added a custom action for the template_redirect hook which must force download a file stored on the server. The code of the download works fine when it is in a simple PHP file outside of Wordpress. But the feature is broken as soon as I add this code inside my template _redirect hook. Chrome says "The site cannot be reached ... ERR_INVALID_RESPONSE". There is no error 500 or other error...

Here's the download code :

<?php
$filename = $_SERVER['DOCUMENT_ROOT'] . 'path-to-my-wordpress/wp-content/uploads/export/test.html';
header( "Expires: 0" );
header( "Cache-Control: no-cache, no-store, must-revalidate" );
header( 'Cache-Control: pre-check=0, post-check=0, max-age=0', false );
header( "Pragma: no-cache" );
header( "Content-type: text/html" );
header( "Content-Disposition:attachment; filename=\"" . basename( $filename ) . "\"" );
header( "Content-Type: application/force-download" );
readfile( "{$filename}" );
?>

Here's the template_redirect hook :

add_action( 'template_redirect', 'my_template_redirect' );
function my_template_redirect() {
$filename = $_SERVER['DOCUMENT_ROOT'] . 'path-to-my-wordpress/wp-content/uploads/export/test.html';
header( "Expires: 0" );
header( "Cache-Control: no-cache, no-store, must-revalidate" );
header( 'Cache-Control: pre-check=0, post-check=0, max-age=0', false );
header( "Pragma: no-cache" );
header( "Content-type: text/html" );
header( "Content-Disposition:attachment; filename=\"" . basename( $filename ) . "\"" );
header( "Content-Type: application/force-download" );
readfile( "{$filename}" );
exit();
}

Any idea ?

EDIT

After some more tests, the problem seems to come from the specific URL from which I'm trying to run this download. In fact, my code is like this :

add_action( 'template_redirect', 'my_template_redirect' );
function my_template_redirect() {
    if ( preg_match( "/\/wp-admin\/export$/", $_SERVER['REQUEST_URI'] ) ) {
        $filename = $_SERVER['DOCUMENT_ROOT'] . 'path-to-my-wordpress/wp-content/uploads/export/test.html';
        header( "Expires: 0" );
        header( "Cache-Control: no-cache, no-store, must-revalidate" );
        header( 'Cache-Control: pre-check=0, post-check=0, max-age=0', false );
        header( "Pragma: no-cache" );
        header( "Content-type: text/html" );
        header( "Content-Disposition:attachment; filename=\"" . basename( $filename ) . "\"" );
        header( "Content-Type: application/force-download" );
        readfile( "{$filename}" );
        exit();
    }
}

The URL is /wp-admin/export and this should launch the download of the file. Without this URL condition, the code does work when I reach the base site URL (= http://mysite.dev/). But with the condition adn trying to reach http://mysite.dev/wp-admin/export, it breaks. I also tried without the wp-admin prefix, and it also breaks.

  • you definitely need to exit to halt execution after the file is output. – Milo May 12 '17 at 16:16
  • I forgot the exit(); in my example, but I do have it in my code. And it doesn't work. – Max May 12 '17 at 16:57
  • works fine for me in latest WordPress, no plugins, twentysixteen theme. – Milo May 12 '17 at 18:12
  • also note that technically, you can't have two different Content-type headers, but that shouldn't break anything. – Milo May 12 '17 at 18:12
  • This seems to come from my custom theme... – Max May 12 '17 at 19:22
1

The solution is in fact very simple. Just use the action admin_post_(action)...

add_action( 'admin_post_export_page', 'export_page' );
function export_page() {
    // any code you want
}

than you can make custom links admin_url( 'admin-post.php?action=export_page&id=' . $post->ID );

Thanks Milo for giving the solution.

0

Error 500 This is a server error, so I assume it is related to or read of the file or its delivery to the client.

The problems I currently see as possible that cause the problem are: 1) You have twice submitted the content type but different settings and parallels. 2) The second time you send an application / force-download type, there are servers that are problematic for them if they do not know the mime type that is being sent.

Try the following code:

add_action( 'template_redirect', 'my_template_redirect' );
function my_template_redirect() {
    if ( strpos( $_SERVER['REQUEST_URI'], admin_url( 'export' ) ) !== false ) {
        $upload_dir = wp_upload_dir();
        $filename = $upload_dir['basedir'] . '/export/test.html';

        header( "Expires: 0" );
        header( "cache-Control: no-cache, no-store, must-revalidate" );
        header( "Pragma: no-cache" );
        header( "content-disposition: attachment; filename=" . basename( $filename ) );
        header( "content-type: application/octet-stream" );
        header( "content-length: " . filesize( $file ) );
        readfile( $filename );
        die();
    }
}
-1

Your not adding your redirect page

 add_action( 'template_redirect', 'my_template_redirect' );
    function my_template_redirect() {
    $filename = $_SERVER['DOCUMENT_ROOT'] . 'path-to-my-wordpress/wp-content/uploads/export/test.html';
    header( "Expires: 0" );
    header( "Cache-Control: no-cache, no-store, must-revalidate" );
    header( 'Cache-Control: pre-check=0, post-check=0, max-age=0', false );
    header( "Pragma: no-cache" );
    header( "Content-type: text/html" );
    header( "Content-Disposition:attachment; filename=\"" . basename( $filename ) . "\"" );
    header( "Content-Type: application/force-download" );
    readfile( "{$filename}" );
    // Add your redirect page here
    wp_redirect( home_url( '/pagename/' ) ); /// works on my install sends to new page
    exit();
    }
  • This doesn't work on my install :-( I 'm testing on a fresh install of Wordpress without any plugins. I'm on a Mac with MAMP and PHP 7.0.13. – Max May 12 '17 at 17:52
  • Did it redirect you? what errors are you getting? – Sam May 12 '17 at 18:09
  • no redirection, same error as previous test – Max May 12 '17 at 18:12
  • maybe the template_redirect hook is not the right thing to use for this purpose... but what else ? – Max May 12 '17 at 18:13
  • I edited my post with more tests... – Max May 12 '17 at 19:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.