ZIP todas as imagens exibidas em uma [galeria] e ofereça como link para download

13

Gostaria de oferecer aos meus visitantes a opção de baixar a galeria de fotos inteira (exibida nas páginas dedicadas da [galeria]) como um arquivo ZIP exibido na parte inferior de cada página da galeria. - A imagem em tamanho real deverá ser incluída.

David Walsh deu um código em seu post aqui para compactar arquivos, mas estou tendo problemas para integrá-lo às funções do Wordpress.

Estou ciente de que existe um plug-in de download da galeria NextGEN, mas não estou em posição de usá-lo, pois uso as funções nativas da galeria wordpress.

Uma pergunta semelhante com uma alternativa (método manual) de concluir o acima pode ser encontrada aqui: Plugin para baixar arquivos de mídia anexados?

Qualquer ajuda seria muito apreciada. Obrigado.

Paul Thomson
fonte
O que você quer dizer com páginas dedicadas à galeria?
NoBugs
postagens padrão que exibem APENAS o código de acesso da galeria [colunas da galeria = "4" link = "arquivo"] e nenhum outro conteúdo na página. Incluí que, na descrição, apenas ajuda os desenvolvedores.
Paul Thomson

Respostas:

13

Primeiro você precisa obter as imagens. Como obter todas as imagens de uma galeria é descrito aqui .

O WordPress usa duas classes para descompactar arquivos. O PHP foi incorporado ZipArchive()(uso, veja David Walsh). E PclZip , você pode encontrar esta classe em wp-admin/includes/class-pclzip.php. Se você tiver problemas com ZipArchive()a classe PclZip.

Agora você só precisa colar os dois juntos. Talvez eu possa postar algum código de exemplo mais tarde, atualmente não estou na minha mesa.

Atualizar

Sua pergunta pode ser dividida em duas partes. O primeiro é obter todas as imagens de uma galeria. O segundo é fechar as imagens e enviar o arquivo zip.
Explicarei apenas a primeira parte, obtendo todas as imagens de uma galeria, porque compactar os arquivos é um pouco offtopic.

Talvez haja outras soluções, mas neste exemplo eu substituo o código de acesso da galeria original por um personalizado para obter as imagens. O motivo é que o WordPress mudou um pouco as galerias na v3.5.
Antes da versão 3.5, as imagens de uma galeria são anexos da postagem. Depois da versão 3.5, as imagens são passadas para o código curto como um atributo. Como o WP3.5 não pode mais obter as imagens anexadas de uma postagem, precisamos buscar a lista nos atributos de código curto. Minha estratégia é substituir o código de acesso original por um código de acesso personalizado, pegar os atributos e chamar o código de acesso original para obter a saída da galeria.

Todas as coisas relacionadas à galeria estão dentro de uma classe. Para criar um arquivo zip, podemos usar outra classe que usa como entrada a saída da classe da galeria. Vamos começar com uma classe e um construtor simples.

class GalleryZip
{
    private static $instance = null;

    public static $images = array();

    public static function get_instance() {
        if ( ! session_id() )
          session_start();

        if ( null === self::$instance )
            self::$instance = new self();

        return self::$instance;
    }

    private final function __construct() {
        remove_shortcode( 'gallery' );
        add_shortcode( 'gallery', array( __CLASS__, 'gallery_zip_shortcode' ) );
    }
}

Chamaremos o método get_instance()posteriormente no plugin com o gancho plugins_loaded. No construtor, removemos o código de acesso original e o substituímos por nosso código de acesso personalizado gallery_zip_shortcode(). Agora precisamos do retorno de chamada de código curto

public static function gallery_zip_shortcode( $atts ) {

    $post = get_post();

    if ( ! function_exists( 'gallery_shortcode' ) )
      require_once ABSPATH . 'wp-includes/media.php';

    self::get_gallery_images_from_shortcode( $post->ID, $atts );
    $output = gallery_shortcode( $atts );

    $gallery_id = count( self::$images[$post->ID] ) - 1;

    $link = sprintf( '<div><a href="#" gallery-id="%d" post-id="%d" class="gallery-zip">%s</a></div>', $gallery_id, $post->ID, __( 'Get as Zip' ) );
    $output .= $link;

    return $output;

}

