ZIP toutes les images affichées dans une [galerie] et offrir comme lien de téléchargement

13

Je voudrais offrir à mes visiteurs la possibilité de télécharger l'intégralité de la galerie de photos (affichée sur les pages [galerie] dédiées) sous forme de fichier ZIP affiché au bas de chaque page de la galerie. - L'image en taille réelle devra être incluse.

David Walsh a donné du code dans son article ici pour compresser les fichiers, mais j'ai du mal à l'intégrer aux fonctions Wordpress.

Je suis conscient qu'il existe un plugin de téléchargement de galerie NextGEN mais je ne suis pas en mesure de l'utiliser car j'utilise les fonctions natives de la galerie wordpress.

Une question similaire avec une alternative (méthode manuelle) pour compléter ce qui précède peut être trouvée ici: Plugin pour télécharger les fichiers multimédias joints?

Toute aide serait grandement appréciée. Merci.

Paul Thomson
la source
Qu'entendez-vous par pages de galerie dédiées?
NoBugs
publications standard qui affichent UNIQUEMENT le shortcode de la galerie [gallery columns = "4" link = "file"] et aucun autre contenu sur la page. J'ai inclus cela dans la description au cas où cela aiderait les développeurs.
Paul Thomson

Réponses:

14

Vous devez d'abord obtenir les images. Comment obtenir toutes les images d'une galerie est décrit ici .

WordPress utilise deux classes pour décompresser les fichiers. PHP bilt in ZipArchive()(utilisation voir David Walsh). Et PclZip , vous pouvez trouver cette classe dans wp-admin/includes/class-pclzip.php. Si vous avez des problèmes avec ZipArchive()la classe PclZip.

Il ne vous reste plus qu'à coller les deux ensemble. Je peux peut-être poster un exemple de code plus tard, actuellement je ne suis pas à mon bureau.

Mise à jour

Votre question peut être divisée en deux parties. Le premier obtient toutes les images d'une galerie. Le second zippe les images et envoie le fichier zip.
Je vais seulement expliquer la première partie, obtenir toutes les images d'une galerie, car la fermeture éclair des fichiers est légèrement hors sujet.

Il existe peut-être d'autres solutions, mais dans cet exemple, je remplace le shortcode de la galerie d'origine par un personnalisé pour obtenir les images. La raison en est que WordPress a un peu changé les galeries en v3.5.
Avant la 3.5, les images d'une galerie sont des pièces jointes de l'article. Après 3.5, les images sont transmises au shortcode en tant qu'attribut. Depuis WP3.5, nous ne pouvons plus obtenir les images jointes d'un message, nous devons récupérer la liste à partir des attributs de shortcode. Ma stratégie consiste à remplacer le shortcode d'origine par un shortcode personnalisé, récupérer les attributs et appeler le shortcode d'origine pour obtenir la sortie de la galerie.

Toutes les choses liées à la galerie sont dans une classe. Pour créer un fichier zip, nous pouvons utiliser une autre classe qui prend en entrée la sortie de la classe gallery. Commençons par une classe et un constructeur simple.

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

Nous appellerons la méthode get_instance()plus tard dans le plugin avec le hook plugins_loaded. Dans le constructeur, nous supprimons le shortcode d'origine et le remplaçons par notre shortcode personnaliségallery_zip_shortcode() . Maintenant, nous avons besoin du rappel de 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 première chose dans cette méthode est d'obtenir le message car nous avons besoin de l'ID du message. Que nous incluons wp-includes/media.php, ce fichier contient la fonction de rappel pour le shortcode de la galerie d'origine. Maintenant, nous appelons une méthode pour obtenir un tableau avec toutes les images, créer la sortie de la galerie en appelant le rappel de la galerie d'origine, créer un lien et ajouter le lien à la sortie de la galerie. Les images elles-mêmes, respectivement les chemins d'accès aux images, sont stockées dans la variable de classe $images, nous aurons besoin de ce tableau plus tard.
La variable de classe $imagecontient une entrée pour chaque article avec une galerie, nous pouvons donc utiliser la fonction en première page ou en vue unique. Chaque entrée contient un tableau pour chaque galerie, car il peut y avoir plus d'une galerie dans chaque publication.

Le cœur du plugin est la méthode pour obtenir les images du 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;

}

Dans un premier temps, nous décidons s'il s'agit d'un poste unique ou d'une liste d'ID de poste. S'il s'agit d'une liste d'ID de publication, nous gérons une galerie de WP3.5 +. Après cela, nous devons gérer l' excludeattribut. Après avoir configuré toutes les variables, nous pouvons enfin obtenir les images de la galerie. Les images récupérées seront poussées dans la classe var $imagespour une utilisation ultérieure.

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

