WEB制作、マーケティングに関する情報をお届けします。ホームページ制作会社、テラのブログ

WordPressで複数ファイルの圧縮と一括ダウンロードを実装する方法

コーポレートサイトや製品サイトなどで資料などを多数ダウンロードできるようにしてあるサイトは多く存在します。
ただ、大量のファイル(資料)がある場合は一つずつダウンロードすることになるとユーザーにとってはとてもストレスになってしまいます。
そこでダウンロードしたいファイルにチェックを入れてzipで圧縮、ダウンロードできるようにすることでユーザーにとって利便性が上がります。
今回は『Wordpressで複数ファイルの圧縮と一括ダウンロードを実装する方法』を紹介します。

使用するプラグイン

ファイルのzip化に使用する『JSZip』

CDNで提供されています。

<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script>

zipファイルのダウンロードに使用する『FileSaver.js』

CDNで提供されています。

<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>

コードを紹介

page.phpなどのテンプレートに記載します。

<?php
/*
Template Name: PDF一括ダウンロード
*/
?>
<!DOCTYPE HTML>
<html lang="ja">
<head>
    <!-- JSZipとFileSaver.jsを読み込み -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
    <?php wp_head(); ?>
</head>
    <div>
        <input type="checkbox" name="os" id="file01" value="file01">
        <label for="file01">file01</label>
    </div>
    <div>
        <input type="checkbox" name="os" id="file02" value="file02">
        <label for="file02">file02</label>
    </div>
    <div>
        <input type="checkbox" name="os" id="file03" value="file03">
        <label for="file03">file03</label>
    </div>
    <div>
        <input type="checkbox" name="os" id="file04" value="file04">
        <label for="file04">file04</label>
    </div>
    <button id="downloadZip">ZIPファイルをダウンロード</button>

    <script>
    // 各ファイルのURLを定義
    const file01 = "https://your-server.com/demo_pdf/dl_01.pdf";
    const file02 = "https://your-server.com/demo_pdf/dl_02.pdf";
    const file03 = "https://your-server.com/demo_pdf/dl_03.pdf";
    const file04 = "https://your-server.com/demo_pdf/dl_04.pdf";

    // 「ZIPファイルをダウンロード」ボタンがクリックされたときのイベントリスナーを追加
    document.getElementById('downloadZip').addEventListener('click', function() {
        // 新しいJSZipオブジェクトを作成
        const zip = new JSZip();
        // ZIPファイル内に "files" フォルダーを作成
        const folder = zip.folder("files");

        // ダウンロードするファイルのリストを作成
        const filesToDownload = [];

        // 各チェックボックスの状態を確認し、チェックされている場合はファイルリストに追加
        if (document.getElementById('file01').checked) {
            filesToDownload.push({name: 'file01.pdf', url: file01});
        }
        if (document.getElementById('file02').checked) {
            filesToDownload.push({name: 'file02.pdf', url: file02});
        }
        if (document.getElementById('file03').checked) {
            filesToDownload.push({name: 'file03.pdf', url: file03});
        }
        if (document.getElementById('file04').checked) {
            filesToDownload.push({name: 'file04.pdf', url: file04});
        }

        // プロキシURLを定義(「your-server.com」を自身のドメインに変更)
        const proxyUrl = 'https://your-server.com/?proxy=1&url=';

        // ファイルごとにフェッチリクエストを行い、ZIPファイルに追加
        const promises = filesToDownload.map(file => {
            return fetch(proxyUrl + encodeURIComponent(file.url)) // プロキシ経由でファイルを取得
                .then(response => {
                    if (!response.ok) {
                        throw new Error(`Failed to fetch ${file.name}`); // エラーチェック
                    }
                    return response.blob(); // ファイルをBlobとして取得
                })
                .then(blob => {
                    folder.file(file.name, blob); // ZIPフォルダーにファイルを追加
                });
        });

        // 全てのファイルのフェッチが完了したらZIPファイルを生成し、ダウンロード
        Promise.all(promises).then(() => {
            zip.generateAsync({type: "blob"}).then(function(content) {
                saveAs(content, "files.zip"); // 生成されたZIPファイルをダウンロード
            });
        }).catch(error => {
            console.error('Error downloading files:', error); // エラーが発生した場合にエラーメッセージを表示
        });
    });
</script>

<footer>
    <?php wp_footer(); ?>
</footer>

</body> 
</html>

コードを解説

プラグインの読み込み

head内などで読み込んでください。

<!-- JSZipとFileSaver.jsを読み込み -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>

ボタンなどのパーツを作成

処理の際にIDを使用するのでそれぞれにID名を振っておきます。

<div>
    <input type="checkbox" name="os" id="file01" value="file01">
    <label for="file01">file01</label>
</div>
<div>
    <input type="checkbox" name="os" id="file02" value="file02">
    <label for="file02">file02</label>
</div>
<div>
    <input type="checkbox" name="os" id="file03" value="file03">
    <label for="file03">file03</label>
</div>
<div>
    <input type="checkbox" name="os" id="file04" value="file04">
    <label for="file04">file04</label>
</div>
<button id="downloadZip">ZIPファイルをダウンロード</button>

JavaScriptの処理

まずはファイルのディレクトリを変数にセットします。

