開発情報・ナレッジ

投稿者:SPIRERS ナレッジ向上チーム 2022年1月18日 (火)

ver.2でレコード値を自動発番できる強化ガジェット

現状、SPIRAL ver.2では新規登録フォームでデータを登録した際、登録番号などのユニークIDを自動生成できません。
そこで、プログラムなどを使って自動発番を実現する方法を考えました。設定方法を説明していきます。

※本記事は暫定的なご案内です。SPIRAL ver.2の今後のバージョンアップに伴い、正式機能がリリースされた場合、
   この記事は削除される可能性があります。
※記事内のサンプルコードの不具合やもっとこうした方が良いなどの改善点がございましたら、
   リクエストボードにお寄せください。

変更・改定履歴

  • 改定

    コメントアウトの文章を修正

仕様

・生成するユニーク値はDBで生成されたレコードIDをもとに、接頭文字、接尾文字を付加したものになります。
例)
  ID00001(接頭文字:ID、レコードID:00001、接尾文字:なし)
  A00001B(接頭文字:A、レコードID:00001、接尾文字:B)
  00001ID(接頭文字:なし、レコードID:00001、接尾文字:ID)
・自動発番した値以外にメールアドレスフィールド1つのみをユニークとして設定できます。

要件

・メールアドレスはユニークとして設定
・完了メールに自動発番した値を記載してユーザに通知

設定方法

1)登録データを格納するDBを作成
・自動発番値を格納するフィールドのタイプは「テキスト」として設定してください
・フォームから一時的にメールアドレスを格納する「仮メールアドレス」フィールドを追加してください
・完了メールをAPIで送信するために「APIメール送信」フィールドをタイプはテキストで追加してください

DBの作成方法の詳細はこちら を参考にしてください。
2)登録フォームブロックをビジュアル設定で作成
・登録フォームに「自動発番」と「メールアドレス」を含めてください、逆に「APIメール送信」は含めないでください
・「仮メールアドレス」をメールアドレス入力欄として設定してください
その際、入力必須は"あり"に設定して、ラベルは「メールアドレス」としてください
・確認ページの「自動発番」と「メールアドレス」を非表示に設定してください
フォームブロックの作成方法の詳細はこちら を参考にしてください。
3)登録フォームのメールアクションで完了メールを設定
・配信条件は「条件付き配信」を選択して、条件抽出(簡易)で「APIメール送信」「値あり」に設定してください

フォームのメールアクション設定方法の詳細はこちら を参考にしてください。
4)フリーコンテンツブロックをソース設定で作成
・下記のテキストを貼り付けてください
<div style="display:none">
    <div th:if="${cp.result.isSuccess}">
        <div id="errorFlag" th:text="${cp.result.value['APIERRORFLAG']}"></div>
    </div>
    <div th:if="${!cp.result.isSuccess}">
        <div id="errorFlag">error</div>
    </div>
</div>
フリーコンテンツブロックの作成方法の詳細はこちら を参考にしてください。
5)APIエージェントの作成
・アカウント上でAPIエージェントの作成をされていない場合は、APIエージェントを作成してAPIキーを発行してください。

APIエージェントの作成方法の詳細はこちら を参考にしてください。
6)3、4で作成したブロックを設置するページを作成
・3、4で作成したブロックをページに設置してください
・ページの「Javascript」タブに下記ソースを貼り付けてください
// 設定値
const FIELD_ID1 = ""; // 自動発番するフィールドのID
const FIELD_ID2 = ""; // メールアドレスフィールドのID
const DISPLAY_FLG = "1"; // ビジュアル設定の場合は1 ソース設定の場合はデザインが崩れる場合があるので0
const BLOCK_SYM = ""; // 登録フォームブロックの識別名

// 原則変更不可
// 複数強化パーツがある場合、変更あり
window.onload = function () {
    onload_autonum();
};

