ZIP semua gambar yang ditampilkan di [galeri] dan tawarkan sebagai tautan unduhan

13

Saya ingin menawarkan kepada pengunjung saya opsi untuk mengunduh seluruh galeri foto (ditampilkan pada halaman [galeri] khusus) sebagai file ZIP yang ditampilkan di bagian bawah setiap halaman galeri. - Gambar berukuran penuh harus dimasukkan.

David Walsh telah memberikan beberapa kode dalam postingannya di sini untuk mem-zip file tetapi saya mengalami kesulitan mengintegrasikannya dengan fungsi Wordpress.

Saya sadar ada plugin unduhan galeri NextGEN tapi saya tidak dalam posisi untuk menggunakannya karena saya menggunakan fungsi galeri wordpress asli.

Pertanyaan serupa dengan alternatif (metode manual) untuk menyelesaikan hal di atas dapat ditemukan di sini: Plugin untuk mengunduh file media terlampir?

Bantuan apa pun akan sangat dihargai. Terima kasih.

Paul Thomson
sumber
Apa yang Anda maksud dengan halaman galeri khusus?
NoBugs
posting standar yang hanya menampilkan kode pendek galeri [kolom kolom = "4" tautan = "file"] dan tidak ada konten lain pada halaman. Saya memasukkan bahwa dalam deskripsi hanya memetikannya membantu pengembang.
Paul Thomson

Jawaban:

13

Pertama, Anda harus mendapatkan gambar. Cara mendapatkan semua gambar galeri dijelaskan di sini .

WordPress menggunakan dua kelas untuk membuka ritsleting file. PHP bilt in ZipArchive()(penggunaan lihat David Walsh). Dan PclZip , Anda dapat menemukan kelas ini di wp-admin/includes/class-pclzip.php. Jika Anda punya masalah denganZipArchive() mencoba kelas PclZip.

Sekarang Anda hanya harus menempelkan keduanya. Mungkin saya dapat memposting beberapa kode sampel nanti, saat ini saya tidak di meja saya.

Memperbarui

Pertanyaan Anda dapat dibagi menjadi dua bagian. Yang pertama adalah mendapatkan semua gambar dari galeri. Yang kedua adalah zip gambar dan mengirim file zip.
Saya hanya akan menjelaskan bagian pertama, mendapatkan semua gambar dari galeri, karena ripping file agak offtopic.

Mungkin ada solusi lain, tetapi dalam contoh ini saya mengganti shortcode galeri asli dengan yang kustom untuk mendapatkan gambar. Alasannya, WordPress mengubah galeri di v3.5 sedikit.
Sebelum 3.5, gambar untuk galeri adalah lampiran posting. Setelah 3.5, gambar dilewatkan ke kode pendek sebagai atribut. Karena WP3.5 kita tidak bisa lagi mendapatkan gambar lampiran dari sebuah posting, kita harus mengambil daftar dari atribut shortcode. Strategi saya adalah mengganti kode pendek asli dengan kode pendek khusus, ambil atribut dan panggil kode pendek asli untuk mendapatkan output galeri.

Semua hal yang berhubungan dengan galeri berada dalam kelas. Untuk membuat file zip, kita bisa menggunakan kelas lain yang mengambil input dari kelas galeri. Mari kita mulai dengan kelas dan konstruktor sederhana.

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

Kami akan memanggil metode get_instance()nanti di plugin dengan hook plugins_loaded. Di konstruktor, kami menghapus kode pendek asli dan menggantinya dengan kode pendek khusus kami gallery_zip_shortcode(). Sekarang kita membutuhkan panggilan balik kode pendek

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;

}

Hal pertama dalam metode ini adalah mendapatkan posting karena kita membutuhkan ID posting. Selain kami sertakan wp-includes/media.php, file ini berisi fungsi panggilan balik untuk kode singkat galeri asli. Sekarang kita memanggil metode untuk mendapatkan array dengan semua gambar, membuat output galeri dengan memanggil callback galeri asli, membuat tautan dan menambahkan tautan ke output galeri. Gambar itu sendiri, masing-masing jalur ke gambar, disimpan dalam variabel kelas $images, kita perlu array ini nanti.
Variabel kelas $imagemenyimpan entri untuk setiap posting dengan galeri, sehingga kita dapat menggunakan fungsi baik di halaman depan atau dalam tampilan tunggal. Setiap entri berisi larik untuk setiap galeri, karena mungkin ada lebih dari satu galeri di setiap kiriman.

Inti dari plugin adalah metode untuk mendapatkan gambar dari kode pendek.

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;

}

Pada awalnya kami memutuskan apakah itu satu posting atau daftar ID posting. Jika ini adalah daftar ID kiriman, kami menangani galeri dari WP3.5 +. Setelah itu, kita harus menangani excludeatributnya. Setelah mengatur semua variabel, kami akhirnya bisa mendapatkan gambar dari galeri. Gambar yang diambil akan didorong ke kelas var $imagesuntuk digunakan nanti.

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

