ZIP lên tất cả các hình ảnh được hiển thị trong [bộ sưu tập] và cung cấp dưới dạng liên kết tải xuống


13

Tôi muốn cung cấp cho khách truy cập của mình tùy chọn tải xuống toàn bộ thư viện ảnh (được hiển thị trên các trang [thư viện] chuyên dụng) dưới dạng tệp ZIP được hiển thị ở cuối mỗi trang thư viện. - Hình ảnh kích thước đầy đủ sẽ phải được bao gồm.

David Walsh đã đưa ra một số mã trong bài đăng của mình ở đây để nén các tệp nhưng tôi gặp khó khăn khi tích hợp nó với các chức năng của Wordpress.

Tôi biết rằng có một plugin tải xuống thư viện NextGEN nhưng tôi không ở vị trí để sử dụng nó khi tôi sử dụng các chức năng thư viện wordpress bản địa.

Một câu hỏi tương tự với một phương pháp thay thế (phương pháp thủ công) để hoàn thành các điều trên có thể được tìm thấy ở đây: Plugin để tải xuống các tệp phương tiện đính kèm?

Mọi sự trợ giúp sẽ rất được trân trọng. Cảm ơn.


Bạn có ý nghĩa gì bởi các trang thư viện dành riêng?
NoBugs

bài viết tiêu chuẩn chỉ hiển thị mã ngắn thư viện [cột thư viện = "4" link = "tệp"] và không có nội dung nào khác trên trang. Tôi đã bao gồm điều đó trong phần mô tả chỉ cần nó giúp các nhà phát triển.
Paul Thomson

Câu trả lời:


13

Đầu tiên bạn phải có được những hình ảnh. Làm thế nào để có được tất cả các hình ảnh của một bộ sưu tập được mô tả ở đây .

WordPress sử dụng hai lớp để giải nén các tập tin. Các bilt PHP trong ZipArchive()(sử dụng xem David Walsh). Và PclZip , bạn có thể tìm thấy lớp này trong wp-admin/includes/class-pclzip.php. Nếu bạn gặp vấn đề với ZipArchive()hãy thử lớp PclZip.

Bây giờ bạn chỉ cần phải dán cả hai với nhau. Có lẽ tôi có thể đăng một số mã mẫu sau, hiện tại tôi không ở bàn làm việc của mình.

Cập nhật

Câu hỏi của bạn có thể được chia thành hai phần. Người đầu tiên nhận được tất cả hình ảnh từ một bộ sưu tập. Cái thứ hai là nén hình ảnh và gửi tệp zip.
Tôi sẽ chỉ giải thích phần đầu tiên, lấy tất cả hình ảnh của một bộ sưu tập, bởi vì việc nén các tập tin hơi khác thường.

Có thể có các giải pháp khác, nhưng trong ví dụ này tôi thay thế shortcode bộ sưu tập ban đầu bằng một tùy chỉnh để lấy hình ảnh. Lý do là, WordPress đã thay đổi các phòng trưng bày trong phiên bản 3.5 một chút.
Trước 3.5, hình ảnh cho một bộ sưu tập là tệp đính kèm của bài đăng. Sau 3.5, các hình ảnh được chuyển đến shortcode dưới dạng một thuộc tính. Vì WP3.5, chúng tôi không thể nhận được các hình ảnh đính kèm của bài đăng, chúng tôi phải tìm nạp danh sách từ các thuộc tính shortcode. Chiến lược của tôi là thay thế mã ngắn ban đầu bằng một mã ngắn tùy chỉnh, lấy các thuộc tính và gọi mã ngắn gốc để lấy đầu ra của thư viện.

Tất cả những thứ liên quan đến bộ sưu tập là trong một lớp học. Để tạo một tệp zip, chúng ta có thể sử dụng một lớp khác lấy đầu vào là đầu ra của lớp bộ sưu tập. Hãy bắt đầu với một lớp và một hàm tạo đơn giản.

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

Chúng ta sẽ gọi phương thức get_instance()sau trong plugin bằng hook plugins_loaded. Trong hàm tạo, chúng tôi xóa mã ngắn ban đầu và thay thế bằng mã ngắn tùy chỉnh gallery_zip_shortcode(). Bây giờ chúng ta cần gọi lại 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;

}

Điều đầu tiên trong phương pháp này là để có được bài viết vì chúng ta cần ID bài đăng. Hơn chúng tôi bao gồm wp-includes/media.php, tệp này chứa chức năng gọi lại cho mã ngắn thư viện gốc. Bây giờ chúng ta gọi một phương thức để có được một mảng với tất cả các hình ảnh, tạo đầu ra của thư viện bằng cách gọi lại cuộc gọi bộ sưu tập ban đầu, tạo một liên kết và nối thêm liên kết vào đầu ra của thư viện. Các hình ảnh, tương ứng các đường dẫn đến hình ảnh, được lưu trữ trong biến lớp $images, chúng ta cần mảng này sau.
Biến lớp $imagegiữ một mục nhập cho mỗi bài đăng với một bộ sưu tập, vì vậy chúng ta có thể sử dụng chức năng này trên frontpage hoặc trong một chế độ xem. Mỗi mục chứa một mảng cho mỗi thư viện, bởi vì có thể có nhiều hơn một thư viện trong mỗi bài.

Cốt lõi của plugin là phương pháp để lấy hình ảnh từ 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;

}

Đầu tiên, chúng tôi quyết định nếu đó là một bài đăng hoặc một danh sách ID bài đăng. Nếu đó là danh sách ID bài đăng, chúng tôi sẽ xử lý một thư viện từ WP3.5 +. Sau đó, chúng ta phải xử lý excludethuộc tính. Sau khi thiết lập tất cả các varibles, cuối cùng chúng ta có thể lấy hình ảnh từ thư viện. Các hình ảnh được gỡ lại sẽ được đẩy vào var lớp $imagesđể sử dụng sau.

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

