問題描述
我想向訪問者提供下載整個照片庫的選項 (顯示在專用 [圖庫] 頁面上) 作為每個圖庫頁面底部顯示的 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。