Wordpress + Staticpress(S3) + S3 で吐き出したファイルがうまく表示されない場合の対処法

# 概要

`Wordpress`で[ **個人ポートフォリオサイト** ](http://portfolio.bakira-tech.com/)を作っているのですが、特に__動的なページは無い__ので`Staticpressプラグイン`で__静的コンテンツ__に吐き出して`StaticpressS3プラグイン`で`AWS`の`S3バケット`に転送して公開しています。

## 転送時の問題

主に`画像ファイル`(たまに`html`)を転送すると、バケット上の静的ページからは画像ファイルが__うまく表示出来ない__場合があります。

例えば、`SVGファイル`の場合。

`Wordpress`上の表示は正常に出ていますが、

<img width="1258" alt="screencapture- 2018-01-04 22.46.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/3f50ca0c-e1a2-3e29-3851-543e232daa84.png">


`S3バケット`に転送すると__うまく表示されません。__

<img width="1245" alt="screencapture- 2018-01-04 22.46.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/4ab64021-8854-e990-fc64-0ea1ea1bc1f7.png">

### 原因

これは`StaticpressS3プラグイン`にて、S3バケットに転送する際の__MIMEタイプ__の指定が正しくされておらず、結果として「__text/plain__」が指定されてしまっているのが原因です。

<img width="851" alt="screencapture- 2018-01-04 23.18.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/c7b66c97-5510-6a90-f796-78e52cea3834.png">


`SVGファイル`であるなら本来は「__image/svg+xml__」と指定されるのが正解です。

### 解決方法

#### 注意

<font color="red">プラグインの修正は間違えるとWordpressが動かなくなることがあるので、必ずファイルのバックアップを取る等してから内容の編集を行うようにしてください！</font>

#### 転送済みファイル向け

__すでに転送済み__の`SVGファイル`については、S3バケット内のSVGファイルの`Content-type`を__image/svg+xml__に変更する必要があります。

`AWS`の__マネジメントコンソール__から一つ一つ変更することも可能ですが、__複数ファイルある場合__はすごくめんどくさいので、`AWS-cli`を利用します。

以下の`shell`を作成し、実行してください。
<font color="red">※__${~}__をそれぞれ置換してください。</font>

```shell:updateContentType.sh
BUCKETNAME=${バケット名}
REGEX="image/svg\+xml";
for KEY in $(aws s3api list-objects　　--profile ${profile} --bucket $BUCKETNAME  --query "Contents[].[Key]" --output text | grep "\.svg$")
do
  RESULT=`aws s3api head-object　　--profile ${profile} --bucket $BUCKETNAME  --key $KEY  --query "[ContentType]"  --output text`
  if [[ $RESULT =~ $REGEX ]] ;
  then
    continue;
  fi
  aws s3api copy-object　　--profile ${profile} --bucket $BUCKETNAME --acl public-read --copy-source $BUCKETNAME/$KEY --key $KEY  --metadata-directive "REPLACE" --content-type $REGEX
done;
```

これを実行することでS3バケット内の__全てのSVGファイルのContentTypeが「image/svg+xml」__に変わります。

#### これから転送するファイル向け

`StaticpressS3プラグイン`のファイルを編集します。

```php:staticpress-s3/includes/class-S3_helper.php
・・・
private function mime_type($filename){
		static $info;
		if (!isset($info)) {
			//$magic_file = '/usr/share/misc/magic';
                        $magic_file = '/etc/httpd/conf/magic';
			$info = file_exists($magic_file)
			? new FInfo(FILEINFO_MIME_TYPE, $magic_file)
			: new FInfo(FILEINFO_MIME_TYPE);
        }
		$mime_type =
			file_exists($filename)
			? $info->file($filename)
			: false;

		if ( $mime_type == 'text/plain') {
			if (preg_match('/\.css$/i', $filename))
				$mime_type = 'text/css';
			else if (preg_match('/\.js$/i', $filename))
				$mime_type = 'application/x-javascript';
			else if (preg_match('/\.html?$/i', $filename))
				$mime_type = 'text/html';
			else if (preg_match('/\.xml$/i', $filename))
				$mime_type = 'application/xml';
			else if (preg_match('/\.svg$/i', $filename))// ★追加
				$mime_type = 'image/svg+xml';// ★追加
		}

		return $mime_type;
 	}
・・・
```

上記のように__ファイル名が「.svg」で終わっている場合__に`MIMEタイプ`を設定するように変更しました。

### 確認

この状態で通常通り`Staticpress`を使ってS3バケット内にSVGファイルを転送すると、__最初からContentTypeにimage/svg+xmlが設定される__ので、前者のShellを流す必要もなくなります。

お困りの方がいたら是非お試しください♪