a-blog cmsでPDFファイルのサイズを自動で表示する

これは [a-blog cms Advent Calendar 2018](https://adventar.org/calendars/2948) の10日目の記事です。

* * * 

a-blog cmsでPDFファイルをアップロードしたときに、ファイルサイズを表示したいときがありますよね。
これは、ファイルサイズを自動で表示するカスタムフィールドを実装したときのお話です。

## 前置き

PDFファイルをたくさんアップロードするページ（例えば：会報、広報誌、カタログ、マニュアル etc.）があるときに便利。たぶん。

## a-blog cmsのカスタマイズ

この記事を書いている時点での最新バージョンは a-blog cms v2.9.8 です。
「beginner2018」テーマをベースにカスタマイズしてゆきます。

### ファイルのカスタムフィールド

通常のユニットでファイルサイズを取得できるという情報が見つからなかったので、カスタムフィールドでいきます！

参考）[カスタムフィールドでファイルをアップロードできるようにする](https://developer.a-blogcms.jp/document/customfield/#entry-id-1492)

ファイルをアップロードするカスタムフィールドを見ると、ファイルサイズを取得するための記述があるのがわかります。

```html
<input type="hidden" name="pdffile@fileSize" value="{pdffile@fileSize}" />
```
今回は、複数のファイルをアップロードしやすくするために **カスタムユニット** にします。

### カスタムユニットの作成

参考）[カスタムユニット](https://developer.a-blogcms.jp/document/units/#entry-id-1628)

公式サイトのドキュメントに則って作業を進めてゆきます。

#### 1. ユニット追加ボタンの作成

管理ページの編集設定でボタンを追加します。わたしは「**PDFファイル**」というラベルにしました。
![filesize01.png](https://qiita-image-store.s3.amazonaws.com/0/111287/f5c248f0-8b8a-9720-3826-7b693bd10ecf.png)

#### 2. 入力フォームのカスタマイズ
[カスタムフィールドメーカー](http://developer.a-blogcms.jp/tools/) でファイルのカスタムユニットを作成し、**/admin/entry/unit/custom.html** に記述します。

```html
<table class="entryFormColumnTable">
    <tr>
        <td class="entryFormFilePreview"><!-- BEGIN pdfFile@path:veil -->
            <a href="%{HTTP_ARCHIVES_DIR}{pdfFile@path}">
                <img src="/images/fileicon/pdf.gif" width="64" height="64" alt="filepdf">
            </a><!-- END pdfFile@path:veil -->
        </td>
        <td class="entryFormFileControl">
            <table class="entryFormColumnSettingTable">
                <tr>
                    <th>PDFファイル</th>
                    <td>
                        <input type="file" name="pdfFile{id}"><br>
                        <!-- BEGIN_IF [{pdfFile@path}/nem] -->
                        <input type="hidden" name="pdfFile{id}@old" value="{pdfFile@path}">
                        <input type="hidden" name="pdfFile{id}@secret" value="{pdfFile@secret}">
                        <input type="hidden" name="pdfFile{id}@fileSize" value="{pdfFile@fileSize}">
                        <div class="acms-admin-form-checkbox">
                            <label for="input-checkbox-pdfFile{id}@edit" class="">
                                <input type="checkbox" name="pdfFile{id}@edit" value="delete" id="input-checkbox-pdfFile{id}@edit"><i class="acms-admin-ico-checkbox"></i>削除</label>
                        </div>
                        <!-- END_IF -->

                        <input type="hidden" name="unit{id}[]" value="pdfFile{id}">
                        <input type="hidden" name="pdfFile{id}@baseName" value="{pdfFile@baseName}">
                        <input type="hidden" name="pdfFile{id}:extension" value="file">
                        <input type="hidden" name="pdfFile{id}@extension" value="pdf">
                        <input type="hidden" name="pdfFile{id}@filename" value="@rawfilename">
                    </td>
                </tr>
                <tr>
                    <th>ファイル名</th>
                    <td>
                        <input type="text" name="pdfName{id}" value="{pdfName}" class="acms-admin-form-width-full">
                        <input type="hidden" name="unit{id}[]" value="pdfName{id}">
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>
```
ファイル名も手入力したいので、テキストの入力欄も一緒に作成しました。
＊ファイルのアイコンを表示するために一部調整しています

#### 3. 表示部分のカスタマイズ

表示側のテンプレート **/include/unit/custom.html** に以下のように記述します。

```html
<!-- BEGIN custom_unit:veil -->
<div class="entry-container" aria-labelledby="custom_unit-{utid}">
    <!-- BEGIN pdfFile@path:veil -->
    <div class="link-item">
        <a href="%{HTTP_ARCHIVES_DIR}{pdfFile@path}" target="_blank">
            <div class="file-image">
                <img src="/images/fileicon/pdf.gif" width="40" height="40" alt="filepdf">
            </div>
            <div class="file-name">{pdfName} ({pdfFile@fileSize})</div>
        </a>
    </div><!-- END pdfFile@path:veil -->
</div>
<!-- BEGIN custom_unit:veil -->
```
＊CSSでスタイル調整しています

ここで、一度PDFファイルをアップロードしてみましょう。

#### 4. アップロード！

カスタムユニットでPDFファイルをアップロードしてみます。

作成したユニット追加ボタンがあるので、ユニットを追加
![filesize02.png](https://qiita-image-store.s3.amazonaws.com/0/111287/af090419-f102-5930-323d-2f8e78256576.png)

アップロードするファイルを選択してファイル名を入力
![filesize03.png](https://qiita-image-store.s3.amazonaws.com/0/111287/96f8e6d9-6e76-9830-2e14-e440a3063b26.png)

作成したエントリーを確認してみると
![filesize04.png](https://qiita-image-store.s3.amazonaws.com/0/111287/fe9ed18c-357f-0854-8511-2813f26c170b.png)

Oh...バイト表記でした……単位を変換する必要がありますね。
[用意されている校正オプション](https://developer.a-blogcms.jp/document/reference/proofreading.html) にそれらしきものがないので、校正オプションを作りましょう！

### 校正オプションの拡張
まずは記述するファイルを確認します。

> Acms\Custom\Correctorクラス（extension/acms/Corrector.php）にメソッドを定義することで、校正オプションの拡張が可能です。Acms\Custom\Correctorクラスが記述される、extension/acms/Corrector.phpは、アップデート時の上書き対象ではないので、自由に拡張してご利用いただけます。

参考）[校正オプションの拡張について](https://developer.a-blogcms.jp/document/user_corrector/#entry-id-1818)

以前のバージョンでは /php/ACMS/User/Corrector.php だったのが **/extension/acms/Corrector.php** に変更になっているようです。

**Corrector.php** に以下のコードを追加します。

```php:Corrector.php
function fileSize($size)
{
    $b = 1000;          // バイト
    $mb = pow($b, 2);   // メガバイト
    $gb = pow($b, 3);   // ギガバイト

    switch(true) {
        case $size >= $gb:
            $target = $gb;
            $unit = 'GB';
            break;
        case $size >= $mb:
            $target = $mb;
            $unit = 'MB';
            break;
        default:
            $target = $b;
            $unit = 'KB';
            break;
    }

    $new_size = round($size / $target, 1);
    $file_size = number_format($new_size, 1, '.', ',') . $unit;

    return $file_size;
}
```
わたしは小数点以下1桁まで表示することにしました。
＊1KB=1000バイトで換算しています

表示側に作成した校正オプション **[fileSize]** を追加します。

```html
<!-- BEGIN custom_unit:veil -->
<div class="entry-container" aria-labelledby="custom_unit-{utid}">
    <!-- BEGIN pdfFile@path:veil -->
    <div class="link-item">
        <a href="%{HTTP_ARCHIVES_DIR}{pdfFile@path}" target="_blank">
            <div class="file-image">
                <img src="/images/fileicon/pdf.gif" width="40" height="40" alt="filepdf">
            </div>
            <div class="file-name">{pdfName} ({pdfFile@fileSize}[fileSize])</div>
        </a>
    </div><!-- END pdfFile@path:veil -->
</div>
<!-- BEGIN custom_unit:veil -->
```
表示を確認してみると……はい！
![filesize05.png](https://qiita-image-store.s3.amazonaws.com/0/111287/13f66179-e543-6286-0bc3-ea7a3c4e1e9b.png)

メガバイトに変換されました！

## おわりに

カスタマイズ部分の説明が長くなりましたが、校正オプションを作ったというお話でした。
この校正オプションはデフォルトで用意されていてもいいと思うのですが…どうでしょう？

## 参考サイト

- [バイトから適切なファイル単位に変換する - Qiita](https://qiita.com/artprojectteam/items/56e7b8f2bbbe3e66ab74)