ZIP ภาพทั้งหมดที่แสดงใน [แกลเลอรี่] และนำเสนอเป็นลิงค์ดาวน์โหลด


13

ฉันต้องการให้ตัวเลือกแก่ผู้เยี่ยมชมในการดาวน์โหลดแกลเลอรี่รูปภาพทั้งหมด (แสดงบนหน้า [แกลเลอรี่] โดยเฉพาะ) เป็นไฟล์ ZIP ที่ปรากฏที่ด้านล่างของหน้าแกลเลอรีแต่ละหน้า - จะต้องรวมภาพขนาดเต็ม

David Walsh ได้ให้รหัสในโพสต์ของเขาที่นี่เพื่อ zip ไฟล์ แต่ฉันมีปัญหาในการรวมกับฟังก์ชั่น Wordpress

ฉันรู้ว่ามีปลั๊กอินดาวน์โหลดแกลลอรี่ NextGEN แต่ฉันไม่สามารถใช้งานได้เพราะฉันใช้ฟังก์ชั่นแกลเลอรี WordPress

คำถามที่คล้ายกันกับทางเลือก (วิธีการด้วยตนเอง) ของการทำตามข้างต้นสามารถพบได้ที่นี่: ปลั๊กอินสำหรับดาวน์โหลดไฟล์สื่อที่แนบมา?

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชมอย่างมาก. ขอบคุณ


คุณหมายถึงอะไรโดยหน้าแกลเลอรีเฉพาะ
NoBugs

โพสต์มาตรฐานที่แสดงเฉพาะรหัสย่อของแกลเลอรี [แกลเลอรีคอลัมน์ = "4" ลิงก์ = "ไฟล์"] และไม่มีเนื้อหาอื่น ๆ ในหน้า ฉันรวมไว้ในคำอธิบายเพียงเพื่อช่วยนักพัฒนา
พอลทอมสัน

คำตอบ:


14

ก่อนอื่นคุณต้องได้ภาพมาก่อน วิธีการรับภาพทั้งหมดของแกลเลอรี่อธิบายไว้ที่นี่

WordPress ใช้สองคลาสสำหรับการคลายไฟล์ PHP bilt in ZipArchive()(การใช้งานดู David Walsh) และPclZipคุณสามารถพบคลาสนี้wp-admin/includes/class-pclzip.phpได้ หากคุณมีปัญหากับการZipArchive()ลองคลาส PclZip

ตอนนี้คุณต้องติดกาวทั้งสองเข้าด้วยกัน บางทีฉันสามารถโพสต์โค้ดตัวอย่างบางส่วนได้ในขณะนี้ฉันไม่ได้อยู่ที่โต๊ะทำงาน

ปรับปรุง

คำถามของคุณสามารถแยกออกเป็นสองส่วน คนแรกคือการรับภาพทั้งหมดจากแกลเลอรี่ อันที่สองคือการซิปภาพและส่งไฟล์ซิป
ฉันจะอธิบายเฉพาะตอนแรกเพื่อให้ได้ภาพทั้งหมดของแกลเลอรี่เพราะการซิปไฟล์เป็นเรื่องเล็กน้อย

อาจมีวิธีแก้ไขปัญหาอื่น ๆ แต่ในตัวอย่างนี้ฉันแทนที่รหัสย่อแกลเลอรีดั้งเดิมด้วยรหัสที่กำหนดเองเพื่อรับรูปภาพ เหตุผลคือ WordPress เปลี่ยนแกลเลอรี่เป็น v3.5 นิดหน่อย
ก่อนหน้า 3.5 ภาพสำหรับแกลเลอรี่เป็นสิ่งที่แนบมากับโพสต์ หลังจาก 3.5 รูปภาพจะถูกส่งไปยังรหัสย่อในฐานะแอตทริบิวต์ เนื่องจาก WP3.5 เราไม่สามารถรับภาพที่แนบมาของโพสต์ได้อีกต่อไปเราจึงต้องดึงรายการจากแอตทริบิวต์รหัสย่อ กลยุทธ์ของฉันคือการแทนที่รหัสเดิมด้วยรหัสย่อที่กำหนดเองคว้าแอตทริบิวต์และเรียกรหัสย่อดั้งเดิมเพื่อรับเอาท์พุทแกลเลอรี่

