ZIP su tutte le immagini visualizzate in una [galleria] e offri come link per il download


13

Vorrei offrire ai miei visitatori la possibilità di scaricare l'intera galleria fotografica (visualizzata su pagine dedicate [galleria]) come file ZIP visualizzato nella parte inferiore di ciascuna pagina della galleria. - L'immagine a dimensione intera dovrà essere inclusa.

David Walsh ha dato un po 'di codice nel suo post qui per comprimere i file, ma ho problemi a integrarlo con le funzioni di Wordpress.

Sono consapevole che esiste un plug-in per il download della galleria NextGEN, ma non sono in grado di utilizzarlo poiché utilizzo le funzioni native della galleria wordpress.

Una domanda simile con un'alternativa (metodo manuale) per completare quanto sopra può essere trovata qui: Plugin per scaricare file multimediali allegati?

Qualsiasi aiuto sarebbe molto apprezzato. Grazie.


Cosa intendi per pagine di gallerie dedicate?
NoBugs

post standard che visualizzano SOLO il codice funzione della galleria [colonne della galleria = "4" link = "file"] e nessun altro contenuto sulla pagina. Ho incluso che nella descrizione solo in caso aiutasse gli sviluppatori.
Paul Thomson,

Risposte:


14

Per prima cosa devi ottenere le immagini. Come ottenere tutte le immagini di una galleria è descritto qui .

WordPress utilizza due classi per decomprimere i file. PHP integrato ZipArchive()(utilizzo vedi David Walsh). E PclZip , puoi trovare questa classe in wp-admin/includes/class-pclzip.php. Se hai problemi con ZipArchive()prova la classe PclZip.

Ora devi solo incollare entrambi insieme. Forse potrò pubblicare qualche codice di esempio in seguito, al momento non sono alla mia scrivania.

Aggiornare

La tua domanda può essere divisa in due parti. Il primo è ottenere tutte le immagini da una galleria. Il secondo è zippare le immagini e inviare il file zip.
Spiegherò solo la prima parte, ottenendo tutte le immagini di una galleria, perché zippare i file è leggermente offtopico.

Forse ci sono altre soluzioni, ma in questo esempio sostituisco lo shortcode della galleria originale con uno personalizzato per ottenere le immagini. Il motivo è che WordPress ha cambiato un po 'le gallerie in v3.5.
Prima del 3.5, le immagini per una galleria sono allegati del post. Dopo 3.5, le immagini vengono passate allo shortcode come attributo. Dal momento che WP3.5 non possiamo più ottenere le immagini allegate di un post, dobbiamo recuperare l'elenco dagli attributi shortcode. La mia strategia è quella di sostituire lo shortcode originale con uno shortcode personalizzato, afferrare gli attributi e chiamare lo shortcode originale per ottenere l'output della galleria.

Tutte le cose relative alla galleria sono all'interno di una classe. Per creare un file zip, possiamo usare un'altra classe che accetta come input l'output della classe gallery. Cominciamo con una classe e un semplice costruttore.

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

Chiameremo il metodo get_instance()più avanti nel plugin con l'hook plugins_loaded. Nel costruttore, rimuoviamo lo shortcode originale e lo sostituiamo con il nostro shortcode personalizzato gallery_zip_shortcode(). Ora abbiamo bisogno del callback dello shortcode

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;

}

La prima cosa in questo metodo è ottenere il post perché abbiamo bisogno dell'ID post. Di ciò che includiamo wp-includes/media.php, questo file contiene la funzione di callback per lo shortcode della galleria originale. Ora chiamiamo un metodo per ottenere un array con tutte le immagini, creare l'output della galleria chiamando il callback originale della galleria, creare un collegamento e aggiungere il collegamento all'output della galleria. Le immagini stesse, rispettivamente i percorsi delle immagini, sono archiviate nella variabile di classe $images, abbiamo bisogno di questo array in seguito.
La variabile di classe $imagecontiene una voce per ogni post con una galleria, quindi possiamo usare la funzione in prima pagina o in vista singola. Ogni voce contiene un array per ogni galleria, perché in ogni post può esserci più di una galleria.

Il nucleo del plugin è il metodo per ottenere le immagini dallo 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;

}

Inizialmente decidiamo se si tratta di un singolo post o di un elenco di ID post. Se è un elenco di ID post, gestiamo una galleria da WP3.5 +. Successivamente, dobbiamo gestire l' excludeattributo. Dopo aver impostato tutte le variabili, possiamo finalmente ottenere le immagini dalla galleria. Le immagini recuperate verranno inserite nella classe var $imagesper un uso successivo.

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

