ImageMagick を使って、a-blog cmsでPDFファイルのアップロード時にサムネイル画像を生成してみる第二弾。
ローカルでの設定(MAMP編)の続きです。
せっかくなので、レンタルサーバにも設定してみます。
サーバはさくらのスタンダードです。
設定の流れ
- サーバの設定
- a-blog cmsのカスタマイズ
- PDFアップロード!
Step1: サーバの設定
さくらのレンタルサーバでは、全プランで ImageMagick が使えるようになっているそうです。
サーバコントロールパネルにログインし、「PHP設定の編集」メニューから php.ini に Imagick(PHP拡張モジュール)エクステンションの記述を追加します。
extension=imagick.so
これだけで phpInfo に imagick が表示されました。簡単!
Step2: a-blog cmsのカスタマイズ
MAMP編 と同様にカスタマイズし、ファイルをアップします。
1. カスタムフィールドを作成
/admin/entry/field.html にPDFファイルをアップロードするカスタムフィールドを記述します(お好みでincludeファイルに)。
カスタムフィールドメーカー でファイルのカスタムフィールドを作成し、画像ファイルのパス ( /images/fileicon/pdf.gif ) を変数 ( %{ARCHIVES_DIR}{pdfThumbnail} ) 変更します。
<table class="entryFormTable acms-admin-table-entry">
<tr>
<th>PDFファイル</th>
<td>
<!-- BEGIN pdfFile@path:veil -->
<input type="hidden" name="pdfFile@old" value="{pdfFile@path}" />
<input type="hidden" name="pdfFile@secret" value="{pdfFile@secret}" />
<input type="hidden" name="pdfFile@fileSize" value="{pdfFile@fileSize}" />
<label for="input-checkbox-pdfFile@edit" class="acms-admin-form-checkbox">
<input type="checkbox" name="pdfFile@edit" value="delete" id="input-checkbox-pdfFile@edit" />
<i class="acms-admin-ico-checkbox"></i> 削除
</label>
<a href="%{ARCHIVES_DIR}{pdfFile@path}"><img src="%{ARCHIVES_DIR}{pdfThumbnail}" width="120" alt="" /></a>
<!-- END pdfFile@path:veil -->
<input type="file" name="pdfFile" />
<input type="hidden" name="field[]" value="pdfFile" />
<input type="hidden" name="pdfFile@baseName" value="{pdfFile@baseName}" />
<input type="hidden" name="pdfFile:extension" value="file" />
<input type="hidden" name="pdfFile@extension" value="pdf" />
</td>
</tr>
</table>
2. Hookを有効に設定
config.server.php でフック拡張を有効(0→1)に変更。
define('HOOK_ENABLE', 1);
3. 独自処理の追加
/php/ACMS/User/Hook.php の beforePostFire function内に以下のコードを追加。
public function beforePostFire($thisModule)
{
if ( !sessionWithContribution() ) return false; // 権限チェック
$class = get_class($thisModule); // モジュールのクラス名取得
$destDir = sprintf('%03d', BID).'/thumbnail/'; // サムネイルを保存するディレクトリ名
$fieldName = 'pdfFile'; // アップロードするPDFのフィールド名
$thumbnailFieldName = 'pdfThumbnail'; // サムネイル画像の変数名
// PDFファイルを元のファイル名に
switch($class) {
case 'ACMS_POST_Entry_Insert':
case 'ACMS_POST_Entry_Update':
$thisModule->Post->_aryField['pdfFile@filename'][0] = 'pdf/'.$_FILES['pdfFile']['name'];
break;
}
// エントリーの作成or更新のみ
if ( !in_array($class, array(
'ACMS_POST_Entry_Insert',
'ACMS_POST_Entry_Update'
)) ) {
return false;
}
$Post =& $thisModule->Post; // POSTデータを取得
$bid = $Post->get('bid');
$cid = $Post->get('cid');
if ( !isset($_FILES[$fieldName]['tmp_name']) ) return false;
$source = $_FILES[$fieldName]['tmp_name'];
if ( !is_readable($source) ) return false;
$myurl = $source.'[0]'; // PDFの1ページを指定
try {
$image = new Imagick();
$image->setResolution(140, 140); // 解像度を指定
$image->readimage($myurl); // PDFの読み込み
$image->setImageFormat('png');
ACMS_POST::setupDir(ARCHIVES_DIR.$destDir, intval(config('permission_dir'))); // 保存先ディレクトリの作成
$file = $_FILES['pdfFile']['name'].'.png'; // 保存ファイル名 (元のファイル名.png)
$dest = ARCHIVES_DIR.$destDir.$file; // 保存先
$image->writeImage($dest);
$image->destroy();
// カスタムフィールドに登録する為、POSTデータにサムネイル画像のパスを登録
$Post->add('field', $thumbnailFieldName);
$Post->add($thumbnailFieldName, $destDir.$file);
} catch(Exception $e) {
echo $e->getMessage();
}
}
〈追記〉エントリー編集後も画像を保持する
エントリーを編集すると画像が消える問題、生成した画像は残っているので、画像のパスの書き方を変えることで解決したいと思います!
ファイル名とパスを見てみる
サムネイル画像をPDFファイル名と連動したことで、それぞれのパスは以下のようになります(ブログIDが1のとき)。
PDFファイル: /archives/001/pdf/filename.pdf
サムネイル画像: /archives/001/thumbnail/filename.pdf.png
PDFファイルのパス ( 001/pdf/filename.pdf ) はカスタムフィールドの値 {pdfFile@path} なので、これに画像の拡張子を追加する ( {pdfFile@path}.png ) と画像のファイル名は取得できますね。
生成したサムネイル画像の保存先がPDFファイルと同じ場所 ( /archives/001/pdf ) ならこのままでOKでした。でもわたしはサムネイル画像は個別に管理したいのです。画像のパスを pdf ディレクトリから thumbnail に変更する必要があります。
そこで登場するのが 校正オプションの拡張 です!
校正オプションの拡張
まずはファイルを準備します。
ダウンロードパッケージのomakeフォルダに含まれるファイルを、設置先にコピーします。
コピー元
(ダウンロードパッケージの展開先)/omake/php/ACMS/User/Corrector.php
コピー先
(a-blog cms設置先)/php/ACMS/User/Corrector.php所定の位置にファイルがコピーされていれば、自動で校正オプションが拡張されるようになります。
Corrector.php に以下のコードを追加します。
function pdf2thumb($txt, $args = array())
{
if ( mb_strpos($txt, '/pdf/') ) {
$txt = str_replace( '/pdf/', '/thumbnail/', $txt );
}
return $txt;
}
表示側の画像のパスを {pdfThumbnail} から {pdfFile@path}.png に変更し、作成した校正オプションを追加します。
<!-- BEGIN pdfFile@path:veil -->
<a href="%{ARCHIVES_DIR}{pdfFile@path}" target="_blank"><img src="%{ARCHIVES_DIR}{pdfFile@path}[pdf2thumb].png" width="120" alt="" /></a>
<!-- END pdfFile@path:veil -->
{pdfFile@path}[pdf2thumb].png のように校正オプションを追加することで 001/pdf/filename.pdf.png が 001/thumbnail/filename.pdf.png になります。
カスタムフィールドの画像のパスも変更しておきましょう。
<table class="entryFormTable acms-admin-table-entry">
<tr>
<th>PDFファイル</th>
<td>
<!-- BEGIN pdfFile@path:veil -->
<input type="hidden" name="pdfFile@old" value="{pdfFile@path}" />
<input type="hidden" name="pdfFile@secret" value="{pdfFile@secret}" />
<input type="hidden" name="pdfFile@fileSize" value="{pdfFile@fileSize}" />
<label for="input-checkbox-pdfFile@edit" class="acms-admin-form-checkbox">
<input type="checkbox" name="pdfFile@edit" value="delete" id="input-checkbox-pdfFile@edit" />
<i class="acms-admin-ico-checkbox"></i> 削除
</label>
<a href="%{ARCHIVES_DIR}{pdfFile@path}"><img src="%{ARCHIVES_DIR}{pdfFile@path}[pdf2thumb].png" width="120" alt="" /></a>
<!-- END pdfFile@path:veil -->
<input type="file" name="pdfFile" />
<input type="hidden" name="field[]" value="pdfFile" />
<input type="hidden" name="pdfFile@baseName" value="{pdfFile@baseName}" />
<input type="hidden" name="pdfFile:extension" value="file" />
<input type="hidden" name="pdfFile@extension" value="pdf" />
</td>
</tr>
</table>
これでエントリーを編集しても画像が消えることはなくなりました。
Step3: PDFアップロード!
カスタムフィールドでPDFファイルをアップロードしてみると、サイズの大きなファイルはアップロードできないことが判明しました。
1. アップロードできる上限サイズを確認
a-blog cms 管理ページのサイドメニューから「チェックリスト」へ。
「サーバー環境情報」を見ると、デフォルトの設定が
アップロード上限サイズ 2M
POSTデータ上限サイズ 8M
になっています。
2. アップロードできる上限サイズを変更
php.ini ファイルを編集して上限サイズを変更します。
; アップロード上限サイズ
upload_max_filesize = 20M
; POSTデータ上限サイズ
post_max_size = 20M
わたしは20MBに設定しました。
3. PDFファイルをアップロード
再度試してみると、2MBを超えるファイルでもアップロードできるようになりました。
サムネイル画像もちゃんと生成できていますね!
4. もしアップロードできなかったら…
上限サイズを変更してもファイルがアップロードできないときは /archives ディレクトリ以下のパーミッションを確認します。
(共用サーバの場合はパーミッションを705、専用サーバ・VPSの場合は777に設定)
最終的な php.ini はこんな感じに。
おわりに
ツール等をインストールする必要が無いので、ローカルで設定するよりもはるかに簡単でした!
さくらのレンタルサーバほんと大好き。