// 変更不可
// 複数強化パーツがある場合、下記を変更不可箇所に追加
function onload_autonum() {
    const param = "_ifbs-" + BLOCK_SYM;
    const url = new URL(window.location.href);
    const paramVal =  url.searchParams.get(param);
    const errorMsg = "登録の際にエラーが発生しました。<br>お手数おかけしますがもう一度お試しください。";
    const textAln = "center";
    const brNum = 4;

    if ( paramVal === "s1_Step1" ) {
        const hiddenValue = id_create("20", "", "@pi-pe.co.jp", "0,1");
        if (FIELD_ID1) { value_set(FIELD_ID1, hiddenValue, DISPLAY_FLG); }
        if (FIELD_ID2) { value_set(FIELD_ID2, hiddenValue, DISPLAY_FLG); }
    } else if ( paramVal === "completion" ) {
        const errorElement = document.querySelector("div#errorFlag");
        const errorFlag = errorElement.textContent;
        if (errorFlag !== "ok") {
            add_child_element(errorMsg, textAln);
            for (let i = 0; i < brNum; i++) { add_child_element("<br>", textAln); }
        }
    }
}
function id_create(idLength, prefix, suffix, idType) {
    var str = ["0123456789", "abcdefghijklmnopqrstuvwxyz"];
    var typspl = idType.split(',');
    var c = "";
    for (var j = 0; j < typspl.length; j++) {
        c += str[typspl[j]];
    }
    var cl = c.length;
    var r = "";
    for (var i = 0; i < idLength; i++) {
        r += c[Math.floor(Math.random() * cl)];
    }
    r = prefix + r + suffix;
    return r;
}
function value_set(fieldId, inpVal, dispFlg) {
    const fieldName = "f0" + fieldId;
    let name = document.getElementsByName(fieldName);
    if (name[0]) {
        name[0].value = inpVal;
        if (dispFlg === "1") { name[0].parentNode.parentNode.style.display ="none"; }
    }
    const fieldReen = fieldName + ":reenter";
    name = document.getElementsByName(fieldReen);
    if (name[0]) {
        name[0].value = inpVal;
    }
}
function add_child_element(text_str, text_align) {
    var parent = document.querySelector("div.sp-form-item.sp-form-html");
    var child = document.createElement("p");
    child.innerHTML = text_str;
    child.style.textAlign = text_align;
    child.style.color = '#ff0000';
    child = parent.appendChild(child);
}
・ページの「PHP」タブに下記ソースを貼り付けてください
<?php
// 設定値
// 自動発番する値の設定
$PREFIX = "ID"; // 接頭文字
$SUFFIX = ""; // 接尾文字
$IDREG = "10"; // ID何桁で0埋めするか

// API設定
$APIKEY = ""; // APIキー
$DBID = ""; // DBID
$BLOCKSYM = ""; // 登録フォームブロックの識別名

$AUTID = ""; // 自動発番値を格納するフィールドの識別名
$EMAIL = ""; // メールアドレスフィールドの識別名
$EMAILID = ""; // メールアドレスフィールドのID
$TENTA = ""; // 仮メールアドレスフィールドの識別名

// APIメール送信設定
$MAILFLG = "0"; // 発番した値を含む完了メールを配信したい場合1 配信しない場合0
$APIMAIL = ""; // APIメール送信フィールドの識別名
$APPID = ""; // アプリID
$ACTIONID = ""; // メールアクションID

// 変更不可
$param = "f0". $EMAILID;
$paramVal = $SPIRAL->getParam($param);

$registForm = $SPIRAL->getRegistrationForm($BLOCKSYM);
$completFlg = $registForm->isCompletedStep();

$base_url = "https://api.spiral-platform.com/v1/";
$header = array(
    "Authorization:Bearer ".$APIKEY,
    "Content-Type:application/json",
    "X-Spiral-App-Authority:"."manage",
);

if ($completFlg) {
    $api_result = array();
    $SPIRAL->setTHValue("APIERRORFLAG", "ok");

    $q_where = "&where=@". $AUTID. "='". $paramVal. "'";
    $query = "?limit=1". $q_where;
    $se_result = selectRecords($base_url, $DBID, $header, $query);
    if (array_key_exists('status', $se_result)){
        if ($se_result["status"] != 200){
            $SPIRAL->setTHValue("APIERRORFLAG", "error");
            return;
        }
    }

    $record_id = $se_result["items"][0]["_id"];
    $new_id = str_pad($record_id, $IDREG, 0, STR_PAD_LEFT);
    $new_id = $PREFIX. $new_id. $SUFFIX;
    $updata = array( $AUTID => $new_id );
    if ($EMAIL !== "" && $TENTA !== "") {
        $updata[$EMAIL] = $se_result["items"][0][$TENTA];
        $updata[$TENTA] = null;
    }
    if ($APIMAIL !== "" && $MAILFLG === "1") {
        $updata[$APIMAIL] = "APIメール送信可能";
    }
    $up_result = updateRecords($base_url, $DBID, $header, $updata, $record_id);
    if (array_key_exists('status', $up_result)){
        if ($up_result["status"] != 200){
            $SPIRAL->setTHValue("APIERRORFLAG", "error");
            return;
        }
    }

    if ($MAILFLG === "1") {
        $data = array("recordId" => $record_id);
        $ac_result = runAction($base_url, $APPID, $header, $data, $ACTIONID);
    }
}

