mediaプラグイン応用(4) Versionファイルを表示時に作成する

デフォルトだと、ファイルのアップロード時にVersionファイルを全て作成します。

これだと、

  1. Versionファイルの容量がかさむ
  2. あとからVersionファイルの設定を追加した場合、以前からのファイルに対応できない

等があるので、VersionファイルをViewで呼び出したときに作成するように改修してみました。


 ちょっとややこしい&改善の余地ありそう ですが・・・・

アップロード時のVersionファイル作成停止

Versionファイルの作成を行なうか否かの設定は、Mediaビヘイビアの$_defaultSettingsにあります。

var $_defaultSettings = array(
	'metadataLevel'   => 1,
	'baseDirectory'   => MEDIA,
	'makeVersions'    => true, // ←これ
	'filterDirectory' => MEDIA_FILTER,
	'createDirectory' => true,
);

これを、アップロードファイル名の変更と同様に、拡張Attachmentモデルで設定変更して、Versionファイルの作成設定をOFFにします。

plugins/media/models/attachment_ex.php

@@ -10,7 +10,10 @@ class AttachmentEx extends Attachment {
function __construct($id = false, $table = null, $ds = null) {

                // Uploadファイルの保存設定
               // ファイル名
                $this->actsAs['Media.Transfer']['destinationFile'] = ':Medium.short::DS::uuid:'.'.'.':Source.extension:';
+               // VersionFile作成
+               $this->actsAs['Media.Media']['makeVersions'] = false;

これで、アップロードした時にtransferディレクトリにファイルは保管されますが、filtersには出力されなくなります。

[cake@cake cake-frame]$ ls app/webroot/media/transfer/img/
4b7cde08-c068-430f-80d8-0a72c0a80b08.jpg
[cake@cake cake-frame]$ ls app/webroot/media/filter/s/transfer/img/
[cake@cake cake-frame]$

Versionファイルの閲覧時出力

次に「versionファイルにアクセス」→「なければ作成して、出力」の処理を追加します。


Versionファイルの作成メソッドは、mediaプラグインのmediaビヘイビアにあります。
afterSave()メソッドからコールされてることで見当をつけました。


mediumヘルパーでファイル表示の典型例は、

  1. file()でパスを取得
  2. embed()でタグを作成

の二段階です。

echo $medium->embed($medium->file('filter/s', $target_user['Attachment'][0]));

$target_user['Attachment'][0]の例

id
 79
dirname
 transfer/img
basename
 4b81d7d9-0e28-451d-b4e4-20e0c0a80b08.jpg
alternative
 null


mediumヘルパーを拡張して、file()メソッドでVersionファイルを出力する独自ヘルパーを作成しました。

Versionファイル作成のメソッドは、MVCとは独立のライブラリとして追加しました。


細かい処理がいろいろありますが、要点は、

  1. core.phpで指定のVersionファイル出力設定を読み込む
  2. 指定サイズ以外の出力設定は削除して、make()メソッド実行

の2点です。

追加ソース

media/views/helpers/upfile.php

<?php 
class UpfileHelper extends MediumHelper {
	function file($path)
	{
		$args = func_get_args();

		// ファイルがある場合、ファイルパスを返す
		$file = parent::file($path, $args[1]);
		if (is_file($file) && is_readable($file)) {

			return $file;

		// $pathがfilter/*指定でファイルがない場合、作成
		} elseif (substr($path, 0, 7) == 'filter/') {
			require_once(APP.'plugins'.DS.'media'.DS.'libs'.DS.'upfile.php');
			$make_result = Upfile::make_version($path, $args[1]['dirname']. DS. $args[1]['basename'], $args[2]);

			// cacheを削除して$file読み込み
			if ($make_result === true) {
				parent::__destruct();
				return self::file($path, $args[1]);
			}
		}

		return null;
	}
}

media/libs/upfile.php

<?php 
/* 
 * ファイルアップロード処理
 */
App::import('Core', 'Shell');

class Upfile extends Object {

	/* Versionファイルの個別作成 */
	function make_version($path, $orig_filepath, $model_name)
	{
		// Confirgureの設定
		$name = Medium::name($orig_filepath);
		$filters = Configure::read('Media.filter.'. strtolower($name));
		if (empty($filters)) {
			return false;
		}
		$dir = substr_replace($path, '', 0, strlen('filter/'));
		if (empty($dir)) {
			return false;
		}
		if (!isset($filters[$dir])) {
			return false;
		}
		Configure::write('Media.filter.'. strtolower($name), array($dir => $filters[$dir]));

		if (!isset($model_name)) {
			return null;
		}
		$Model = CorePlus::set_model($model_name);
		$Media = CorePlus::set_behavoir('Media.Media');

		$Media->setup($Model);
		$result = $Media->make($Model, $orig_filepath);

		// Configure戻す
		Configure::write('Media.filter.'. strtolower($name), $filters);

		return $result;
	}

}

Uploadヘルパーを使用するための追加改修

app/controllers/app_controller.php

var $helpers = array(
	'Html',
	'Form',
	'Media.Medium',
+	'Media.Upfile',
	'Token'
);

app/views/elements/home.ctp

-echo $medium->embed($medium->file('filter/s', $target_user['Attachment'][0]));
+$file = $upfile->file('filter/m', $target_user['Attachment'][0], 'User');

+if (!empty($file)) {
+    echo $medium->embed(
+        $file,
+        array(
+            'restrict' => array('image')
+        )
+    );
+} else {
+    echo "&nbsp;";
+}