问题描述
我想向访问者提供下载整个照片库的选项 (显示在专用 [图库] 页面上) 作为每个图库页面底部显示的 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 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。