A primeira coisa nesse método é obter a postagem porque precisamos do ID da postagem. Do que incluímos wp-includes/media.php, esse arquivo contém a função de retorno de chamada para o código de acesso da galeria original. Agora, chamamos um método para obter uma matriz com todas as imagens, criar a saída da galeria chamando o retorno de chamada da galeria original, criar um link e anexar o link à saída da galeria. As imagens em si, respectivamente os caminhos para as imagens, são armazenadas na variável de classe $images, precisamos dessa matriz posteriormente.
A variável de classe $imagemantém uma entrada para cada postagem com uma galeria, para que possamos usar a função na primeira página ou na visualização única. Cada entrada contém uma matriz para cada galeria, porque pode haver mais de uma galeria em cada postagem.

O núcleo do plugin é o método para obter as imagens do shortcode.

protected static function get_gallery_images_from_shortcode( $id, $atts ) {

    // use the post ID if the attribute 'ids' is not set or empty
    $id = ( ! isset( $atts['ids'] ) || empty( $atts['ids'] ) ) ?
        (int) $id : $atts['ids'];

    $exclude = ( isset( $atts['exclude'] ) && ! empty( $atts['exclude'] ) ) ?
        $atts['exclude'] : '';

    if ( ! isset( self::$images[$id] ) || ! is_array( self::$images[$id] ) )
        self::$images[$id] = array();

    $images = self::get_gallery_images( $id, $exclude );

    array_push( self::$images[$id], $images );

    return $images;

}

Inicialmente, decidimos se é uma postagem única ou uma lista de IDs de postagem. Se for uma lista de IDs de postagem, lidamos com uma galeria do WP3.5 +. Depois disso, temos que lidar com o excludeatributo Depois de configurar todas as variáveis, podemos finalmente obter as imagens da galeria. As imagens recuperadas serão enviadas para a classe var $imagespara uso posterior.

protected static function get_gallery_images( $id, $exclude ) {
    $images     = array();
    $query_args = array(
            'post_status'    => 'inherit',
            'post_type'      => 'attachment',
            'post_mime_type' => 'image',
    );

    // handle gallery WP3.5+
    // if $id contains an comma, it is a list of post IDs
    if ( false !== strpos( $id, ',' ) ) {
        $query_args['include'] = $id;
    } elseif ( ! empty( $exclude ) ) {
        // handle excluding posts
        $query_args['post_parent'] = $id;
        $query_args['exclude']     = $exclude;
    } else {
        // handle gallery before WP3.5
        $query_args['post_parent'] = $id;
    }

    $attachments = get_posts( $query_args );

    $img_sizes = array_merge( array( 'full' ), get_intermediate_image_sizes() );

    $img_size = ( in_array( self::IMAGE_SIZE, $img_sizes ) ) ?
            self::IMAGE_SIZE : 'full';

    foreach ( $attachments as $key => $post ) {
        $img = wp_get_attachment_image_src( $post->ID, $img_size, false, false );
        $images[] = sprintf( '%s/%s', dirname( get_attached_file( $post->ID ) ), basename( $img[0] ) );
    }

    return $images;
}

Este é o ouro do plugin. Basta configurar uma matriz com argumentos de consulta, obter os anexos get_posts()e percorrer os anexos recuperados. Para lidar com tamanhos diferentes, obtemos a imagem do anexo e a faixa do URL. No arquivo anexado, pegamos o caminho e o juntamos ao nome do arquivo. $imagesAgora, na matriz, estão todas as imagens e seus caminhos da galeria.