Đây là vàng của plugin. Đơn giản chỉ cần thiết lập một mảng với các đối số truy vấn, nhận các tệp đính kèm get_posts()và đi qua các tệp đính kèm được truy xuất. Để xử lý các kích thước khác nhau, chúng tôi lấy hình ảnh đính kèm và dải url. Từ tệp đính kèm, chúng tôi lấy đường dẫn và đặt nó cùng với tên tệp. Trong mảng $imagesbây giờ là tất cả các hình ảnh và đường dẫn của chúng từ bộ sưu tập.

Về cơ bản câu hỏi của bạn được trả lời tại thời điểm này. Nhưng bạn cũng muốn tạo tệp zip từ hình ảnh. Bạn có thể tạo một tệp zip từ mảng $imagestrong phương thức cuối cùng. Nhưng phương pháp này được gọi mỗi khi một thư viện được hiển thị và việc tạo tệp zip có thể mất một lúc. Có lẽ không ai sẽ yêu cầu tệp zip bạn tạo ở đây, đây là một sự lãng phí tài nguyên.

Làm thế nào chúng ta có thể làm điều đó tốt hơn? Bạn có nhớ rằng tôi đặt tất cả các hình ảnh trong biến lớp $imageskhông? Chúng ta có thể sử dụng var lớp này cho một yêu cầu ajax. Nhưng một yêu cầu ajax chỉ là một tải trang khác và chúng ta chỉ có thể truy cập các hình ảnh khi đầu ra của thư viện được tạo. Chúng tôi phải lưu hình ảnh của chúng tôi ở một nơi mà chúng tôi có thể truy cập chúng ngay cả sau khi yêu cầu trang khác.
Trong ví dụ này tôi sử dụng biến phiên để lưu trữ mảng bằng hình ảnh. Một biến phiên có thể được truy cập ngay cả sau khi tải lại trang khác. Để lưu trữ hình ảnh, tôi đăng ký một phương thức với shutdownhook. Sau khi WordPress kết xuất trang xong, shutdownhook sẽ được gọi. Tại thời điểm này, chúng ta nên thu thập tất cả các hình ảnh từ tất cả các phòng trưng bày được hiển thị. Chúng tôi chỉ cần lưu trữ hình ảnh và có thể truy cập chúng trong một yêu cầu ajax.

Khi yêu cầu ajax được kích hoạt, chúng tôi gọi lại var phiên và tạo tệp zip từ dữ liệu. Nhưng đây là một chủ đề hơi xa cho câu hỏi này.

Tôi đã tạo một kho lưu trữ trên GitHub với mã plugin hoàn chỉnh. Tôi hy vọng nó chỉ cho bạn đi đúng hướng.


lưu ý rằng nếu bạn đang xử lý các phòng trưng bày kiểu 3,5 mới, phương pháp đó để truy xuất hình ảnh từ thư viện có thể không hiệu quả với bạn.
Milo

Để làm rõ, tôi đang sử dụng phiên bản Wordpress 3.5.1 mới nhất. Xin chào, tôi sẽ rất biết ơn nếu bạn có thể cung cấp một số mã mẫu khi bạn ở bên cạnh máy tính để bàn của bạn. Cảm ơn, Paul
Paul Thomson

Này Ralf, đây là một công việc tuyệt vời! Cám ơn vì đã chia sẻ. Để hình ảnh bộ sưu tập của tôi hiển thị chính xác, tôi phải đưa link = "file" vào shortcode tức là: [gallery link = "file"] vì shortcode được viết lại thông qua mã của bạn, tôi nghĩ rằng nó bị bỏ lại và như một kết quả phòng trưng bày của tôi không được hiển thị chính xác. Có cách nào để sửa đối số đó vào mã của bạn không?
Paul Thomson

Thông thường các thuộc tính chỉ đơn giản được chuyển qua shortcode gốc và sẽ không được sửa đổi. Các phòng trưng bày được hiển thị như bình thường, nhưng có thêm một số HTML. Trong các thử nghiệm của tôi (với hai mươi hai chủ đề standrad), các phòng trưng bày được hiển thị chính xác.
Ralf912

@PaulThomson Tôi đã sửa một số vấn đề trong kho github. Mã không sạch.
Ralf912

0

Tôi thích ý tưởng về plugin của Ralf để có thể tải xuống toàn bộ thư viện trong một lần, nhưng tôi không thể làm cho nó hoạt động được. Tôi đã đưa ra một cách giải quyết phù hợp với mục đích của chúng tôi. Phương pháp này là thay thế thư viện WP gốc bằng thư viện riêng của bạn mà bạn đặt ở cuối functions.phptệp của chủ đề VÀ thêm tệp sau, được đặt tên download.phpvào thư mục chủ đề đang hoạt động. Trong thư viện tùy chỉnh, một liên kết trong tệp gọi tệp download.php sẽ tự động buộc tải tệp của bạn xuống ổ cứng. Tôi đã thử nghiệm điều này trên các phiên bản Chrome, Firefox và Safari mới nhất và nó hoạt động tốt. Đã sử dụng chủ đề Twenty Tw 12, nhưng không có lý do tại sao nó không hoạt động trên các chủ đề khác.

a) Thêm phần sau vào cuối functions.php. Điều này chỉ đơn giản là lấy từ 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) Sao chép và dán đoạn sau vào một tệp được gọi download.phptrong thư mục cơ sở của chủ đề.

<?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). Đừng quên liên kết đến tập tin trong bộ sưu tập !! Quan trọng!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.