const file01 = "https://your-server.com/demo_pdf/dl_01.pdf";
const file02 = "https://your-server.com/demo_pdf/dl_02.pdf";
const file03 = "https://your-server.com/demo_pdf/dl_03.pdf";
const file04 = "https://your-server.com/demo_pdf/dl_04.pdf";

次にZIPファイルをダウンロードをクリックした際に実行させるためにイベントリスナーを追加します。

document.getElementById('downloadZip').addEventListener('click', function() {}

新しいJSZipオブジェクトを作成します。

const zip = new JSZip();

ZIPファイル内に “files” フォルダーを作成します。
ここは任意ですがファイルの内容を総称したネームなどが最適でしょう。

const folder = zip.folder("files");

ダウンロードするリストを作成します。
チェック状況を『document.getElementById(‘ファイルのID名’).checked){}』でチェックのあるファイルのみダウンロードリストに挿入していきます。

// ダウンロードするファイルのリストを作成
const filesToDownload = [];
// 各チェックボックスの状態を確認し、チェックされている場合はファイルリストに追加
if (document.getElementById('file01').checked) {
    filesToDownload.push({name: 'file01.pdf', url: file01});
}
if (document.getElementById('file02').checked) {
    filesToDownload.push({name: 'file02.pdf', url: file02});
}
if (document.getElementById('file03').checked) {
    filesToDownload.push({name: 'file03.pdf', url: file03});
}
if (document.getElementById('file04').checked) {
    filesToDownload.push({name: 'file04.pdf', url: file04});
}

プロキシURLを定義して『filesToDownload.map()』で配列に処理をかけていきます。
Fetchを使って、プロキシ経由で、レスポンスを取得します。

// プロキシURLを定義(「your-server.com」を自身のドメインに変更)
const proxyUrl = 'https://your-server.com/?proxy=1&url=';
// ファイルごとにフェッチリクエストを行い、ZIPファイルに追加
const promises = filesToDownload.map(file => {
    return fetch(proxyUrl + encodeURIComponent(file.url)) // プロキシ経由でファイルを取得
        .then(response => {
            if (!response.ok) {
                throw new Error(`Failed to fetch ${file.name}`); // エラーチェック
            }
            return response.blob(); // ファイルをBlobとして取得
        })
        .then(blob => {
            folder.file(file.name, blob); // ZIPフォルダーにファイルを追加
        });
});

フェッチの処理が完了したらzipファイルを生成してダウンロードしていきます。

// 全てのファイルのフェッチが完了したらZIPファイルを生成し、ダウンロード
Promise.all(promises).then(() => {
    zip.generateAsync({type: "blob"}).then(function(content) {
        saveAs(content, "files.zip"); // 生成されたZIPファイルをダウンロード
    });
}).catch(error => {
    console.error('Error downloading files:', error); // エラーが発生した場合にエラーメッセージを表示
});

 

『dbDelta()』というテーブル名を更新する関数を使用します。
1行前の『require_once(ABSPATH . ‘wp-admin/includes/upgrade.php’);』は『dbDelta()』を呼び出すためのディレクトリの読み込みです。セットになると考えてください。

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);

最後に『add_action(‘after_setup_theme’, ‘create_search_query_table’);』でフックを設定します。

テーブルに検索クエリを保存する

『function save_search_query($query) {}』で関数を作成します。
管理画面での発火を防ぐために以下で管理画面以外、メインクエリー、ホームの時に限定して処理を実行するようにします。ここは必要に応じて条件を書くと良いでしょう。

if (!is_admin() && $query->is_search() && $query->is_main_query()) {}

データベースの情報を取得、テーブル名を設定します。

global $wpdb;
$table_name = $wpdb->prefix . 'search_query';

保存する内容を変数に設定していきます。
以下は現在の日時、、検索キーワード、ユーザーIPですが、UserAgentやClientHintsからデバイス情報、言語情報、ブラウザ情報などさまざまなデータが取得できますので必要なものを設定してください。
※データの種類を追加する場合はカラムの追加も必要になります。

// 現在の日時
$current_time = current_time('mysql');
// 検索キーワード
$search_keyword = get_search_query();
// ユーザーのIPアドレス
$user_ip = $_SERVER['REMOTE_ADDR'];

『$wpdb->insert{}』でデータベースに挿入します。

// データベースに挿入
$wpdb->insert(
    $table_name,
    array(
        'search_date' => $current_time,
        'search_keyword' => $search_keyword,
        'user_ip' => $user_ip,
    )
);

最後にフックを設定して終了です。

add_action('pre_get_posts', 'save_search_query');

まとめ

以上、『Wordpressで複数ファイルの圧縮と一括ダウンロードを実装する方法』でした。
ファイルの一括ダウンロード自体は本記事で対応可能ですが、実装となる場合にはダウンロードが始まるまでのローディングなども必要なのでかなり手間がかかる作業になってくるかと思います。
実装する際は参考にしてください。

テラ合同会社(東京都)

テラは2014年に東京都でスタートアップしたホームページ制作会社です。ホームページ制作以外にも広告運用、マーケティング、ブランディング、印刷物など幅広い領域をサポートしています。
コーポレートサイトはこちらをご覧ください。