Skip to content

Commit

Permalink
BcUpload 同一モデルの複数保存に対応 (#2495)
Browse files Browse the repository at this point in the history
  • Loading branch information
seto1 authored Oct 9, 2023
1 parent fe1da7c commit 4411987
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 45 deletions.
12 changes: 7 additions & 5 deletions plugins/baser-core/src/Model/Behavior/BcUploadBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public function beforeMarshal(EventInterface $event, ArrayObject $data)
{
$this->BcFileUploader[$this->table()->getAlias()]->setupRequestData($data);
$this->BcFileUploader[$this->table()->getAlias()]->setupTmpData($data);
$this->oldEntity[$this->table()->getAlias()] = (!empty($data['id']))? $this->getOldEntity($data['id']) : null;
$this->oldEntity[$this->table()->getAlias()][$data['_bc_upload_id']] = (!empty($data['id']))? $this->getOldEntity($data['id']) : null;
}

/**
Expand Down Expand Up @@ -160,12 +160,14 @@ public function afterMarshal(EventInterface $event, EntityInterface $entity, Arr
*/
public function afterSave(EventInterface $event, EntityInterface $entity)
{
if ($entity->id && !empty($this->oldEntity[$this->table()->getAlias()])) {
$this->BcFileUploader[$this->table()->getAlias()]->deleteExistingFiles($this->oldEntity[$this->table()->getAlias()]);
if ($entity->id && !empty($this->oldEntity[$this->table()->getAlias()][$entity->_bc_upload_id])) {
$oldEntity = $this->oldEntity[$this->table()->getAlias()][$entity->_bc_upload_id];
$oldEntity->_bc_upload_id = $entity->_bc_upload_id;
$this->BcFileUploader[$this->table()->getAlias()]->deleteExistingFiles($oldEntity);
}
$this->BcFileUploader[$this->table()->getAlias()]->saveFiles($entity);
if ($entity->id && !empty($this->oldEntity[$this->table()->getAlias()])) {
$this->BcFileUploader[$this->table()->getAlias()]->deleteFiles($this->oldEntity[$this->table()->getAlias()], $entity);
if ($entity->id && !empty($this->oldEntity[$this->table()->getAlias()][$entity->_bc_upload_id])) {
$this->BcFileUploader[$this->table()->getAlias()]->deleteFiles($this->oldEntity[$this->table()->getAlias()][$entity->_bc_upload_id], $entity);
}
if ($this->BcFileUploader[$this->table()->getAlias()]->isUploaded()) {
$this->BcFileUploader[$this->table()->getAlias()]->renameToBasenameFields($entity);
Expand Down
36 changes: 22 additions & 14 deletions plugins/baser-core/src/Utility/BcFileUploader.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ class BcFileUploader
*/
private $uploadingFiles = [];

/**
* 同一テーブルのデータを複数扱う場合の競合対策のための固有ID
*
* @var int
*/
private $bcUploadId = 1;

/**
* Initialize
* @param array $config
Expand Down Expand Up @@ -213,7 +220,8 @@ public function setupRequestData($data)
}
$files[$name] = $file;
}
$this->setUploadingFiles($files);
$data['_bc_upload_id'] = $this->bcUploadId++;
$this->setUploadingFiles($files, $data['_bc_upload_id']);
return $data;
}

Expand All @@ -230,7 +238,7 @@ public function setupTmpData($data)
foreach($this->settings['fields'] as $setting) {
$name = $setting['name'];
if (isset($data[$name . '_tmp']) && $this->moveFileSessionToTmp($data, $name)) {
$data[$setting['name']] = $this->getUploadingFiles()[$setting['name']];
$data[$setting['name']] = $this->getUploadingFiles($data['_bc_upload_id'])[$setting['name']];
// セッションに一時ファイルが保存されている場合は復元する
unset($data[$setting['name'] . '_tmp']);
}
Expand Down Expand Up @@ -281,7 +289,7 @@ public function isUploadable($fileType, $contentType, $file)
*/
public function saveFiles($entity)
{
$files = $this->getUploadingFiles();
$files = $this->getUploadingFiles($entity->_bc_upload_id);
$this->uploaded = false;
foreach($this->settings['fields'] as $setting) {
$file = $files[$setting['name']] ?? [];
Expand All @@ -293,7 +301,7 @@ public function saveFiles($entity)
}
}
}
$this->setUploadingFiles($files);
$this->setUploadingFiles($files, $entity->_bc_upload_id);
}

/**
Expand Down Expand Up @@ -370,7 +378,7 @@ public function saveFile($setting, $file)
*/
public function deleteFiles($oldEntity, $newEntity, $force = false)
{
$files = $this->getUploadingFiles();
$files = $this->getUploadingFiles($newEntity->_bc_upload_id);
foreach($this->settings['fields'] as $setting) {
$file = $files[$setting['name']] ?? [];
$newEntity = $this->deleteFileWhileChecking($setting, $file, $newEntity, $oldEntity, $force);
Expand Down Expand Up @@ -479,7 +487,7 @@ public function moveFileSessionToTmp($data, $fieldName)
$uploadInfo['uploadable'] = true;
$uploadInfo['ext'] = BcUtil::decodeContent($fileType, $fileName);
$uploadedFile[$fieldName] = $uploadInfo;
$this->setUploadingFiles($uploadedFile);
$this->setUploadingFiles($uploadedFile, $data['_bc_upload_id']);
return true;
}

Expand Down Expand Up @@ -665,7 +673,7 @@ public function getImageSize($path)
public function renameToBasenameFields($entity, $copy = false)
{
if (!$copy) {
$files = $this->getUploadingFiles();
$files = $this->getUploadingFiles($entity->_bc_upload_id);
}
foreach($this->settings['fields'] as $setting) {
if ($copy) {
Expand Down Expand Up @@ -977,7 +985,7 @@ public function isFileExists(string $fileName): bool
public function deleteExistingFiles($oldEntity, $force = false): void
{
if (!$oldEntity) return;
$files = $this->getUploadingFiles();
$files = $this->getUploadingFiles($oldEntity->_bc_upload_id);
if (!$files) return;
foreach($files as $name => $file) {
if(!empty($file['uploadable']) || $force) {
Expand Down Expand Up @@ -1030,9 +1038,9 @@ public function copyImages(array $setting, array $file): void
* @noTodo
* @unitTest
*/
public function setUploadingFiles(array $files): void
public function setUploadingFiles(array $files, $bcUploadId): void
{
$this->uploadingFiles = $files;
$this->uploadingFiles[$bcUploadId] = $files;
}

/**
Expand All @@ -1041,9 +1049,9 @@ public function setUploadingFiles(array $files): void
* @noTodo
* @unitTest
*/
public function getUploadingFiles(): array
public function getUploadingFiles($bcUploadId): array
{
return $this->uploadingFiles ?? [];
return $this->uploadingFiles[$bcUploadId] ?? [];
}

/**
Expand All @@ -1062,7 +1070,7 @@ public function saveTmpFiles($data, $tmpId)
$this->Session->delete('Upload');
$this->tmpId = $tmpId;
$data = $this->setupRequestData($data);
$files = $this->getUploadingFiles();
$files = $this->getUploadingFiles($data['_bc_upload_id']);
$entity = new Entity($data);
foreach($this->settings['fields'] as $setting) {
$fileName = $this->saveTmpFile($setting, $files[$setting['name']], $entity);
Expand All @@ -1079,7 +1087,7 @@ public function saveTmpFiles($data, $tmpId)
unset($entity[$field]);
}
}
$this->setUploadingFiles($files);
$this->setUploadingFiles($files, $data['_bc_upload_id']);
return $entity;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,14 @@ public function testInitialize()
*/
public function testBeforeMarshal()
{
$this->table->dispatchEvent('Model.beforeMarshal', ['data' => new ArrayObject($this->uploadedData), 'options' => new ArrayObject()]);
$data = new ArrayObject($this->uploadedData);
$this->table->dispatchEvent('Model.beforeMarshal', ['data' => $data, 'options' => new ArrayObject()]);
// setupRequestDataが実行されてるか確認
$this->assertNotNull($this->BcUploadBehavior->BcFileUploader[$this->table->getAlias()]->getUploadingFiles());
$this->assertNotNull(
$this->BcUploadBehavior
->BcFileUploader[$this->table->getAlias()]
->getUploadingFiles($data['_bc_upload_id'])
);
}

/**
Expand All @@ -145,10 +150,11 @@ public function testAfterSave()
'uploadable' => true
]
];
$this->BcUploadBehavior->BcFileUploader[$this->table->getAlias()]->setUploadingFiles($uploadedFile);
$bcUploadId = 1;
$this->BcUploadBehavior->BcFileUploader[$this->table->getAlias()]->setUploadingFiles($uploadedFile, $bcUploadId);
$this->BcUploadBehavior->BcFileUploader[$this->table->getAlias()]->settings['fields']['eyecatch'] = $this->eyecatchField;
// 新規保存の場合
$entity = new Entity(['id' => 6, 'eyecatch' => 'baser.power.gif']);
$entity = new Entity(['id' => 6, 'eyecatch' => 'baser.power.gif', '_bc_upload_id' => $bcUploadId]);
$this->table->dispatchEvent('Model.afterSave', ['entity' => $entity, 'options' => new ArrayObject()]);
$this->assertFileExists($this->savePath . 'baser.power.gif');
// 削除の場合
Expand Down Expand Up @@ -249,8 +255,9 @@ public function testRenameToBasenameFields($filename, $copy, $fileList)
// 初期化
$entity = $this->table->get(1);
$entity->eyecatch = $filename;
$entity->_bc_upload_id = 1;
$uploader = $this->BcUploadBehavior->getFileUploader();
$uploader->setUploadingFiles(['eyecatch' => ['name' => $filename, 'ext' => 'txt']]);
$uploader->setUploadingFiles(['eyecatch' => ['name' => $filename, 'ext' => 'txt']], $entity->_bc_upload_id);

// ダミーファイルの生成
touch($this->savePath . $filename);
Expand Down
52 changes: 31 additions & 21 deletions plugins/baser-core/tests/TestCase/Utility/BcFileUploaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,12 @@ public function testSetupRequestData()
'error' => 0
]
]);
$this->BcFileUploader->setupRequestData($data);
$uploaded = $this->BcFileUploader->getUploadingFiles();
$data = $this->BcFileUploader->setupRequestData($data);
$uploaded = $this->BcFileUploader->getUploadingFiles($data['_bc_upload_id']);
$this->assertFalse($uploaded['eyecatch']['uploadable']);
// upload=trueの場合のテスト
$this->BcFileUploader->setupRequestData($this->uploadedData);
$uploaded = $this->BcFileUploader->getUploadingFiles();
$uploadedData = $this->BcFileUploader->setupRequestData($this->uploadedData);
$uploaded = $this->BcFileUploader->getUploadingFiles($uploadedData['_bc_upload_id']);
$this->assertTrue($uploaded['eyecatch']['uploadable']);
$this->assertEquals("png", $uploaded['eyecatch']['ext']);
// 新しいデータが送信されず、既存データを引き継ぐ場合
Expand All @@ -225,8 +225,8 @@ public function testSetupRequestData()
],
'eyecatch_' => 'test.png',
]);
$this->BcFileUploader->setupRequestData($data);
$uploaded = $this->BcFileUploader->getUploadingFiles();
$data = $this->BcFileUploader->setupRequestData($data);
$uploaded = $this->BcFileUploader->getUploadingFiles($data['_bc_upload_id']);
$this->assertFalse($uploaded['eyecatch']['uploadable']);
$this->assertEquals("test.png", $data['eyecatch']);
}
Expand Down Expand Up @@ -299,13 +299,14 @@ public function testDeleteFiles()
'_' => '00000006_eyecatch.gif'
]
];
$this->BcFileUploader->setUploadingFiles($file);
$bcUploadId = 1;
$this->BcFileUploader->setUploadingFiles($file, $bcUploadId);
$targetPath = $this->savePath . $fileName;
touch($targetPath);
$this->BcFileUploader->deleteFiles($this->ContentsService->get(6), new Content());
$this->BcFileUploader->deleteFiles($this->ContentsService->get(6), new Content(['_bc_upload_id' => $bcUploadId]));
$this->assertFileDoesNotExist($targetPath);
touch($targetPath);
$this->BcFileUploader->deleteFiles(new Content(), new Content());
$this->BcFileUploader->deleteFiles(new Content(), new Content(['_bc_upload_id' => $bcUploadId]));
$this->assertFileExists($targetPath);
@unlink($targetPath);
}
Expand Down Expand Up @@ -351,8 +352,9 @@ public function testSaveFiles()
$filePath = $this->savePath . $this->uploadedData['eyecatch']['name'];
$tmp = $this->uploadedData['eyecatch']['tmp_name'];
touch($tmp);
$this->BcFileUploader->setUploadingFiles($this->uploadedData);
$this->BcFileUploader->saveFiles(new Content());
$bcUploadId = 1;
$this->BcFileUploader->setUploadingFiles($this->uploadedData, $bcUploadId);
$this->BcFileUploader->saveFiles(new Content(['_bc_upload_id' => $bcUploadId]));
$this->assertFileExists($filePath);
unlink($filePath);
}
Expand Down Expand Up @@ -522,15 +524,17 @@ public function testMoveFileSessionToTmp()
$targetName = $entity->eyecatch_tmp;
$targetPath = $this->savePath . str_replace(['.', '/'], ['_', '_'], $targetName);

$bcUploadId = 1;
$data = new ArrayObject([
"{$fieldName}_tmp" => $entity->eyecatch_tmp,
'_bc_upload_id' => $bcUploadId,
]);
// セッションからファイルを保存
$this->BcFileUploader->moveFileSessionToTmp($data, $fieldName);

// 判定
$this->assertFileExists($targetPath, 'セッションに保存されたファイルデータをファイルとして保存できません');
$result = $this->BcFileUploader->getUploadingFiles()[$fieldName];
$result = $this->BcFileUploader->getUploadingFiles($bcUploadId)[$fieldName];
$expected = [
'error' => 0,
'name' => $targetName,
Expand Down Expand Up @@ -717,14 +721,16 @@ public function testDeleteFile($prefix, $suffix, $imagecopy, $message)
// copyのダミーファイルを生成
if (is_array($this->eyecatchField['imagecopy'])) {
copy(ROOT . '/plugins/bc-admin-third/webroot/img/baser.power.gif', $tmpPath . $fileName . '.' . $ext);
$bcUploadId = 1;
$uploaded = [
'dummy' => [
'name' => $fileName . '.' . $ext,
'tmp_name' => $tmpPath . $fileName . '.' . $ext,
'ext' => $ext
]
'ext' => $ext,
'_bc_upload_id' => $bcUploadId,
],
];
$this->BcFileUploader->setUploadingFiles($uploaded);
$this->BcFileUploader->setUploadingFiles($uploaded, $bcUploadId);
foreach($this->eyecatchField['imagecopy'] as $copy) {
$copy['name'] = $fileName;
$copy['ext'] = $this->eyecatchField['ext'];
Expand Down Expand Up @@ -783,7 +789,8 @@ public function testRenameToFieldBasename($oldName, $ext, $copy, $imagecopy, $me
$entity = $this->table->get(1);
$oldName = $oldName . '.' . $ext;
$entity->eyecatch = $oldName;
$this->BcFileUploader->setUploadingFiles(['eyecatch' => ['name' => $oldName, 'ext' => $ext]]);
$entity->_bc_upload_id = 1;
$this->BcFileUploader->setUploadingFiles(['eyecatch' => ['name' => $oldName, 'ext' => $ext]], $entity->_bc_upload_id);
$setting = $this->BcFileUploader->settings['fields']['eyecatch'];

if ($imagecopy) {
Expand Down Expand Up @@ -1072,7 +1079,7 @@ public function testDeleteExistingFiles()
// ダミーのファイルを生成
touch($targetPath);
// アップロードされていなければ、returnで終了
$this->BcFileUploader->setUploadingFiles([]);
$this->BcFileUploader->setUploadingFiles([], 1);
$this->BcFileUploader->deleteExistingFiles($this->ContentsService->get(6));
$this->assertFileExists($targetPath);
// アップロードされていれば削除処理
Expand All @@ -1081,9 +1088,12 @@ public function testDeleteExistingFiles()
'tmp_name' => TMP . $fileName . '.' . $this->eyecatchField['ext'],
'uploadable' => true
];
$this->BcFileUploader->setUploadingFiles(['eyecatch' => $uploaded]);
$bcUploadId = 1;
$this->BcFileUploader->setUploadingFiles(['eyecatch' => $uploaded], $bcUploadId);
$this->BcFileUploader->settings['fields']['eyecatch'] = $this->eyecatchField;
$this->BcFileUploader->deleteExistingFiles($this->ContentsService->get(6));
$content = $this->ContentsService->get(6);
$content->_bc_upload_id = $bcUploadId;
$this->BcFileUploader->deleteExistingFiles($content);
$this->assertFileDoesNotExist($targetPath);
@unlink($targetPath);
}
Expand Down Expand Up @@ -1155,8 +1165,8 @@ public function copyImagesDataProvider()
*/
public function testSetAndGetUploadedFile()
{
$this->BcFileUploader->setUploadingFiles($this->uploadedData);
$this->assertEquals($this->uploadedData, $this->BcFileUploader->getUploadingFiles());
$this->BcFileUploader->setUploadingFiles($this->uploadedData, 1);
$this->assertEquals($this->uploadedData, $this->BcFileUploader->getUploadingFiles(1));
}

/**
Expand Down

0 comments on commit 4411987

Please sign in to comment.