開発情報・ナレッジ

投稿者: ShiningStar株式会社 2024年10月10日 (木)

アップロードされるファイルの名前をレコードの値に揃えてリネームするサンプル

全体像

SPIRALのDBにアップロードされるファイルのファイル名は、アップロード者依存してしまいます。
ファイル名をレコードの値にリネームし、管理しやすくするためのサンプルプログラムです。
例えば自動発番される会員IDを用いてアップロードされるファイルを下記の形式にすることで、管理しやすい状態にします。
会員ID_本人確認書類.docx
会員ID_身分証写真.jpg

DB設定

任意のDBを作成して、会員IDのようなユニークになる"テキストフィールド"と添付用の"ファイルフィールド"を準備してください。
テキストフィールドには自動発番設定をして会員ID(例USER_レコードID10桁)等を発番すると、
USER_0000000001_A.jpgの様な形にリネームさせる事が可能です。
次にDB設定画面のトリガタブに移動して非同期アクションを作成してください。
その上で後述するPHPを貼り付けてください。

PHP(非同期アクション)

<?php
//------------------------------
// 設定値
//------------------------------
define("API_URL", "https://api.spiral-platform.com/v1");
define("API_KEY", "");
define("APP_ROLE", "");
define("APP_ID", "");
define("DB_ID", "");
// 複数のファイルフィールドとテキストフィールドの組み合わせ
$fieldMappings = [
    [
        'fileFieldTitle' => 'file1', // リネームしたいファイルフィールドの識別名 
        'fileFieldId' => '2', // ファイルフィールドのIDを設定
        'textFieldTitle' => 'text1', // 自動発番されるフィールドの識別名
        'prefix' => ['接頭語1_', '接頭語2_'], // 接頭語
        'suffixes' => ['_接尾語1', '_接尾語2'] // 接尾語
    ],
    [
        'fileFieldTitle' => 'file2', 
        'fileFieldId' => '4', 
        'textFieldTitle' => 'text2',
        'prefix' => [], // 接頭語なし
        'suffixes' => [] // 接尾語なし
    ]
];

//------------------------------
// API実行
//------------------------------
$commonBase = CommonBase::getInstance();

// レコード取得
$record = $SPIRAL->getRecord();

foreach ($fieldMappings as $mapping) {
    $fileFieldId = $mapping['fileFieldId'];
    $fileFieldTitle = $mapping['fileFieldTitle'];
    $textFieldTitle = $mapping['textFieldTitle'];
    $prefixes = $mapping['prefix'];
    $suffixes = $mapping['suffixes'];

    // テキストフィールドとファイルフィールドの値を取得
    $textValue = $record['item'][$textFieldTitle];
    $files = $record['item'][$fileFieldTitle];

    // ファイルキーを格納する配列
    $fileKeyArray = [];

    //------------------------------
    // ファイルをダウンロードしてリネーム
    //------------------------------
    foreach ($files as $index => $file) {
        $fileKey = $file['fileKey']; // ファイルキーを取得
        $recordId = $record['item']['_id']; // レコードIDも取得

        // ダウンロード用のAPI URLを作成
        $apiUrlPass = "/apps/" . APP_ID . "/dbs/" . DB_ID . "/" . $fileFieldId . "/" . $recordId . "/files/" . $fileKey . "/download";

        // APIを使ってファイルをダウンロード 
        $apiResponse = $commonBase->apiCurlAction("GET", $apiUrlPass, "", "", "not");
        $fileContent = $apiResponse;

        // 元のファイル名を取得
        $originalFileName = $file['fileName'];
        $fileExtension = '';
        if (strpos($originalFileName, '.') !== false) {
            $fileExtension = substr($originalFileName, strrpos($originalFileName, '.') + 1);
        }

        // 接頭語と接尾語を取得
        $prefix = isset($prefixes[$index]) ? $prefixes[$index] : '';
        $suffix = isset($suffixes[$index]) ? $suffixes[$index] : '';

        // 新しいファイル名を作成
        $newFileName = $prefix . $textValue . $suffix . "." . $fileExtension;

        //------------------------------
        // アップロード
        //------------------------------
        // アップロードトークン生成
        $uploadTokenResponse = $commonBase->apiCurlAction("POST", "/apps/" . APP_ID . "/dbs/" . DB_ID . "/" . $fileFieldId . "/files/uploadToken");
        if (isset($uploadTokenResponse['fileUploadToken'])) {
            $uploadToken = $uploadTokenResponse['fileUploadToken'];
            // アップロード用のリクエストボディを作成
            $requestBody = "--WebKitFormBoundary7MA4YWxkTrZu0gW\r\n";
            $requestBody .= "Content-Disposition: form-data; name=\"file\"; filename=\"" . $newFileName . "\"\r\n";
            $requestBody .= "Content-Type: text/plain\r\n\r\n";
            $requestBody .= $fileContent . "\r\n";  // 直接ファイル内容をアップロード
            $requestBody .= "--WebKitFormBoundary7MA4YWxkTrZu0gW\r\n";
            $requestBody .= "Content-Disposition: form-data; name=\"fileUploadToken\"\r\n\r\n";
            $requestBody .= $uploadToken . "\r\n";
            $requestBody .= "--WebKitFormBoundary7MA4YWxkTrZu0gW--";

            $contentType = "Content-Type: multipart/form-data; boundary=WebKitFormBoundary7MA4YWxkTrZu0gW";
            $apiResponse = $commonBase->apiCurlAction("POST", "/apps/". APP_ID. "/dbs/". DB_ID. "/". $fileFieldId. "/files", $requestBody, $contentType);

            // ファイルキーを配列に追加
            if (isset($apiResponse['fileKey'])) {
                $fileKeyArray[] = $apiResponse['fileKey'];
            }
        }
    }

    // レコードにファイルを紐づけ
    $updateData = [
        $fileFieldTitle => $fileKeyArray // fileFieldTitleを使用してファイルキーを配列にまとめる
    ];

    $apiResponse = $commonBase->apiCurlAction("PATCH", "/apps/". APP_ID. "/dbs/". DB_ID. "/records/". $recordId, $updateData);
}

