mediaプラグイン応用(2) アップロードファイル名の変更

mediaプラグインでアップロードしたファイル名を、任意に変更してみました。

元々のファイル名のままだと、日本語のファイル名で不正エラーになるケースがあったり、サーバ側でファイルを扱えなくなる可能性があるので、ファイル名変更は必須です。


Attachmentモデルを拡張して実装しました。


参考サイトさんに、

保存ファイル名の変更

media/models/behaviors/transfer.php のコメントをみるとだいたい分かる。

とあるので、ソースを見て見ました。


たぶんここのことでしょう。
media/models/behaviors/transfer.php

/**
 * Default settings
(中略)
 * destinationFile
 *  A path (withouth leading slash) relative to `baseDirectory`.
 *
 * 	These markers can be used:
 * 	:DS:                    Directory separator `'/'` or `'\'`
 *  :uuid:                  An uuid generated by String::uuid()
 *  :day:                   The current day
 * 	:month:                 The current month
 * 	:year:                  The current year
 * 	:Model.name:
 *  :Model.alias:
 *  :Model.xyz:             Where `xyz` is a field of the submitted record
 * 	:Source.basename:       e.g. `'logo.png'`
 * 	:Source.filename:       e.g. `'logo'`
 * 	:Source.extension:      e.g. `'png'`
 * 	:Source.mimeType:       e.g. `'image_png'`
 * 	:Medium.name:           Lowercased medium name of the source file (e.g. `'image'`)
 * 	:Medium.short:          Short medium name of the source file (e.g. `'img'`)
 *

デフォルトの設定が

var $_defaultSettings = array(
	'trustClient'     => false,
	'destinationFile' => ':Medium.short::DS::Source.basename:',

なので、画像をアップすると
  img/元のファイル名.拡張子
となる理屈にあいます。


ビヘイビアの設定は、モデルで使う時の$actAsで変更できます。
http://book.cakephp.org/ja/view/90/Using-Behaviors


Attachmentモデルでも、設定が明示されていました。

media/models/attachment.php

var $actsAs = array(
(中略)
	'Media.Transfer' => array(
		'trustClient'     => false,
		'destinationFile' => ':Medium.short::DS::Source.basename:',


ところが、transferビヘイビアでは、$_defaultSettingsをsetup()メソッドで読み込みセットしてしまっています。

function setup(&$Model, $config = null) {
(中略)
	$this->settings[$Model->alias] = $config + $this->_defaultSettings;
	$this->runtime[$Model->alias] = $this->_defaultRuntime;
}

Attachmentモデルを呼び出した後に$actsAsの設定を変更しても、もう意味がありません・・・


mediaプラグイン自体は変更したくなかったので、Attachmentの拡張モデルを作って$actsAsを設定しました。

attachment_ex.php

<?php
/**
 * Extend of Attachment Model File
 */
app::import('Media.Attachment');
class AttachmentEx extends Attachment {
	var $name = 'AttachmentEx';


	function __construct($id = false, $table = null, $ds = null) {

		$this->actsAs['Media.Transfer']['destinationFile'] = ':Medium.short::DS::uuid:'.'.'.':Source.extension:';

		parent::__construct($id, $table, $ds);
	}

}

__construct()の変数は、拡張元を辿ってmodel.phpをベースに設定しています。


AttachmentEx対応のソース変更点

--- a/app/models/user.php
+++ b/app/models/user.php
@@ -14,7 +14,7 @@ class User extends AppModel {
        var $hasMany = array(
                'Attachment' => array(
-                       'className' => 'Media.Attachment',
+                       'className' => 'Media.AttachmentEx',
                        'foreignKey' => 'foreign_key',


以上の改修で、アップロードファイル名をString::uuid()で生成する文字列にすることができました。

mysql> SELECT * FROM attachments\G
*************************** 1. row ***************************
         id: 30
      model: User
foreign_key: 1
    dirname: transfer/img
   basename: 4b7bfb71-3f10-43c9-a6a7-0a72c0a80b08.jpg
   checksum: 44f459734b6067be6aefd27b75a5ded3
      group: attachment
alternative: 
    created: 2010-02-17 23:21:37
   modified: 2010-02-17 23:21:37
1 row in set (0.00 sec)

[cake@cake cake-frame]$ ls app/webroot/media/transfer/img/4b7bfb71-3f10-43c9-a6a7-0a72c0a80b08.jpg
app/webroot/media/transfer/img/4b7bfb71-3f10-43c9-a6a7-0a72c0a80b08.jpg