สิ่งที่เกี่ยวข้องกับแกลเลอรี่ทั้งหมดอยู่ในชั้นเรียน เพื่อสร้างไฟล์ zip เราสามารถใช้คลาสอื่นที่ใช้เป็นอินพุตเอาต์พุตของคลาสแกลเลอรี เริ่มจากคลาสและคอนสตรัคเตอร์เรียบง่ายกันเถอะ

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

เราจะเรียกวิธีการต่อไปในปลั๊กอินที่มีตะขอget_instance() plugins_loadedใน Constructor 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;

}

สิ่งแรกในวิธีนี้คือรับโพสต์เพราะเราต้องการรหัสโพสต์ 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 เราจัดการแกลเลอรี่จาก WP3.5 + หลังจากนั้นเราต้องจัดการexcludeคุณสมบัติ หลังจากตั้งค่า varibles ทั้งหมดในที่สุดเราก็สามารถรับภาพจากแกลเลอรี่ ภาพที่ถูกดึงกลับมาจะถูกส่งไปยัง var class $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 จากภาพ คุณสามารถสร้างไฟล์ zip จากอาเรย์$imagesในวิธีสุดท้าย แต่วิธีนี้เรียกว่าทุกครั้งที่แกลเลอรี่ปรากฏขึ้นและการสร้างไฟล์ zip อาจใช้เวลาสักครู่ อาจไม่มีใครขอไฟล์ซิปที่คุณสร้างขึ้นที่นี่นี่เป็นการสิ้นเปลืองทรัพยากร

เราจะทำให้ดีขึ้นได้อย่างไร คุณจำได้ไหมว่าฉันใส่ภาพทั้งหมดในตัวแปรคลาส$images? เราสามารถใช้ var class นี้สำหรับคำขอ ajax แต่คำขอ ajax เป็นเพียงการโหลดหน้าอื่นและเราสามารถเข้าถึงภาพได้ก็ต่อเมื่อสร้างเอาท์พุทแกลเลอรี่ เราต้องบันทึกภาพของเราในสถานที่ที่เราสามารถเข้าถึงได้แม้จะมีคำขอหน้าอื่น
ในตัวอย่างนี้ฉันใช้ตัวแปรเซสชั่นเพื่อเก็บอาร์เรย์ด้วยภาพ ตัวแปรเซสชั่นสามารถเข้าถึงได้แม้หลังจากโหลดหน้าอื่น ในการจัดเก็บภาพฉันลงทะเบียนวิธีการด้วยshutdownเบ็ด หลังจาก WordPress แสดงผลหน้าเว็บเสร็จshutdownตะขอจะถูกเรียก ณ จุดนี้เราควรรวบรวมภาพทั้งหมดจากแกลเลอรี่ที่แสดงทั้งหมด เราเพียงเก็บรูปภาพและสามารถเข้าถึงได้ในคำขอ ajax

เมื่อมีการเรียกใช้คำขอ ajax เราจะเรียกคืนเซสชัน var และสร้างไฟล์ zip จากข้อมูล แต่นี่เป็นหัวข้อสำหรับคำถามนี้เล็กน้อย

ฉันสร้างที่เก็บบน GitHubด้วยรหัสปลั๊กอินที่สมบูรณ์ ฉันหวังว่ามันจะชี้ให้คุณในทิศทางที่ถูกต้อง


โปรดทราบว่าหากคุณกำลังจัดการกับแกลเลอรีสไตล์ 3.5 ใหม่วิธีการดึงภาพจากแกลเลอรีอาจไม่ได้ผลสำหรับคุณ
Milo