//------------------------------
// 共通モジュール
//------------------------------
class CommonBase {
    /**
     * シングルトンインスタンス
     * @var UserManager
     */
    protected static $singleton;

    public function __construct() {
        if (self::$singleton) {
            throw new Exception('must be singleton');
        }
        self::$singleton = $this;
    }

    /**
     * シングルトンインスタンスを返す
     * @return UserManager
     */
    public static function getInstance() {
        if (!self::$singleton) {
            return new CommonBase();
        } else {
            return self::$singleton;
        }
    }

    /**
     * V2用 API送信ロジック
     * @return Result
     */
    function apiCurlAction($method, $addUrlPass, $data = null, $multiPart = null, $jsonDecode = null) {
        $header = array(
            "Authorization:Bearer " . API_KEY,
            "X-Spiral-Api-Version: 1.1",
        );
        if ($multiPart) {
            $header = array_merge($header, array($multiPart));
        } else {
            $header = array_merge($header, array("Content-Type:application/json"));
        }
        if (APP_ROLE) {
            $header = array_merge($header, array("X-Spiral-App-Role: " . APP_ROLE));
        }

        // curl
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_URL, API_URL . $addUrlPass);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        if ($method == "POST") {
            if ($multiPart) {
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            } else {
                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            }
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        }
        if ($method == "PATCH") {
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        }
        if ($method == "DELETE") {
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        }
        $response = curl_exec($curl);
        if (curl_errno($curl)) echo curl_error($curl);
        curl_close($curl);
        if ($jsonDecode) {
            return $response;
        } else {
            return json_decode($response, true);
        }
    }
}
?> 
                
上記を貼り付けたら設定値をお使いの環境に変更してください。

設定値に関して

共通で使用する値に関しては、定数として初めに設定します。
具体的には下記のような値を設定してください。
API_URL リクエスト先URLの固定部分です。固定値ですので特に変更する必要はありません。
API_KEY 発行したAPIキーを設定してださい。別途権限の付与が必要になります。
APP_ROLE アプリロールを指定する場合は記入、指定しない場合は空で大丈夫です。
APP_ID ファイルをアップしている当該DBが属しているアプリのIDを設定してください。
DB_ID ファイルをアップし、リネームしたい当該DBのIDを設定してください。
設定値
//------------------------------
// 設定値
//------------------------------
define("API_URL", "https://api.spiral-platform.com/v1");
define("API_KEY", "");
define("APP_ROLE", "");
define("APP_ID", "");
define("DB_ID", ""); 
            

$fieldMappingsについて
// 複数のファイルフィールドとテキストフィールドの組み合わせ
$fieldMappings = [
    [
        'fileFieldTitle' => 'file1', // リネームしたいファイルフィールドの識別名 
        'fileFieldId' => '2', // ファイルフィールドのIDを設定
        'textFieldTitle' => 'text1', // 自動発番されるフィールドの識別名
        'prefix' => ['接頭語1_', '接頭語2_'], // 接頭語
        'suffixes' => ['_接尾語1', '_接尾語2'] // 接尾語
    ],
    [
        'fileFieldTitle' => 'file2', 
        'fileFieldId' => '4', 
        'textFieldTitle' => 'text2',
        'prefix' => [], // 接頭語なし
        'suffixes' => [] // 接尾語なし
    ]
]; 
            

$fieldMappingsについてはファイルフィールドやテキストフィールドのIDや識別名を指定します。
複数のテキストフィールドとファイルフィールドの紐づけに対応していますので、紐づけたい箇所に合わせて指定を行ってください。
prefixとsuffixesはそれぞれ接頭語と接尾辞にあたります。
1フィールドに複数ファイルをアップ出来るようにした場合でファイル名を別にしたい時に利用します。
アップロードされた順とprefix,suffixesの順が紐づいて接頭語と接尾辞がついてリネームされるため、
順番はアップロード者に依存するのでご注意ください。

非同期アクション

上記PHPの設定が完了したらPHP実行アクションを有効化して非同期アクションの設定を完了させてください。
非同期アクションを登録トリガに設定した場合、登録時に自動でリネームされ、
更新トリガに場合、更新時にリネームされます。
仕様に合わせて任意のトリガに設定してください。

注意点

APIでのファイル登録を行う場合、1度に発行できるファイルキーは3つとなっております。(9/30時点)
アクセス数が多いサイトなどで、
複数の方が同時に実行された場合、ファイルキーの上限でエラーになってしまう可能性がございます。
ご利用の際は、事前に確認するようにしてください

解決しない場合はこちら コンテンツに関しての
要望はこちら