Entrega de un archivo en lugar de wordpress page

2

Estoy tratando de hacer una página donde un usuario proporcione un ID de un archivo adjunto y el sitio establecerá los encabezados y entregará ese archivo en lugar de una página 404. por lo que / download / 1754 buscará el archivo adjunto con ese Id y lo enviará para verlo / descargarlo, dependiendo del tipo de archivo.

No puedo pensar en una forma fácil de hacer wordpress para hacer esto desde dentro de un complemento. Consideré usar add_rewrite_rule pero no podía verlo bien, también consideré revisar $ _SERVER ['REQUEST_URI'] para entregar el contenido antes de cualquier HTML, pero luego tendría que detener la página para que no mostrara un 404 y no estaba Seguro de que Wordpress es una manera fácil de hacer esto.

Mi idea actual era que mi complemento hiciera una página de descarga, asignara una plantilla y que esa plantilla ejecutara la lógica en lugar de mi clase de complemento. aunque he usado esto antes para otra situación, era muy complicado ya que tuve que escribir un montón de código para obligar a los usuarios a no poder actualizar o editar el archivo y volver a crearlo / borrarlo en la activación. Desactivación. así que idealmente me gustaría evitar eso.

    
pregunta Chris Morris 26.01.2015 - 16:15

2 respuestas

2

Estás en el camino correcto con una regla de reescritura. Si solo está entregando un archivo, puede enganchar una acción temprana, verificar si se solicitó una descarga, luego generar el archivo y salir antes de que WordPress llegue a la etapa de consultar la base de datos y decidir que la solicitud es un 404. p>

// add the download ID query var which we'll set in the rewrite rule
function wpd_query_var( $query_vars ){
    $query_vars[] = 'download_id';
    return $query_vars;
}
add_filter( 'query_vars', 'wpd_query_var' );

// add rewrite rule
function wpd_rewrite(){
    add_rewrite_rule(
        'download/([0-9]+)/?$',
        'index.php?download_id=$matches[1]',
        'top'
    );
}
add_action( 'init', 'wpd_rewrite' );

// check for download_id and output the file
function wpd_request( $wp ){
    if( array_key_exists( 'download_id', $wp->query_vars ) ) {
        // output your headers and file here
        // ID is in $wp->query_vars['download_id']
        // then exit to halt any further execution
        exit;
    }
}
add_action( 'parse_query', 'wpd_request' );
    
respondido por el Milo 26.01.2015 - 17:03
2

Puedes probar el siguiente ejemplo, para adjuntos de imágenes:

add_action( 'init', function()
{                                                               
    add_rewrite_endpoint( 'download', EP_ROOT );
    add_action( 'template_redirect', function()
    {
        if ( $pid = get_query_var( 'download' ) ) 
        {
            $found = false;
            if( $file = wp_get_attachment_image_src( absint( $pid ), 'full' ) )
            {
                $found = true;
                header( "Content-Disposition: attachment; filename=" . basename( $file[0] ) );
                readfile( $file[0] );
                exit();
            }
            if( ! $found )
                wp_die( __( 'Image file not found!' ) );
        }
    } );   
} );

donde podría tener que ajustar los encabezados a sus necesidades.

Vuelva a generar sus reglas de reescritura y luego debería poder descargar los archivos adjuntos de la imagen desde:

http://example.tld/download/123/

Hay scripts mucho mejores por ahí, en comparación con esta simple demostración, pero parece funcionar en mi instalación. Ver ejemplo en este blog , parece tener algunas ideas interesantes sobre cómo manejar archivos grandes.

Espero que puedas modificarlo según tus necesidades.

    
respondido por el birgire 26.01.2015 - 18:36

Lea otras preguntas en las etiquetas