問題描述

我想向訪問者提供下載整個照片庫的選項 (顯示在專用 [相簿] 頁面上) 作為每個相簿頁面底部顯示的 ZIP 檔案。 – 必須包括 full-sized 影像。

David Walsh 在他的帖子 here 中給了一些程式碼來壓縮檔案,但是我遇到了與 Wordpress 功能整合的麻煩。

我知道有一個 NextGEN 相簿下載外掛,但我不能使用,因為我使用本機 wordpress 畫廊功能。

有關完成以上操作的另一種 (手動方法) 的類似問題可以在這裡找到:Plugin to download attached media files?

任何幫助將不勝感激。謝謝。

最佳解決方案

首先你必須得到影像。如何獲取相簿的所有影像描述為 here

WordPress 使用兩個類來解壓檔案。 PHP 在 ZipArchive()中使用 (用法見 David Walsh) 。和 PclZip,你可以在 wp-admin/includes/class-pclzip.php 中找到這個類。如果您有 ZipArchive()的問題,請嘗試使用 PclZip 類。

現在你只需要粘在一起。也許我可以稍後再發一些示例程式碼,目前我不在我的桌子上。

更新

你的問題可以分為兩部分。第一個是從畫廊獲取所有影像。第二個是壓縮影像併傳送 zip 檔案。我將僅解釋第一部分,獲取畫廊的所有影像,因為壓縮檔案略有偏離。

也許還有其他的解決方案,但在這個例子中,我用原來的相簿短程式碼來替換圖片。原因是 WordPress 在 v3.5 中改變了畫廊。在 3.5 之前,畫廊的圖片是帖子的附件。 3.5 之後,將影像作為屬性傳遞給短碼。由於 WP3.5 我們不能再收到附件的貼子,所以我們必須從短程式碼屬性中獲取列表。我的策略是用自定義的短程式碼替換原始的短碼,抓住屬性,並呼叫原始的短碼來獲得相簿的輸出。

所有畫廊的相關內容都在課堂內。要建立一個 zip 檔案,我們可以使用另一個類作為輸入的 gallery 類的輸出。我們從一個類和一個簡單的建構函式開始。

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

我們將在掛接 plugins_loaded 的外掛後面呼叫方法 get_instance()。在建構函式中,我們刪除原來的短碼,並用我們的自定義短碼 gallery_zip_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;

}

這個方法的第一件事就是得到帖子,因為我們需要帖子 ID 。比較我們包括 wp-includes/media.php,這個檔案包含原始相簿短程式碼的回撥函式。現在我們呼叫一個方法來獲取一個包含所有影像的陣列,透過呼叫原始相簿回撥來建立相簿輸出,建立一個連結並追加到相簿輸出的連結。影像本身分別對影像進行編輯,儲存在類變數 $images 中,稍後我們需要這個陣列。類變數 $image 為每個具有庫的文章儲存一個條目,因此我們可以在首頁或單個檢視中使用該函式。每個條目包含每個畫廊的陣列,因為每個職位中可以有多個畫廊。

外掛的核心是從短碼中獲取影像的方法。

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;

}

起初我們決定是單個帖子還是帖子 ID 列表。如果它是一個帖子 ID 的列表,我們處理從 WP3.5 +的畫廊。之後,我們必須處理 exclude 屬性。在設定所有可變數之後,我們終於可以從畫廊獲取影像。被刪除的影像將被推入類別 $images 以備將來使用。

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

這是外掛的金子。只需設定一個帶有查詢引數的陣列,即可使用 get_posts()獲取附件,然後瀏覽檢索到的附件。為了處理不同的大小,我們得到了 URL 的附件影像和條。從附件檔案中,我們將路徑放在檔名中。在陣列 $images 現在是所有的影像和他們的畫廊從畫廊。

基本上你的問題在這一點上得到回答。但是您也想從影像建立 zip 檔案。您可以在上一個方法中從陣列 $images 建立一個 zip 檔案。但是,每當顯示畫廊時都會呼叫此方法,並建立一個 zip 檔案可能需要一段時間。也許沒有人會請求您在這裡建立的 zip 檔案,這是浪費資源。

我們怎麼能做得更好?你還記得我將所有影像放在類變數 $images 中嗎?我們可以使用這個類 var 進行 ajax 請求。但是 ajax 請求只是另一個頁面載入,只有建立庫的輸出時,才能訪問影像。我們必須將影像儲存在我們可以訪問它們的地方,即使在另一個頁面請求之後。在這個例子中,我使用會話變數來儲存陣列的影像。即使再次重新載入頁面,也可以訪問會話變數。要儲存影像,我用 shutdown 鉤子註冊一個方法。 WordPress 完成渲染頁面後,將呼叫 shutdown 鉤子。在這一點上,我們應該收集所有展示的畫廊的所有影像。我們只需儲存影像,並可以在 ajax 請求中訪問它們。

當 ajax 請求被觸發時,我們記住會話 var 並從資料中建立一個 zip 檔案。但這是一個有關這個問題的話題。

我建立了一個帶有完整外掛程式碼的 repository on GitHub 。我希望它指向正確的方向。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。