ストレージ
ビヘイビアは、1つのファイルを最大3か所に保存できます。
filePathで指定したローカルのディレクトリ- 添付ファイルのテーブルの
file_objectカラム - Amazon S3
Labelヘルパーは、S3のURLを指定しないかぎりローカルのファイルを表示します。データベースとS3に置くのはファイルのコピーで、ローカルのファイルがなくなったときはfind()がこのコピーから復元します。
ストレージを選ぶ
コピーの置き場所は、ビヘイビアのstorage設定で選びます。デフォルトでは、ビヘイビアはデータベースにコピーを置きます。次のモデルは、データベースとS3にコピーを置きます。
public $actsAs = [
'Filebinder.Bindable' => [
'storage' => [BindableBehavior::STORAGE_DB, BindableBehavior::STORAGE_S3],
],
];次のモデルは、ローカルのファイルだけを残します。
public $actsAs = [
'Filebinder.Bindable' => [
'storage' => false,
],
];ローカルにファイルを残さない場合は、filePathをfalseにします。ビヘイビアはストレージにだけファイルを保存します。
ローカルのディレクトリ
ビヘイビアは、次のパスにファイルを保存します。
<filePath>/<model>/<model_id>/<field_name>/<file_name>
filePathには、フィールドのfilePathを使います。フィールドになければ、ビヘイビアのfilePath設定を使います。デフォルトはWWW_ROOT . 'img' . DSです。
ビヘイビアは、ディレクトリをdirModeの0755で、ファイルをfileModeの0644で作ります。
webrootの下に置いたファイルには公開のURLがあり、誰でも開けます。webrootの外に置いたファイルには、それ自体のURLがありません。Labelヘルパーは、このファイルをプラグインのloaderアクション経由でリンクします。loaderアクションは、先に署名を確認します。ファイルのURLを参照してください。
パスを変える
ファイルを別のパスに保存するには、モデルでtransferTo()をオーバーライドします。このメソッドは、filePathからの相対パスを返します。
/**
* Returns the path of a file, relative to `filePath`.
*
* @param array $data File data.
* @return string
*/
public function transferTo($data)
{
return $this->alias . DS . $data['model_id'] . DS . $data['field_name'] . DS . $data['file_name'];
}ビヘイビアは、ファイルを保存するときと、あとでファイルを探すときの両方でtransferTo()を呼びます。そのため、同じファイルの情報に対しては毎回同じパスを返してください。mt_rand()、uniqid()、time()のような乱数や時刻は使えません。
データベース
データベースのストレージでは、ビヘイビアは各ファイルの内容をBase64にしてfile_objectカラムに保存します。
find()は、デフォルトではfile_objectを返しません。内容が必要なときはwithObjectを有効にします。
$this->Post->withObject(true);S3のストレージも使っている場合、データベースに内容がなければ、withObjectはS3から内容をダウンロードします。
ファイルの復元
find()は、次のどちらかのときにストレージからローカルのファイルを復元します。
- ローカルのファイルがない
- ローカルのファイルが、レコードの
modifiedの時刻より古い
ビヘイビアはデータベースからファイルを復元します。S3のストレージを使っている場合はS3から復元します。復元したファイルにはfileModeを設定し、そのパスを渡してafterAttachコールバックを呼びます。
復元を止めるには、restoreFromStorageをfalseにします。
$this->Post->setSettings(['restoreFromStorage' => false]);ファイルの差し替えと削除
すでにファイルのあるフィールドに新しいファイルを保存すると、新しいファイルで差し替わります。デフォルトでは、ビヘイビアは古いファイルを削除します。exchangeFileをfalseにすると、古いファイルのレコードだけを削除し、ファイルはそのまま残します。
フィールドのファイルを削除するには、delete_<field>に真の値を入れて保存します。フォームにチェックボックスを置くと、この値を送れます。
echo $this->Form->input('delete_image', ['type' => 'checkbox', 'label' => __('Delete the image')]);レコードを削除すると、ビヘイビアはそのレコードのファイルも削除します。
レコードを残してファイルだけを削除するには、deleteEntity()にレコードのIDとフィールドを渡します。
$this->Post->deleteEntity($id, 'image');フィールドを省略すると、deleteEntity()はレコードのすべてのフィールドのファイルを削除します。