เพื่อชี้แจงว่าฉันใช้ Wordpress 3.5.1 เวอร์ชันล่าสุด โยฮันเนสฉันจะขอบคุณมากเกินไปถ้าคุณสามารถให้รหัสตัวอย่างเมื่อคุณต่อไปที่เดสก์ท็อปของคุณ ขอบคุณพอล
พอลทอมสัน

เฮ้ราล์ฟนี่เป็นงานที่ยอดเยี่ยมมาก! ขอบคุณสำหรับการแบ่งปัน. เพื่อให้ภาพแกลเลอรี่ของฉันที่จะแสดงอย่างถูกต้องฉันต้องรวม link = "file" ใน shortcode เช่น: [gallery link = "file"] เนื่องจาก shortcode นั้นถูกเขียนใหม่อีกครั้งผ่านรหัสของคุณฉันคิดว่าถูกทิ้งไว้และเป็น ทำให้แกลเลอรี่ของฉันแสดงไม่ถูกต้อง มีวิธีใดที่จะแก้ไขอาร์กิวเมนต์นี้ในรหัสของคุณ?
Paul Thomson

โดยปกติแล้วแอททริบิวต์จะถูกส่งผ่านไปยังรหัสย่อดั้งเดิมและจะไม่ถูกแก้ไข แกลเลอรีจะแสดงตามปกติ แต่มี HTML บางส่วนต่อท้าย ในการทดสอบของฉัน (ด้วยชุดรูปแบบ standoff สิบสอง) แกลเลอรี่จะแสดงอย่างถูกต้อง
Ralf912

@PaulThomson ฉันแก้ไขปัญหาบางอย่างในที่เก็บ github รหัสไม่สะอาด
Ralf912

0

ฉันชอบความคิดของปลั๊กอินของ Ralf ที่สามารถดาวน์โหลดแกลเลอรีทั้งหมดได้ในคราวเดียว แต่ฉันไม่สามารถใช้งานได้ ฉันคิดวิธีแก้ปัญหาที่เหมาะกับวัตถุประสงค์ของเรา วิธีการคือการแทนที่แกลเลอรี่ WP ดั้งเดิมด้วยของคุณเองที่คุณวางในตอนท้ายของfunctions.phpไฟล์ชุดรูปแบบของคุณและเพิ่มไฟล์ต่อไปนี้ชื่อdownload.phpในโฟลเดอร์ธีมที่ใช้งาน ในแกลเลอรีที่กำหนดเองลิงก์ใต้ไฟล์จะเรียกไฟล์ download.php ซึ่งจะบังคับให้ดาวน์โหลดไฟล์ของคุณไปยังฮาร์ดไดรฟ์โดยอัตโนมัติ ฉันได้ทำการทดสอบกับ Chrome, Firefox และ Safari เวอร์ชันล่าสุดแล้วและใช้งานได้ดี ใช้ธีมยี่สิบยี่สิบ แต่ไม่มีเหตุผลว่าทำไมมันไม่ควรทำงานกับคนอื่นด้วย

ก) functions.phpเพิ่มต่อไปนี้เพื่อการสิ้นสุดของ สิ่งนี้นำมาจาก 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) คัดลอกและวางสิ่งต่อไปนี้ลงในไฟล์ที่เรียกว่าdownload.phpในไดเรกทอรีฐานของธีม

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

ค). อย่าลืมลิงค์ไปยังไฟล์ในคลังภาพ !! สำคัญ!


ฉันไม่คิดว่านี่เป็นความคิดที่ดีการใช้download.phpและ$_GETพารามิเตอร์ที่ฉันสามารถดาวน์โหลดไฟล์ทั้งหมดที่ฉันต้องการจากเว็บโฟลเดอร์ของคุณ (รวมถึงเครือข่ายแชร์) เช่นwp-config.php
Diego Betto
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.