【WordPress】WordPress管理ページ中でajaxを利用して、CSVファイルをダウンロードする方法（実装解説付き）

# やりたいこと
WordPress管理ページ上で、任意のデータをシームレスにCSVダウンロードする
CSVファイルを出力する際に一度外部のPHPファイルをリンクさせず、シームレスにダウンロードしたい

手短にソースだけ確認したい方はこちらを参照してください
https://qiita.com/tsukahara-akito/items/976690c099f8f3316a7d

# 仮シナリオ
やりたいことのイメージが掴めない方は、仮シナリオにそって記事を読んでみてください。
慣れてきたら、CSVファイルとして出力するデータをアレンジしてみてください。

今回の仮シナリオは
「WordPress管理ページ上で、DBから投稿データを取得し、CSVファイルでダウンロードする」

# 処理の流れ
1.CSVで出力したいデータをDBから取得
2.ajaxでCSVを出力するPHPファイルを呼び出す
3.ajaxから受け取ったデータをCSVファイルとして出力する

# 作るもの
- WordPress管理ページ
 - 管理ページ出力
 - PHPファイルを呼び出すjavascript 
- CSVファイルを出力するPHP

# ディレクトリ構造
wordpress/
　├ tools/
　│　└ csv/
　│　　　└request.php/
　├ wp-content/
　│　└ themes/
　│　　　└ your-theme/
　│　　　　　└ functions/
　│　　　　　　　└ function-csvdownload.php
　│　　　　　└ functions.php

　
# 実装
1.管理ページの作成
wordpressに最初から用意されているfunctions.phpに処理を追加しても良いのですが、一つのファイルが長くなりすぎないように今回の処理は別のファイルに記載していきます。
functions.phpには1行のみ追加してください。

```php:functions.php
require_once(dirname(__FILE__)."/functions/function-csvdownload.php"); 
```

新しくファイルを作成したら、管理ページを追加しましょう。

```php:function-csvdownload.php
add_action( 'admin_menu', 'csvdownload_menu' );
function csvdownload_menu() {
	add_menu_page( 'CSVダウンロード', 'CSVダウンロード', 'manage_options', 'csvdownload_menu', 'csvdownload_init','dashicons-download',8 );
}
/*
 * CSVダウンロード管理ページの初期化
 */
function csvdownload_init() {
	
}

```

下のように新しくページが追加されます。
![スクリーンショット 2018-07-14 17.34.13.png](https://qiita-image-store.s3.amazonaws.com/0/251415/caa2bafc-03ae-a561-435a-e3db4e8a3628.png)

次に処理手順1「CSVで出力したいデータをDBから取得」の処理を追加しましょう。
今回はwordpress中の記事を3件取得し、一部のデータをCSVファイルに出力するデータとして抽出しています。

```php:function-csvdownload.php
/*
 * CSVダウンロード管理ページの初期化
 */
function csvdownload_init() {
	//CSVダウンロード管理ページ 表示用関数
  csvdownload_page();
}

/*
 * CSVダウンロード管理ページ
 */
function csvdownload_page(){
  //1.CSVで出力したいデータをDBから取得
  $args = array(
    'post_type'       => 'post',
    'post_status'     => 'publish',
    'order'           => 'ASC',
    'orderby'         => 'date',
    "posts_per_page"  => 3,//取得件数
  );
  $posts = get_posts($args);

  //CSVで出力したいデータを配列に格納
  $origin_data = array();
  $data_header = implode( ",",array('ID','post_title','post_date'));
  array_push($origin_data,$data_header);

  foreach($posts as $post_data){
    $choice_data = implode( ",",array(
      $post_data->ID,
      $post_data->post_title,
      $post_data->post_date
    ));
    array_push($origin_data,$choice_data);
  }
}
```

試しにvar_dump()でデータを出力させてみましょう。
![スクリーンショット 2018-07-14 17.44.34.png](https://qiita-image-store.s3.amazonaws.com/0/251415/95b8431c-ca8f-9bf8-056f-32489af7cd98.png)


次は、処理手順2「ajaxでCSVを出力するPHPファイルを呼び出す」を実装します
ダウンロードボタンをクリックすることでCSVファイルがダウンロードできるようにします。
管理ページ側の実装はここまでです。

```php:function-csvdownload.php
//管理ページにCSVダウンロード用スクリプトを出力する
csv_download_script();

//2.ajaxでCSVを出力するPHPファイルを呼び出す
$origin_data_json = json_encode($origin_data,JSON_UNESCAPED_UNICODE);
  
//ダウンロードボタンを管理ページに出力
print '<button onclick=\'csv_download('.$origin_data_json.','.date('Ymd').')\'>CSVダウンロード</button>';

/*
* CSVダウンロード用スクリプトを出力する
*/
function csv_download_script(){
  print '
  <script>
  function csv_download(data,date){
    jQuery.ajax({
      url:"/your-theme/tools/csv/request.php",//CSVファイルを出力するPHPファイル
      dataType: "json",
      contentType: "application/json",
      type:"POST",
      data: JSON.stringify(data),
      beforeSend: function(xhr){
        xhr.overrideMimeType("text/plain; charset=shift_jis");//文字化けしないようにMIMEタイプをオーバーライドする
      },
      success: function(data) {
        if(data!=""){
          var downloadData = new Blob([data], {type: "text/csv"});
          var filename = date+"_post-data.csv";
          //ファイルのダウンロードにはブラウザ毎に処理を分ける必要があります！
          if(window.navigator.msSaveBlob){ // for IE
            window.navigator.msSaveBlob(downloadData, filename);
          }else{
            var downloadUrl  = (window.URL || window.webkitURL).createObjectURL(downloadData);
            var link = document.createElement("a");
            link.href = downloadUrl;
            link.download = filename;
            link.click();
            (window.URL || window.webkitURL).revokeObjectURL(downloadUrl);
          }
        }
      },
      error: function(xhr, textStatus, errorThrown){
        alert("CSVファイルのダウンロードに失敗しました。")
      }
    })
  }
</script>
';
}

```

最後に処理手順3「ajaxから受け取ったデータをCSVファイルとして出力する」を実装します

```php:request.php
require_once(dirname(__FILE__)."/../../wp-load.php");
$json = file_get_contents("php://input");
$data = json_decode($json);
//3.ajaxから受け取ったデータをCSVファイルとして出力する
$csv="";
foreach ($data as $value){
  $csv.=$value;
  $csv.="\n";
}

header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=test.csv");

echo(json_encode($csv));
```


管理ページで目的のデータがCSVファイルで出力されているか確認してみましょう。
![スクリーンショット 2018-07-14 17.44.34.png](https://i.gyazo.com/bdba8444c96753d736970b89e6a82adb.gif)
ファイルの中身も問題なく出力できているかと思います。
<img width="396" alt="スクリーンショット 2018-07-14 18.00.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/251415/a649a88f-5e61-d941-46fa-8fe56a18b725.png">

以上、「WordPress管理ページ中でajaxを利用して、CSVファイルをダウンロードする方法」でした。
皆様のお役に立てれば幸いです！