Skompresuj wszystkie obrazy wyświetlane w [galerii] i zaoferuj jako link do pobrania

13

Chciałbym zaoferować odwiedzającym opcję pobrania całej galerii zdjęć (wyświetlanej na dedykowanych stronach [galerii]) jako pliku ZIP wyświetlanego na dole każdej strony galerii. - Konieczne będzie dołączenie pełnowymiarowego obrazu.

David Walsh dał jakiś kod w swoim poście tutaj aby zapiąć pliki ale mam problemy integracyjne, które z funkcji Wordpress.

Wiem, że istnieje wtyczka pobierania galerii NextGEN, ale nie jestem w stanie jej używać, ponieważ używam natywnych funkcji galerii wordpress.

Podobne pytanie z alternatywną (ręczną metodą) wykonania powyższego można znaleźć tutaj: Wtyczka do pobierania załączonych plików multimedialnych?

Każda pomoc byłaby bardzo mile widziana. Dzięki.

Paul Thomson
źródło
Co rozumiesz przez dedykowane strony galerii?
NoBugs
standardowe posty, które wyświetlają TYLKO shortcode galerii [gallery columns = "4" link = "file"] i żadnych innych treści na stronie. Zawarłem to w opisie, co tylko pomogło programistom.
Paul Thomson,

Odpowiedzi:

14

Najpierw musisz zdobyć obrazy. Jak uzyskać wszystkie obrazy galerii opisano tutaj .

WordPress używa dwóch klas do rozpakowywania plików. Wtargnięcie PHP ZipArchive()(użycie patrz David Walsh). I PclZip , możesz znaleźć tę klasę w wp-admin/includes/class-pclzip.php. Jeśli masz problemy z ZipArchive()wypróbowaniem klasy PclZip.

Teraz musisz po prostu skleić oba razem. Może później mogę opublikować przykładowy kod, obecnie nie ma mnie przy biurku.

Aktualizacja

Twoje pytanie można podzielić na dwie części. Pierwszym z nich jest pobranie wszystkich zdjęć z galerii. Drugi polega na kompresowaniu obrazów i wysyłaniu pliku zip.
Wyjaśnię tylko pierwszą część, uzyskanie wszystkich zdjęć galerii, ponieważ spakowanie plików jest nieco nie na temat.

Być może istnieją inne rozwiązania, ale w tym przykładzie zamieniam oryginalny skrót galerii na niestandardowy, aby uzyskać obrazy. Powodem jest to, że WordPress nieco zmienił galerie w wersji 3.5.
Przed wersją 3.5 obrazy do galerii są załącznikami postu. Po 3.5 obrazy są przekazywane jako krótki kod jako atrybut. Ponieważ WP3.5 nie możemy już uzyskać załączonych obrazów postu, musimy pobrać listę z atrybutów shortcode. Moją strategią jest zastąpienie oryginalnego kodu krótkiego niestandardowym kodem, pobranie atrybutów i wywołanie oryginalnego kodu, aby uzyskać wynik galerii.

Wszystkie rzeczy związane z galerią należą do klasy. Aby utworzyć plik zip, możemy użyć innej klasy, która przyjmuje jako dane wyjściowe klasy galerii. Zacznijmy od klasy i prostego konstruktora.

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

Wywołamy tę metodę get_instance()później we wtyczce z hakiem plugins_loaded. W konstruktorze usuwamy oryginalny skrót i zastępujemy go naszym niestandardowym skrótem gallery_zip_shortcode(). Teraz potrzebujemy oddzwonienia 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;

}

Pierwszą rzeczą w tej metodzie jest uzyskanie posta, ponieważ potrzebujemy jego identyfikatora. Niż ten dołączamy wp-includes/media.php, ten plik zawiera funkcję wywołania zwrotnego dla oryginalnego skrótu galerii. Teraz wywołujemy metodę uzyskania tablicy ze wszystkimi obrazami, tworzymy wyjście galerii, wywołując oryginalne wywołanie zwrotne galerii, tworzymy link i dołączamy link do wyjścia galerii. Same obrazy, odpowiednio ścieżki do obrazów, są przechowywane w zmiennej klasy $images, potrzebujemy tej tablicy później.
Zmienna class $imagezawiera wpis dla każdego postu z galerią, dzięki czemu możemy użyć funkcji na pierwszej stronie lub w pojedynczym widoku. Każdy wpis zawiera tablicę dla każdej galerii, ponieważ w każdym poście może znajdować się więcej niż jedna galeria.

Rdzeniem wtyczki jest metoda uzyskiwania obrazów z krótkiego kodu.

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;

}

Najpierw decydujemy, czy jest to pojedynczy post, czy lista identyfikatorów postów. Jeśli jest to lista identyfikatorów postów, obsługujemy galerię z wersji WP3.5 +. Następnie musimy obsłużyć excludeatrybut. Po skonfigurowaniu wszystkich zmiennych możemy wreszcie pobrać obrazy z galerii. Pobrane obrazy zostaną przeniesione do var klasy $imagesdo późniejszego wykorzystania.

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