Basicamente, sua pergunta é respondida neste momento. Mas você também deseja criar um arquivo zip a partir das imagens. Você pode criar um arquivo zip a partir da matriz $imagesno último método. Mas esse método é chamado sempre que uma galeria é exibida e a criação de um arquivo zip pode demorar um pouco. Talvez ninguém solicite o arquivo zip que você criou aqui, isso é um desperdício de recursos.

Como podemos fazer melhor? Você se lembra que eu coloquei todas as imagens na variável de classe $images? Podemos usar essa classe var para uma solicitação ajax. Mas uma solicitação ajax é apenas outra carga de página e podemos acessar as imagens somente quando a saída da galeria é criada. Temos que salvar nossas imagens em um local onde possamos acessá-las mesmo após uma solicitação de outra página.
Neste exemplo, eu uso uma variável de sessão para armazenar a matriz com imagens. Uma variável de sessão pode ser acessada mesmo após outra página ser recarregada. Para armazenar as imagens, registro um método com o shutdowngancho. Depois que o WordPress terminar de renderizar a página, o shutdowngancho será chamado. Neste ponto, deveríamos ter coletado todas as imagens de todas as galerias exibidas. Simplesmente armazenamos as imagens e podemos acessá-las em uma solicitação ajax.

Quando a solicitação ajax é acionada, lembramos a sessão var e criamos um arquivo zip a partir dos dados. Mas este é um tópico pouco interessante para esta pergunta.

Eu criei um repositório no GitHub com o código completo do plugin. Espero que você aponte na direção certa.

Ralf912
fonte
observe que, se você estiver lidando com novas galerias de estilo 3.5, esse método para recuperar imagens de uma galeria pode não funcionar para você.
Milo
Para esclarecer, estou usando a versão mais recente do Wordpress 3.5.1. Johannes, ficaria muito grato se você pudesse fornecer algum código de exemplo quando for o próximo na área de trabalho. Obrigado, Paul
Paul Thomson
Ei Ralf, este é um trabalho fantástico! Obrigado por compartilhar. Para que as imagens da minha galeria sejam exibidas corretamente, eu tenho que incluir link = "arquivo" no shortcode, ou seja: [gallery link = "file"], pois o shortcode é reescrito no seu código e acho que está sendo deixado de fora. resultado, minhas galerias não estão sendo exibidas corretamente. Existe alguma maneira de corrigir esse argumento no seu código?
Paul Thomson
Normalmente, os atributos são simplesmente passados ​​para o código de acesso original e não serão modificados. As galerias são exibidas como normais, mas com algum HTML anexado. Nos meus testes (com tema de vinte e doze standrad), as galerias são exibidas corretamente.
Ralf912
@PaulThomson Corrigi alguns problemas no repositório do github. O código não estava limpo.
Ralf912
0

Gosto da ideia do plugin de Ralf poder baixar uma galeria inteira de uma só vez, mas não consegui fazê-la funcionar. Eu vim com uma solução alternativa que funciona para nossos propósitos. O método é substituir a galeria WP nativa pela sua própria, que você coloca no final do functions.phparquivo do seu tema E adicionar o seguinte arquivo, nomeado download.phpna pasta do tema ativo. Na galeria personalizada, um link sob o arquivo chama o arquivo download.php, que força automaticamente o download do seu arquivo para o disco rígido. Eu testei isso nas versões mais recentes do Chrome, Firefox e Safari e funciona bem. Usaram o tema Twenty Twelve, mas não há razão para que ele não funcione em outros também.

a) Adicione o seguinte ao final de functions.php. Isso é simplesmente retirado do media.php

