レコードの移動を API・サーバースクリプトから行う
本体の標準機能ではありません
このページは本体を改修する場合の設計メモです。1.5.8.1 では、レコードの移動は画面(編集画面の「移動」、一覧の一括移動)からしか行えません。Web API、スクリプトの $p.api*、サーバースクリプトの items.* には移動の手段がありません。
前提にした現行の実装(1.5.8.1)
ソースへのリンクは Implem/Implem.Pleasanter の 1.5.8.1(コミット fdcbb3f8)固定です。
画面の移動
| 項目 | 内容 |
|---|---|
| 対象 | 期限付きテーブル・記録テーブルのレコード。Wiki は対象外(ItemModel.Move() の既定分岐で NotFound。ItemModel.cs#L2559-L2579) |
| 操作 | 編集画面の単体移動(/items/{id}/Move)と、一覧の一括移動(/items/{id}/BulkMove)(ItemsController.cs#L922-L980) |
| 移動先 | サイト設定の MoveTargets(移動先サイト ID の一覧)から画面で選び、フォームの MoveTargets として送る |
| 権限 | 移動元と移動先の両方に更新権限が要る(Permissions.CanMove。Permissions.cs#L587-L591) |
ResultUtilities.Move() の流れは次のとおりです(ResultUtilities.cs#L5549-L5600)。
図を読み込み中…
OnMoving() が確かめるのは、テーブルのロック・レコードのロック・CanMove の 3 つです(ResultValidators.cs)。サーバー側では、移動先がそのサイトの MoveTargets に入っているかは確かめていません。MoveTargets の制限は、画面の選択肢で掛かっているだけです。
追加する箇所
既存の Delete の API 版(DeleteByApi)とサーバースクリプト版(items.Delete)に倣います。単体移動を先に作り、一括移動は後回しにします(一括移動は一覧の選択状態からレコードを特定する処理が要るため)。
| ファイル | 追加するもの |
|---|---|
Libraries/Requests/Api.cs | 移動先サイト ID を受け取る MoveTargetId(手書きのクラスなので CodeDefiner の生成対象外) |
Controllers/Api/ItemsController.cs | [HttpPost("{id}/Move")] のアクション |
Models/Items/ItemModel.cs | MoveByApi()・MoveByServerScript()(Issues・Results に振り分け、それ以外は NotFound / false) |
Models/Issues/IssueUtilities.cs、Models/Results/ResultUtilities.cs | MoveByApi()・MoveByServerScript() |
Libraries/ServerScripts/ServerScriptUtilities.cs | Move(context, id, destinationSiteId)(CreateContext でアクション Move の Context を作る) |
Libraries/ServerScripts/ServerScriptModelApiItems.cs | items.Move(id, destinationSiteId)(OnTesting のときは false) |
Implem.PleasanterFrontend/.../_api.js | $p.apiMove($p.apiExec($p.apiUrl(args.id, 'move'), args)) |
MoveByApi の処理
ResultUtilities.Move() のうち、フォームから読んでいる移動先を Api.MoveTargetId に置き換え、応答を ApiResults にします。
Mime.ValidateOnApi()で Content-Type を確かめる- リクエストを
Apiとして読み、MoveTargetIdが 0 ならInvalidJsonData - 移動先の件数上限(
ItemsLimit) - レコードを読み、
AccessStatusがSelectedでなければ NotFound OnMoving()で検証ResultModel.Move()を実行し、成功ならApiResults.Success(メッセージはDisplays.Moved)
json
{
"ApiVersion": 1.1,
"ApiKey": "your-api-key",
"MoveTargetId": 67890
}javascript
if (!items.Move(12345, 67890)) {
context.Log('移動に失敗しました');
}決めておくこと
- 移動先の制限: 画面と同じく
MoveTargetsに入っているサイトだけを許すか、更新権限さえあればどこにでも移せるようにするか。現行のサーバー側処理はMoveTargetsを見ていないので、API でも制限したいなら検証を足す必要があります。 - API 用の検証:
OnDeleting()はapi: trueのときにValidators.ValidateApi()を呼びますが(ResultValidators.cs#L792-L806)、OnMoving()にはこの引数がありません。OnMoving()にapi引数を足して同じ検証を通すのが揃った形です。 - サーバースクリプトの再帰:
items.Moveの中でも移動元・移動先のサーバースクリプトが動く可能性があるので、既存のitems.Updateと同じくCreateContext()で作った Context に乗せ、ServerScriptDepthによる深さの制限(10 段未満。ServerScriptUtilities.cs#L1189)を効かせます。