開発情報・ナレッジ

投稿者: SPIRERS ナレッジ向上チーム 2022年3月31日 (木)

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

プログラムでレコード値を自動発番できる強化ガジェットの設定方法をこちらの記事で解説します。

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

変更・改定履歴

  • 改定

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

  • 改定

    ver.2.20アップデートに伴い注意事項を追記

仕様

・生成するユニーク値はDBで生成されたレコードIDをもとに、接頭文字、接尾文字を付加したものになります。
例)
  ID00001(接頭文字:ID、レコードID:00001、接尾文字:なし)
  A00001B(接頭文字:A、レコードID:00001、接尾文字:B)
  00001ID(接頭文字:なし、レコードID:00001、接尾文字:ID)

要件

・メールアドレスはユニークではなく重複可能な設定
・完了メールに自動発番した値を記載してユーザに通知

設定方法

1)登録データを格納するDBを作成
・自動発番値を格納する「自動発番」フィールドを追加してください
   タイプは「テキスト」必須制約/ユニーク制約どちらもありとして設定してください
・完了メールを送信するために「メールアドレス」フィールドを追加してください
   タイプは「メールアドレス」必須制約はありでユニーク制約はなしとして設定してください
※完了メールが不要な場合は、メールアドレスをDBに含める必要はありません
・完了メールをAPIで送信するために必要な「APIメール送信」フィールドを追加してください
   タイプは「テキスト」必須制約/ユニーク制約どちらもなしで追加してください

強化ガジェットで必要になるフィールドは上記のみです。
その他は案件に合わせて適宜フィールドを追加してください。

DBの基本的な作成方法はこちら を参考にしてください。
2)登録フォームブロックをビジュアル設定で作成
・登録フォームには「自動発番」と「メールアドレス」を含めてください
   「APIメール送信」に関してはフォームに含む必要はありません
・確認ページの「自動発番」を非表示に設定してください
※この設定を行わないと確認ページで自動発番フィールドが表示されてしまいますのでご注意ください
フォームブロックの基本的な作成方法はこちら を参考にしてください。
3)登録フォームのメールアクションで完了メールを設定
・完了メールをAPIで送信するために配信条件を設定してください
   「条件付き配信」を選択して、条件抽出(簡易)で「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エージェントの権限は自動発番先のDBがあるアプリやフォームがあるサイトの全権限を持たせる必要があります

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

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