remove_shortcode('gallery');
function gallery_with_download_links($attr) {
    $post = get_post();
    static $instance = 0;
    $instance++;
    if ( ! empty( $attr['ids'] ) ) {
        // 'ids' is explicitly ordered, unless you specify otherwise.
        if ( empty( $attr['orderby'] ) )
            $attr['orderby'] = 'post__in';
        $attr['include'] = $attr['ids'];
    }
    // Allow plugins/themes to override the default gallery template.
    $output = apply_filters('post_gallery', '', $attr);
    if ( $output != '' )
        return $output;
    // We're trusting author input, so let's at least make sure it looks like a valid orderby statement
    if ( isset( $attr['orderby'] ) ) {
        $attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] );
        if ( !$attr['orderby'] )
            unset( $attr['orderby'] );
    }

    extract(shortcode_atts(array(
        'order'      => 'ASC',
        'orderby'    => 'menu_order ID',
        'id'         => $post->ID,
        'itemtag'    => 'dl',
        'icontag'    => 'dt',
        'captiontag' => 'dd',
        'columns'    => 3,
        'size'       => 'thumbnail',
        'include'    => '',
        'exclude'    => ''
    ), $attr));

    $id = intval($id);
    if ( 'RAND' == $order )
        $orderby = 'none';

    if ( !empty($include) ) {
        $_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );

        $attachments = array();
        foreach ( $_attachments as $key => $val ) {
            $attachments[$val->ID] = $_attachments[$key];
        }
    } elseif ( !empty($exclude) ) {
        $attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
    } else {
        $attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
    }

    if ( empty($attachments) )
        return '';

    if ( is_feed() ) {
        $output = "\n";
        foreach ( $attachments as $att_id => $attachment )
            $output .= wp_get_attachment_link($att_id, $size, true) . "\n";
        return $output;
    }

    $itemtag = tag_escape($itemtag);
    $captiontag = tag_escape($captiontag);
    $icontag = tag_escape($icontag);
    $valid_tags = wp_kses_allowed_html( 'post' );
    if ( ! isset( $valid_tags[ $itemtag ] ) )
        $itemtag = 'dl';
    if ( ! isset( $valid_tags[ $captiontag ] ) )
        $captiontag = 'dd';
    if ( ! isset( $valid_tags[ $icontag ] ) )
        $icontag = 'dt';

    $columns = intval($columns);
    $itemwidth = $columns > 0 ? floor(100/$columns) : 100;
    $float = is_rtl() ? 'right' : 'left';

    $selector = "gallery-{$instance}";

    $gallery_style = $gallery_div = '';
    if ( apply_filters( 'use_default_gallery_style', true ) )
        $gallery_style = "
        <style type='text/css'>
            #{$selector} {
                margin: auto;
            }
            #{$selector} .gallery-item {
                float: {$float};
                margin-top: 10px;
                text-align: center;
                width: {$itemwidth}%;
            }
            #{$selector} img {
                border: 2px solid #cfcfcf;
            }
            #{$selector} .gallery-caption {
                margin-left: 0;
            }
        </style>
        <!-- see gallery_shortcode() in wp-includes/media.php -->";
    $size_class = sanitize_html_class( $size );
    $gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>";
    $output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div );

    $i = 0;
    foreach ( $attachments as $id => $attachment ) {
        $link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);

        $output .= "<{$itemtag} class='gallery-item'>";
        $output .= "
            <{$icontag} class='gallery-icon'>
                $link
            </{$icontag}>";
        if ( $captiontag && trim($attachment->post_excerpt) ) {
            $output .= "
                <{$captiontag} class='wp-caption-text gallery-caption'>
                " . wptexturize($attachment->post_excerpt) . "
                </{$captiontag}>";
        }
// This is my addon which outputs a link to download the file through download.php . NB your file uri will be public! 
        $output .= '<br/ ><a href="'.get_template_directory_uri().'/download.php?file='.get_attached_file( $id ).'">Download image</a>';
        $output .= "</{$itemtag}>";
        if ( $columns > 0 && ++$i % $columns == 0 )
            $output .= '<br style="clear: both" />';
    }

    $output .= "
            <br style='clear: both;' />
        </div>\n";

    return $output;
}
add_shortcode( 'gallery' , 'gallery_with_download_links' );

b) Copie e cole o seguinte em um arquivo chamado download.phpno diretório base do tema.

<?php
$file = $_GET['file'];
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>

c) Não se esqueça de vincular o arquivo na galeria !! Importante!

Sam Edgecombe
fonte