
何の参考にもならんと思うが🐱
一時ファイルアップロードしてから本ディレクトリにコミットする流れの汎用クラス
FileUploadToS3Service.php
<?php
namespace App\Services;
use App\Exceptions\FileUploadException;
use Prettus\Repository\Generators\FileAlreadyExistsException;
use Illuminate\Filesystem\FilesystemManager;
use Illuminate\Support\Str;
/**
* 汎用ファイルアップロード処理
*
* @author masuda
*/
class FileUploadTo3Service
{
protected $client_s3;
public function __construct(
FilesystemManager $file_system_manager
) {
$this->client_s3 = $file_system_manager->disk('s3');
}
/**
* 非公開一時ファイルアップロード
*
*/
public function privateTemporaryUpload(
UploadedFile $upload_file,
int $company_id,
string $type,
?bool $is_original_name = true
):array {
$temp_path = $path = config('const.PRIVATE_FILEUPLOAD_TEMP_PATH') . '/' . $company_id . '/';
// ディレクトリチェック なかったらS3に保存領域を作成
$this->_createDirectory($temp_path);
$file_name = $upload_file->getClientOriginalName();
$response = $this->_putFile($upload_file, $path, $file_name, $is_original_name);
if (!$response) {
throw new FileUploadException("テンポラリー登録に失敗しました。");
}
return [
'file_name' => $file_name,
'file_path' => $temp_path . $file_name,
'mime' => $upload_file->getMimeType(),
'size' => $upload_file->getSize(),
];
}
/**
* 非公開一時ファイルを利用用途別の本ディレクトリに移動
*
* @param int $company_id,
* @param string $now_file_path,
* @param string $file_name,
* @param string $usage,
* @param bool $is_original_name = false
* @return string
*/
public function commitPrivateFile(
int $company_id,
string $now_file_path,
string $file_name,
string $usage,
bool $is_original_name = false
):string {
// 本ディレクトリを取得
switch ($usage) {
case 'SALES':
$base_path = config('const.PRIVATE_FILEUPLOAD_USAGE.SALES.BASE_PATH');
break;
case 'SYSTEM':
$base_path = config('const.PRIVATE_FILEUPLOAD_USAGE.SYSTEM.BASE_PATH');
break;
case 'ADMIN':
$base_path = config('const.PRIVATE_FILEUPLOAD_USAGE.ADMIN.BASE_PATH');
break;
default:
throw new FileUploadException("利用用途の指定が間違っています。");
}
// 本ディレクトリの組み立て
$target_dir = $base_path . '/' . $company_id . '/';
// S3にディレクトリ作成
$this->_createDirectory($target_dir);
// ファイル設置先パスの組み立て
if ($is_original_name) {
$target_path = $target_dir . $file_name;
} else {
// 同名ファイルアップロードでの上書きを防止
$target_path = $target_dir . Str::uuid() . '-' . $file_name;
}
// 現在のファイルパスの先頭に'private/temp/'がパスに付いていなかったら、すでに本登録されたファイルであるので現在のパスを返却だけする
$base_temp_path = preg_quote(config('const.PRIVATE_FILEUPLOAD_TEMP_PATH'), '/');
if (preg_match('/^'. $base_temp_path . '\/(.*)/', $now_file_path) === 0) {
return $now_file_path;
}
// 本ディレクトリにファイルを移動
if ($this->client_s3->exists($now_file_path)) {
$this->client_s3->move($now_file_path, $target_path);
return $target_path;
} else {
throw new FileUploadException("本ディレクトリへの登録に失敗しました。改めて一時ファイルアップロードを行ってください。");
}
}
/**
* S3にディレクトリ作成
*
* @param string
* @return void
*/
private function _createDirectory(string $path):void
{
if (!$this->client_s3->exists($path)) {
$this->client_s3->makeDirectory($path);
}
}
/**
* S3にディレクトリ作成
*
* @param string
* @return void
*/
private function _putFile(UploadedFile $upload_file, string $path, string $file_name, bool $is_original_name)
{
// $is_original_nameがtrueの場合は上書き可なので通過させる
if ($is_original_name === false) {
// ファイルの存在チェック
if ($this->exists($path, $file_name)) {
// すでに存在してたら例外エラー
throw new FileAlreadyExistsException('すでにファイルが存在しています。');
}
}
// ファイルをS3指定パスに保存
$save_file_name = $path . $file_name;
$options = [
'Tagging' => 'isTemp=1',
'TaggingDirective' => 'REPLACE'
];
return $this->clientS3->put($save_file_name, $this->fileSystem->get($upload_file), $options);
}
/**
* ファイル存在チェック
*
* @param string $path
* @param $file_name
* @return bool
*/
public function exists(string $path, string $file_name)
{
$check_file_name = $path . $file_name;
return $this->clientS3->exists($check_file_name);
}
}
関連