Ini adalah emas dari plugin. Cukup siapkan array dengan argumen kueri, dapatkan lampirannya get_posts()dan berjalan di atas lampiran yang diambil. Untuk menangani ukuran yang berbeda, kami mendapatkan gambar lampiran dan strip url. Dari file terlampir, kami mengambil path dan menggabungkannya dengan nama file. Dalam array $imagessekarang semua gambar dan jalurnya dari galeri.

Pada dasarnya pertanyaan Anda dijawab pada saat ini. Tetapi Anda juga ingin membuat file zip dari gambar. Anda bisa membuat file zip dari array $imagesdi metode terakhir. Tetapi metode ini disebut setiap kali galeri ditampilkan dan membuat file zip bisa memakan waktu cukup lama. Mungkin tidak ada yang akan meminta file zip yang Anda buat di sini, ini adalah pemborosan sumber daya.

Bagaimana kita bisa melakukannya dengan lebih baik? Apakah Anda ingat bahwa saya meletakkan semua gambar dalam variabel kelas $images? Kita bisa menggunakan var kelas ini untuk permintaan ajax. Tetapi permintaan ajax hanyalah pemuatan halaman lain dan kita hanya dapat mengakses gambar ketika output galeri dibuat. Kita harus menyimpan gambar kita di tempat di mana kita dapat mengaksesnya bahkan setelah permintaan halaman lain.
Dalam contoh ini saya menggunakan variabel sesi untuk menyimpan array dengan gambar. Variabel sesi dapat diakses bahkan setelah halaman lain dimuat ulang. Untuk menyimpan gambar, saya mendaftarkan metode dengan shutdownhook. Setelah WordPress selesai merender halaman, shutdownhook akan dipanggil. Pada titik ini, kita seharusnya sudah mengumpulkan semua gambar dari semua galeri yang ditampilkan. Kami hanya menyimpan gambar dan dapat mengaksesnya dalam permintaan ajax.

Ketika permintaan ajax dipicu, kami mengingat sesi var dan membuat file zip dari data. Tapi ini agak aneh untuk pertanyaan ini.

Saya membuat repositori di GitHub dengan kode plugin lengkap. Saya harap ini menunjukkan Anda ke arah yang benar.

Ralf912
sumber
perhatikan bahwa jika Anda berurusan dengan galeri 3,5 gaya baru, metode untuk mengambil gambar dari galeri mungkin tidak cocok untuk Anda.
Milo
Untuk memperjelas saya menggunakan versi terbaru dari Wordpress 3.5.1. Johannes, saya akan sangat berterima kasih jika Anda bisa memberikan beberapa kode contoh saat Anda berikutnya di desktop Anda. Terima kasih, Paul
Paul Thomson
Hei Ralf, ini pekerjaan yang fantastis! Terima kasih telah berbagi. Agar gambar galeri saya dapat ditampilkan dengan benar, saya harus memasukkan tautan = "file" yaitu: [galeri tautan = "file"] karena kode pendek tersebut ditulis ulang melalui kode Anda, saya pikir sedang ditinggalkan dan sebagai hasil galeri saya tidak ditampilkan dengan benar. Apakah ada cara untuk memperbaiki argumen itu ke dalam kode Anda?
Paul Thomson
Biasanya atribut hanya diteruskan ke kode pendek asli dan tidak akan dimodifikasi. Galeri ditampilkan seperti biasa, tetapi dengan beberapa HTML ditambahkan. Dalam pengujian saya (dengan tema dua puluh dua standrad) galeri ditampilkan dengan benar.
Ralf912
@ PaulThomson Saya memperbaiki beberapa masalah di repositori github. Kode tidak bersih.
Ralf912
0

Saya menyukai gagasan plugin Ralf untuk dapat mengunduh seluruh galeri dalam sekali jalan, tetapi saya belum dapat membuatnya berfungsi. Saya telah menemukan solusi yang berfungsi untuk tujuan kita. Metode ini adalah mengganti galeri WP asli dengan galeri Anda sendiri yang Anda tempatkan di akhir functions.phpfile tema Anda DAN tambahkan file berikut ini, beri nama download.phpke dalam folder tema aktif. Di galeri khusus, tautan di bawah file tersebut memanggil file download.php yang secara otomatis memaksa unduhan file Anda ke hard drive. Saya telah menguji ini pada versi Chrome, Firefox dan Safari terbaru dan berfungsi dengan baik. Telah menggunakan tema Twenty Twelve, tetapi tidak ada alasan mengapa itu tidak bisa bekerja pada yang lain juga.

a) Tambahkan berikut ini ke akhir functions.php. Ini hanya diambil dari 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) Salin dan tempel yang berikut ke dalam file yang disebut download.phpdi direktori dasar 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). Jangan lupa untuk menautkan ke file di galeri !! Penting!

Sam Edgecombe
sumber