Заархивируйте все изображения, отображаемые в галерее, и предложите ссылку для скачивания.

13

Я хотел бы предложить своим посетителям возможность загрузки всей фотогалереи (отображаемой на выделенных страницах [gallery]) в виде ZIP-файла, отображаемого внизу каждой страницы галереи. - Полноразмерное изображение должно быть включено.

Дэвид Уолш дал код в своем посте здесь застегивать файлы , но у меня возникают проблемы с интеграцией , что с функциями Wordpress.

Я знаю, что есть плагин для скачивания галереи NextGEN, но я не могу его использовать, так как использую встроенные функции галереи WordPress.

Аналогичный вопрос с альтернативным (ручной метод) завершения вышеупомянутого можно найти здесь: Плагин для загрузки вложенных медиа-файлов?

Любая помощь будет принята с благодарностью. Благодарю.

Пол Томсон
источник
Что вы подразумеваете под выделенными страницами галереи?
NoBugs
стандартные сообщения, которые отображают ТОЛЬКО шорткод галереи [gallery columns = "4" link = "file"] и никакого другого контента на странице. Я включил, что в описании как раз это помогло разработчикам.
Пол Томсон

Ответы:

14

Сначала вы должны получить изображения. Как получить все изображения галереи описано здесь .

WordPress использует два класса для распаковки файлов. PHP встроен ZipArchive()(см. Дэвид Уолш). И PclZip , вы можете найти этот класс в wp-admin/includes/class-pclzip.php. Если у вас возникли проблемы, ZipArchive()попробуйте класс PclZip.

Теперь вам просто нужно склеить оба вместе. Может быть, я могу опубликовать пример кода позже, в настоящее время я не на моем столе.

Обновить

Ваш вопрос можно разделить на две части. Первый получает все изображения из галереи. Второй - архивирование изображений и отправка zip-файла.
Я объясню только первую часть, получая все изображения галереи, потому что архивирование файлов слегка оффтопично.

Возможно, есть и другие решения, но в этом примере я заменяю оригинальный шорткод галереи на собственный, чтобы получить изображения. Причина в том, что WordPress немного изменил галереи в версии 3.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. В конструкторе мы удаляем исходный шорткод и заменяем его нашим собственным шорткодом 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;

}

Сначала мы решаем, будет ли это один пост или список идентификаторов постов. Если это список идентификаторов постов, мы обрабатываем галерею из WP3.5 +. После этого мы должны обработать excludeатрибут. После настройки всех переменных мы наконец можем получить изображения из галереи. Полученные изображения будут помещены в класс var $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-файла может занять некоторое время. Возможно, никто не будет запрашивать созданный вами zip-файл, это пустая трата ресурсов.

Как мы можем сделать это лучше? Вы помните, что я поместил все изображения в переменную класса $images? Мы можем использовать этот класс var для ajax-запроса. Но ajax-запрос - это просто очередная загрузка страницы, и мы можем получить доступ к изображениям только при создании вывода галереи. Мы должны сохранять наши изображения в месте, где мы можем получить к ним доступ даже после запроса другой страницы.
В этом примере я использую переменную сеанса для хранения массива с изображениями. Переменная сеанса может быть доступна даже после перезагрузки другой страницы. Чтобы сохранить изображения, я регистрирую метод с shutdownкрючком. После того, как WordPress закончит рендеринг страницы, shutdownбудет вызван хук. На данный момент мы должны были собрать все изображения из всех отображаемых галерей. Мы просто храним изображения и можем получить к ним доступ в запросе ajax.

Когда запускается ajax-запрос, мы вызываем сессию var и создаем zip-файл из данных. Но это немного не по теме для этого вопроса.

Я создал репозиторий на GitHub с полным кодом плагина. Я надеюсь, что это указывает вам в правильном направлении.

Ralf912
источник
Учтите, что если вы имеете дело с новыми галереями в стиле 3.5, этот метод извлечения изображений из галереи может не сработать.
Майло
Чтобы уточнить, я использую последнюю версию Wordpress 3.5.1. Йоханнес, я был бы очень признателен, если бы вы смогли предоставить пример кода, когда будете рядом на рабочем столе. Спасибо, Пол
Пол Томсон
Эй, Ральф, это фантастическая работа! Спасибо, что поделился. Чтобы изображения галереи отображались правильно, я должен включить в шорткод link = "file", т.е.: [gallery link = "file"], так как шорткод перезаписывается через ваш код, я думаю, что он пропущен и как результат мои галереи не отображаются правильно. Есть ли способ исправить этот аргумент в вашем коде?
Пол Томсон
Обычно атрибуты просто передаются в исходный шорткод и не будут изменены. Галереи отображаются как обычно, но с добавлением HTML. В моих тестах (с двадцатью двенадцатью стандартными темами) галереи отображаются правильно.
Ralf912
@PaulThomson Я исправил некоторые проблемы в репозитории github. Код не был чистым.
Ralf912
0

Мне нравится идея, что плагин Ральфа может загружать целую галерею за один раз, но я не смог заставить его работать. Я нашел обходной путь, который работает для наших целей. Метод состоит в том, чтобы заменить собственную галерею 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' );

б) Скопируйте и вставьте следующее в файл, называемый 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
Диего Бетто