To jest złoto wtyczki. Wystarczy ustawić tablicę z argumentami zapytania, pobrać załączniki get_posts()i przejrzeć pobrane załączniki. Aby obsłużyć różne rozmiary, otrzymujemy obraz załącznika i pasek adresu URL. Z załączonego pliku bierzemy ścieżkę i łączymy ją z nazwą pliku. W tablicy $imagessą teraz wszystkie obrazy i ich ścieżki z galerii.

Zasadniczo odpowiedź na twoje pytanie jest w tym momencie. Ale chcesz również utworzyć plik zip z obrazów. Możesz utworzyć plik zip z tablicy $imagesw ostatniej metodzie. Ale ta metoda jest wywoływana za każdym razem, gdy wyświetlana jest galeria, a utworzenie pliku zip może chwilę potrwać. Może nikt nie poprosiłby o utworzony tutaj plik zip, to marnowanie zasobów.

Jak możemy to zrobić lepiej? Czy pamiętasz, że umieściłem wszystkie obrazy w zmiennej klasy $images? Możemy użyć tej klasy var do żądania ajax. Ale żądanie ajax to tylko kolejne ładowanie strony i możemy uzyskać dostęp do obrazów tylko wtedy, gdy tworzony jest wynik galerii. Musimy zapisać nasze zdjęcia w miejscu, w którym możemy uzyskać do nich dostęp nawet po kolejnym żądaniu strony.
W tym przykładzie używam zmiennej sesji do przechowywania tablicy z obrazami. Dostęp do zmiennej sesji można uzyskać nawet po ponownym załadowaniu innej strony. Aby zapisać obrazy, rejestruję metodę za pomocą shutdownhaka. Po zakończeniu renderowania strony przez WordPress shutdownhak zostanie wywołany. W tym momencie powinniśmy zebrać wszystkie obrazy ze wszystkich wyświetlanych galerii. Po prostu przechowujemy obrazy i możemy uzyskać do nich dostęp w żądaniu ajax.

Po uruchomieniu żądania ajax przywołujemy zmienną sesji i tworzymy plik zip z danych. Ale to trochę nie na temat tego pytania.

Utworzyłem repozytorium na GitHub z pełnym kodem wtyczki. Mam nadzieję, że wskaże ci właściwy kierunek.

Ralf912
źródło
zwróć uwagę, że jeśli masz do czynienia z nowymi galeriami w stylu 3.5, ta metoda pobierania obrazów z galerii może nie działać.
Milo
Aby to wyjaśnić, używam najnowszej wersji Wordpress 3.5.1. Johannes, byłbym bardzo wdzięczny, gdybyś był w stanie podać przykładowy kod, gdy będziesz następny na pulpicie. Dzięki, Paul
Paul Thomson,
Hej, Ralf, to fantastyczna praca! Dzięki za udostępnienie. Aby obrazy mojej galerii były wyświetlane poprawnie, muszę umieścić link = "plik" w krótkim kodzie, tj .: [link do galerii = "plik"], ponieważ kod jest ponownie zapisywany w twoim kodzie, myślę, że został pominięty i jako wynik moje galerie nie są wyświetlane poprawnie. Czy jest jakiś sposób, aby naprawić ten argument w kodzie?
Paul Thomson
Zwykle atrybuty są po prostu przekazywane do oryginalnego krótkiego kodu i nie będą modyfikowane. Galerie są wyświetlane normalnie, ale z dołączonym kodem HTML. W moich testach (z motywem dwudziestu dwunastu standradów) galerie są wyświetlane poprawnie.
Ralf912
@PaulThomson Naprawiłem niektóre problemy w repozytorium github. Kod nie był czysty.
Ralf912
0

Podoba mi się pomysł, aby wtyczka Ralfa mogła pobierać całą galerię za jednym razem, ale nie udało mi się sprawić, żeby działała. Wymyśliłem obejście, które działa dla naszych celów. Metoda polega na zamianie natywnej galerii WP na własną, którą umieszczasz na końcu functions.phppliku motywu ORAZ dodaj następujący plik, nazwany download.phpw aktywnym folderze motywu. W galerii niestandardowej link pod plikiem wywołuje plik download.php, który automatycznie wymusza pobranie pliku na dysk twardy. Przetestowałem to w najnowszych wersjach Chrome, Firefox i Safari i działa dobrze. Używam motywu Twenty Twelve, ale nie ma powodu, dla którego nie powinien on działać również na innych.

a) Dodaj następujące na końcu functions.php. Jest to po prostu wzięte z 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) Skopiuj i wklej następujące elementy do pliku wywoływanego download.phpw katalogu podstawowym motywu.

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

do). Nie zapomnij o linku do pliku w galerii !! Ważny!

Sam Edgecombe
źródło
Nie sądzę, że jest to dobry pomysł, używając download.phpi $_GETparametru, który mogę pobrać wszystkie pliki, które chcę z twojego folderu internetowego (również z udziałów sieciowych), na przykładwp-config.php
Diego Betto