Questo è l'oro del plugin. Basta impostare un array con argomenti di query, ottenere gli allegati get_posts()e camminare sugli allegati recuperati. Per gestire dimensioni diverse, otteniamo l'immagine dell'allegato e la striscia dell'URL. Dal file allegato, prendiamo il percorso e lo mettiamo insieme al nome del file. Nell'array $imagessono ora presenti tutte le immagini e i relativi percorsi dalla galleria.

Fondamentalmente la tua domanda ha una risposta a questo punto. Ma vuoi anche creare un file zip dalle immagini. È possibile creare un file zip dall'array $imagesnell'ultimo metodo. Ma questo metodo viene chiamato ogni volta che viene visualizzata una galleria e la creazione di un file zip potrebbe richiedere del tempo. Forse nessuno richiederebbe il file zip che hai creato qui, questo è uno spreco di risorse.

Come possiamo farlo meglio? Ti ricordi che ho inserito tutte le immagini nella variabile di classe $images? Possiamo usare questa classe var per una richiesta Ajax. Ma una richiesta Ajax è solo un altro caricamento della pagina e possiamo accedere alle immagini solo quando viene creato l'output della galleria. Dobbiamo salvare le nostre immagini in un luogo in cui possiamo accedervi anche dopo un'altra richiesta di pagina.
In questo esempio utilizzo una variabile di sessione per memorizzare l'array con le immagini. È possibile accedere a una variabile di sessione anche dopo il ricaricamento di un'altra pagina. Per memorizzare le immagini, registro un metodo con il shutdowngancio. Dopo che WordPress ha terminato il rendering della pagina, shutdownverrà chiamato l' hook. A questo punto, avremmo dovuto raccogliere tutte le immagini da tutte le gallerie visualizzate. Memorizziamo semplicemente le immagini e possiamo accedervi in ​​una richiesta Ajax.

Quando viene attivata la richiesta Ajax, ricordiamo la sessione var e creiamo un file zip dai dati. Ma questo è un po 'fuori tema per questa domanda.

Ho creato un repository su GitHub con il codice plugin completo. Spero che ti indichi nella giusta direzione.


nota che se hai a che fare con nuove gallerie in stile 3.5, quel metodo per recuperare immagini da una galleria potrebbe non funzionare per te.
Milo,

Per chiarire sto usando l'ultima versione di Wordpress 3.5.1. Johannes, sarei estremamente grato se tu fossi in grado di fornire un codice di esempio quando sarai il prossimo sul tuo desktop. Grazie, Paul
Paul Thomson,

Ehi Ralf, questo è un lavoro fantastico! Grazie per la condivisione. Affinché le mie immagini della galleria vengano visualizzate correttamente, devo includere link = "file" nel codice funzione ovvero: [gallery link = "file"] poiché il codice funzione viene riscritto attraverso il codice penso che sia stato escluso e come risultato le mie gallerie non vengono visualizzate correttamente. C'è un modo per correggere tale argomento nel tuo codice?
Paul Thomson,

Normalmente gli attributi vengono semplicemente passati allo shortcode originale e non verranno modificati. Le gallerie vengono visualizzate normalmente, ma con un po 'di HTML aggiunto. Nei miei test (con il tema ventiquattro standrad) le gallerie sono visualizzate correttamente.
Ralf912,

@PaulThomson Ho risolto alcuni problemi nel repository github. Il codice non era pulito.
Ralf912,

0

Mi piace l'idea del plugin di Ralf di poter scaricare un'intera galleria in una volta sola, ma non sono stato in grado di farlo funzionare. Ho escogitato una soluzione alternativa che funziona per i nostri scopi. Il metodo consiste nel sostituire la galleria WP nativa con la tua che si inserisce alla fine del functions.phpfile del tema E aggiungere il seguente file, denominato download.phpnella cartella del tema attiva. Nella galleria personalizzata un link sotto il file chiama il file download.php che forza automaticamente il download del tuo file sul disco rigido. Ho provato questo sulle ultime versioni di Chrome, Firefox e Safari e funziona benissimo. Ho usato il tema Twenty Twelve, ma nessun motivo per cui non dovrebbe funzionare anche su altri.

a) Aggiungere quanto segue alla fine di functions.php. Questo è semplicemente preso da 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) Copia e incolla quanto segue in un file chiamato download.phpnella directory di base del 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). Non dimenticare di collegarti al file nella galleria !! Importante!


Non credo sia una buona idea, usando download.phpe il $_GETparametro posso scaricare tutti i file che voglio dalla tua cartella web (anche su condivisioni di rete), comewp-config.php
Diego Betto,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.