// 変更不可
// 複数強化パーツがある場合、下記を変更不可箇所に追加
function onload_autonum() {
    const param = "_ifbs-" + autga_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", "", "@spiral-platform.co.jp", "0,1");
        if (autga_field_1) { value_set(autga_field_1, hiddenValue, autga_display_flg); }
        if (autga_field_2) { value_set(autga_field_2, hiddenValue, autga_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
// 設定値
// API設定
define("API_URL", "https://api.spiral-platform.com/v1");
define("API_KEY", ""); // APIキー

// 自動発番する値の設定
$AUTGA_PREFIX = ""; // 接頭文字
$AUTGA_SUFFIX = ""; // 接尾文字
$AUTGA_IDREG = ""; // ID何桁で0埋めするか

$AUTGA_DBID = ""; // DBID
$AUTGA_APPID = ""; // アプリID
$AUTGA_BLOCKSYM = ""; // 登録フォームブロックの識別名

$AUTGA_AUTSYM = ""; // 自動発番値を格納するフィールドの識別名
$AUTGA_AUTID = ""; // 自動発番値を格納するフィールドのID

$AUTGA_EMAILSYM = ""; // メールアドレスフィールドの識別名 ※メールアドレスがユニークではない場合は何もいれないでください
$AUTGA_TENTASYM = ""; // 仮メールアドレスフィールドの識別名 ※メールアドレスがユニークではない場合は何もいれないでください

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

// 変更不可
$commonBase = CommonBase::getInstance();
$apiPath = "/apps/". $AUTGA_APPID;

$param = "f0". $AUTGA_AUTID;
$paramVal = $SPIRAL->getParam($param);

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

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

    $q_where = "&where=@". $AUTGA_AUTSYM. "='". $paramVal. "'";
    $query = "?limit=1". $q_where;
    // 更新するレコードを取得
    $se_result = $commonBase->apiCurlAction("GET", $apiPath. "/dbs/". $AUTGA_DBID. "/records". $query);
    if (array_key_exists('status', $se_result)){
        if ($se_result["status"] != 200){
            $SPIRAL->setTHValue("APIERRORFLAG", $se_result);
            return;
        }
    }

    $record_id = $se_result["items"][0]["_id"];
    $new_id = str_pad($record_id, $AUTGA_IDREG, 0, STR_PAD_LEFT);
    $new_id = $AUTGA_PREFIX. $new_id. $AUTGA_SUFFIX;
    $updata = array( $AUTGA_AUTSYM => $new_id );
    if ($AUTGA_EMAILSYM !== "" && $AUTGA_TENTASYM !== "") {
        $updata[$AUTGA_EMAILSYM] = $se_result["items"][0][$AUTGA_TENTASYM];
        $updata[$AUTGA_TENTASYM] = null;
    }
    if ($AUTGA_APIMAILSYM !== "" && $AUTGA_MAILFLG === "1") {
        $updata[$AUTGA_APIMAILSYM] = "APIメール送信可能";
    }
    // レコードを更新
    $up_result = $commonBase->apiCurlAction("PATCH", $apiPath. "/dbs/". $AUTGA_DBID. "/records/". $record_id, $updata);
    if (array_key_exists('status', $up_result)){
        if ($up_result["status"] != 200){
            $SPIRAL->setTHValue("APIERRORFLAG", "error");
            return;
        }
    }
    // フラグが立っていれば、メールアクションを実行
    if ($AUTGA_MAILFLG === "1") {
        $data = array("recordId" => $record_id);
        $ac_result = $commonBase->apiCurlAction("POST", $apiPath. "/actions/". $AUTGA_ACTIONID. "/run", $data);
    }
}
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) {
        $header = array(
            "Authorization:Bearer ". API_KEY,
            "Content-Type:application/json",
            "X-Spiral-App-Authority:"."manage",
            "X-Spiral-App-Role:"."_fullAccess",
            "X-Spiral-Api-Version: 1.1",
        );
        // 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") {
            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_CUSTOMREQUEST, $method);
        }
        $response = curl_exec($curl);
        if (curl_errno($curl)) echo curl_error($curl);
        curl_close($curl);
        return json_decode($response , true);
    }
    /**
	 * エスケープ用
	 * @param type $str
	 * @return type
	 */
	public static function e($str) {
		if ($str != '') {
			return htmlspecialchars($str);
		} else {
			return '';
		}
	}
}
?>
・先ほど貼り付けたJavascript内の設定値部分にそれぞれ値を入れてください
autga_field_1 自動発番フィールドのフィールドIDを "" の中に入力してください。
autga_field_2 今回はメールアドレスがユニークではないので、未入力のままにしてください。
autga_display_flg 今回はフォームをビジュアル設定で作成したと思いますので "1" のままで大丈夫です。
ソース設定に切り替える場合は "0" に変更してください。
autga_block_sym (2)で作成した登録フォームブロックの識別名 "" の中に入力してください。
それぞれの入力例
※値は全てサンプルですので、それぞれの環境に合わせて値の入力を行ってください
※ソース内で「変更不可」と記載がある箇所以降は変更しないように注意してください
ver.2.20アップデート よりソース設定のフォームではname値がフィールド識別名となります
この強化ガジェットを使用する場合は設定値を変更する必要がありますので、ご注意ください
// 設定値
const autga_field_1 = "15"; // 自動発番するフィールドのID
const autga_field_2 = ""; // メールアドレスフィールドのID ※メールアドレスがユニークではない場合は何もいれないでください
const autga_display_flg = "1"; // ビジュアル設定の場合は1 ソース設定の場合はデザインが崩れる場合があるので0
const autga_block_sym = "newInsertForm"; // 登録フォームブロックの識別名
それぞれフィールドの識別名とIDは赤枠部分に記載されております。
・先ほど貼り付けたPHP内の設定値部分にそれぞれ値を入れてください
API_URL APIのURLを指定しています。
固定値ですので、元から入っている値そのままで大丈夫です。
API_KEY (5)で発行したAPIキーを "" の中に入力してください。
$AUTGA_PREFIX 自動発番する値の接頭文字を "" の中に入力してください。
$AUTGA_SUFFIX 自動発番する値の接尾文字を "" の中に入力してください。
$AUTGA_IDREG レコードIDを何桁で0埋めするかの数字を "" の中に入力してください。
$AUTGA_DBID (1)で作成したDBのIDを "" の中に入力してください。
$AUTGA_APPID (1)のDBを作成したアプリのIDを "" の中に入力してください。
$AUTGA_BLOCKSYM (2)で作成した登録フォームブロックの識別名を "" の中に入力してください。
$AUTGA_AUTSYM 自動発番フィールドのフィールドの識別名を "" の中に入力してください。
$AUTGA_AUTID 自動発番フィールドのフィールドのIDを "" の中に入力してください。
$AUTGA_EMAILSYM 今回はメールアドレスがユニークではないので、未入力のままにしてください。
$AUTGA_TENTASYM 今回はメールアドレスがユニークではないので、未入力のままにしてください。
$AUTGA_MAILFLG 今回はAPIで完了メールを送信するため "1" のままで大丈夫です。
$AUTGA_APIMAILSYM APIメール送信フィールドのフィールドの識別名を "" の中に入力してください。
$AUTGA_ACTIONID (3)で作成したメールアクションのIDを "" の中に入力してください。
それぞれの入力例
※値は全てサンプルですので、それぞれの環境に合わせて値の入力を行ってください
※ソース内で「変更不可」と記載がある箇所以降は変更しないように注意してください
// 設定値
// API設定
define("API_URL", "https://api.spiral-platform.com/v1");
define("API_KEY", "AB12CDe3fGHIJKL45MNoPQRSTUVwXyz6"); // APIキー

// 自動発番する値の設定
$AUTGA_PREFIX = "ID"; // 接頭文字
$AUTGA_SUFFIX = ""; // 接尾文字
$AUTGA_IDREG = "10"; // ID何桁で0埋めするか

$AUTGA_DBID = "11111"; // DBID
$AUTGA_APPID = "22222"; // アプリID
$AUTGA_BLOCKSYM = "newInsertForm"; // 登録フォームブロックの識別名

$AUTGA_AUTSYM = "id_field"; // 自動発番値を格納するフィールドの識別名
$AUTGA_AUTID = "15"; // 自動発番値を格納するフィールドのID

$AUTGA_EMAILSYM = ""; // メールアドレスフィールドの識別名 ※メールアドレスがユニークではない場合は何もいれないでください
$AUTGA_TENTASYM = ""; // 仮メールアドレスフィールドの識別名 ※メールアドレスがユニークではない場合は何もいれないでください

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

最後に

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

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