Ceci est l'or du plugin. Configurez simplement un tableau avec des arguments de requête, récupérez les pièces jointes avec get_posts()et parcourez les pièces jointes récupérées. Pour gérer différentes tailles, nous obtenons l'image de la pièce jointe et la bande de l'url. À partir du fichier joint, nous prenons le chemin et le mettons ensemble avec le nom de fichier. Dans le tableau $imagessont maintenant toutes les images et leurs chemins de la galerie.

Fondamentalement, votre question reçoit une réponse à ce stade. Mais vous souhaitez également créer un fichier zip à partir des images. Vous pouvez créer un fichier zip à partir du tableau$images dans la dernière méthode. Mais cette méthode est appelée à chaque fois qu'une galerie est affichée et la création d'un fichier zip peut prendre un certain temps. Peut-être que personne ne demanderait le fichier zip que vous avez créé ici, c'est un gaspillage de ressources.

Comment pouvons-nous faire mieux? Vous souvenez-vous que j'ai mis toutes les images dans la variable de classe $images? Nous pouvons utiliser cette classe var pour une requête ajax. Mais une requête ajax n'est qu'un chargement de page supplémentaire et nous ne pouvons accéder aux images que lorsque la sortie de la galerie est créée. Nous devons enregistrer nos images dans un endroit où nous pouvons y accéder même après une autre demande de page.
Dans cet exemple, j'utilise une variable de session pour stocker le tableau avec des images. Une variable de session est accessible même après un autre rechargement de page. Pour stocker les images, j'enregistre une méthode avec le shutdowncrochet. Une fois que WordPress a terminé de rendre la page, le shutdowncrochet sera appelé. À ce stade, nous aurions dû collecter toutes les images de toutes les galeries affichées. Nous stockons simplement les images et pouvons y accéder dans une demande ajax.

Lorsque la demande ajax est déclenchée, nous rappelons la session var et créons un fichier zip à partir des données. Mais c'est un peu hors sujet pour cette question.

J'ai créé un référentiel sur GitHub avec le code complet du plugin. J'espère que cela vous indique la bonne direction.

Ralf912
la source
notez que si vous avez affaire à de nouvelles galeries de style 3.5, cette méthode pour récupérer des images d'une galerie peut ne pas fonctionner pour vous.
Milo
Pour clarifier, j'utilise la dernière version de Wordpress 3.5.1. Johannes, je vous serais extrêmement reconnaissant de bien vouloir fournir un exemple de code lors de votre prochaine visite sur votre bureau. Merci, Paul
Paul Thomson
Hé Ralf, c'est un travail fantastique! Merci d'avoir partagé. Pour que mes images de galerie s'affichent correctement, je dois inclure link = "file" dans le shortcode, c'est-à-dire: [gallery link = "file"] car le shortcode est réécrit à travers votre code, je pense qu'il est laissé de côté et en tant que résultat mes galeries ne s'affichent pas correctement. Existe-t-il un moyen de corriger cet argument dans votre code?
Paul Thomson
Normalement, les attributs sont simplement transmis au shortcode d'origine et ne seront pas modifiés. Les galeries sont affichées comme d'habitude, mais avec du HTML en annexe. Dans mes tests (avec vingt-douze thèmes standards), les galeries s'affichent correctement.
Ralf912
@PaulThomson J'ai corrigé quelques problèmes dans le dépôt github. Le code n'était pas propre.
Ralf912
0

J'aime l'idée que le plugin de Ralf puisse télécharger une galerie entière en une seule fois, mais je n'ai pas pu le faire fonctionner. J'ai trouvé une solution de contournement qui fonctionne pour nos besoins. La méthode consiste à remplacer la galerie WP native par la vôtre que vous placez à la fin du functions.phpfichier de votre thème ET ajoutez le fichier suivant, nommé download.phpdans le dossier de thème actif. Dans la galerie personnalisée, un lien sous le fichier appelle le fichier download.php qui force automatiquement le téléchargement de votre fichier sur le disque dur. J'ai testé cela sur les dernières versions de Chrome, Firefox et Safari et cela fonctionne très bien. J'ai utilisé le thème Twenty Twelve, mais aucune raison pour laquelle il ne devrait pas fonctionner sur d'autres.

a) Ajoutez ce qui suit à la fin de functions.php. Ceci est simplement extrait de 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) Copiez et collez ce qui suit dans un fichier appelé download.phpdans le répertoire de base du thème.

<?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'oubliez pas de créer un lien vers le fichier dans la galerie !! Important!

Sam Edgecombe
la source
Je ne pense pas que ce soit une bonne idée, en utilisant download.phpet le $_GETparamètre que je peux télécharger tous les fichiers que je veux à partir de votre dossier Web (également sur les partages réseau), commewp-config.php
Diego Betto