function selectRecords($base_url, $DBID, $header, $query) {
    $url = $base_url."dbs/". $DBID. "/records". $query;
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_URL , $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER , $header);
    $response = curl_exec($curl);
    if (curl_errno($curl)) echo curl_error($curl);
    curl_close($curl);
    $result = json_decode($response , true);
    return $result;
}
function updateRecords($base_url, $DBID, $header, $data, $record_id) {
    $url = $base_url."dbs/". $DBID. "/records/". $record_id;
    $json_body = json_encode($data);
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_URL , $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER , $header);
    curl_setopt($curl, CURLOPT_POSTFIELDS , $json_body);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST , 'PATCH');
    $response = curl_exec($curl);
    if (curl_errno($curl)) echo curl_error($curl);
    curl_close($curl);
    $result = json_decode($response , true);
    return $result;
}
function runAction($base_url, $APPID, $header, $data, $ACTIONID) {
    $url = $base_url."apps/". $APPID. "/actions/". $ACTIONID. "/run";
    $json_body = json_encode($data);
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_URL , $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER , $header);
    curl_setopt($curl, CURLOPT_POSTFIELDS , $json_body);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST , 'POST');
    $response = curl_exec($curl);
    if (curl_errno($curl)) echo curl_error($curl);
    curl_close($curl);
    $result = json_decode($response , true);
    return $result;
}
?>
・先ほど貼り付けたJavascript内の下記変数設定部分にそれぞれ値を入れてください
※ソース内で「以下は変更しないでください」と記載がある箇所以降は変更しないように注意してください
// 設定値
const FIELD_ID1 = ""; // 自動発番するフィールドのID
const FIELD_ID2 = ""; // メールアドレスフィールドのID
const DISPLAY_FLG = "1"; // ビジュアル設定の場合は1 ソース設定の場合はデザインが崩れる場合があるので0
const BLOCK_SYM = ""; // 登録フォームブロックの識別名
それぞれフィールドの識別名とIDは赤枠部分に記載されております。
・先ほど貼り付けたPHP内の下記変数設定部分にそれぞれ値を入れてください
※ソース内で「以下は変更しないでください」と記載がある箇所以降は変更しないように注意してください
// 設定値
// 自動発番する値の設定
$PREFIX = "ID"; // 接頭文字
$SUFFIX = ""; // 接尾文字
$IDREG = "10"; // ID何桁で0埋めするか

// API設定
$APIKEY = ""; // APIキー
$DBID = ""; // DBID
$BLOCKSYM = ""; // 登録フォームブロックの識別名

$AUTID = ""; // 自動発番値を格納するフィールドの識別名
$EMAIL = ""; // メールアドレスフィールドの識別名
$EMAILID = ""; // メールアドレスフィールドのID
$TENTA = ""; // 仮メールアドレスフィールドの識別名

// APIメール送信設定
$MAILFLG = "0"; // 発番した値を含む完了メールを配信したい場合1 配信しない場合0
$APIMAIL = ""; // APIメール送信フィールドの識別名
$APPID = ""; // アプリID
$ACTIONID = ""; // メールアクションID
以上で自動発番をするための設定は完了です!

最後に

設定完了後は正しく動作するかのテストを必ず行ってください。
また冒頭にも記載しておりますが、暫定的な方法となりますので少々回りくどい実装になっていることはご容赦いただけますと幸いです。

記事に載せているサンプルコードは下記にZipでまとめて添付しております。
解決しない場合はこちら コンテンツに関しての
要望はこちら