プリザンターのサーバスクリプトのcontext.Conditionを見てみる

## はじめに
プリザンターの機能で1つである[サーバスクリプト](https://pleasanter.org/ja/manual/server-script)。この機能の中でユーザIDやサイトIDなどの環境にまつわる値を取得したり設定したりするモデルに`context`があります。この`context`には「サーバースクリプトの条件の名称」が格納されている`Condition`があります。
マニュアルには「サーバースクリプトの条件の名称」とだけ記載されていて実際に取り得る値が分からない状態です。今回は`Condition`の中身に何が入っているかを紹介します。

## 実装を見てみる
`context`の実装は`Implem.Pleasanter.Libraries.ServerScripts.ServerScriptModelContext`にあります。

https://github.com/Implem/Implem.Pleasanter/blob/24fb71aa12d54ce04dd1fbf2fc49b0862031904d/Implem.Pleasanter/Libraries/ServerScripts/ServerScriptModelContext.cs

`context.Condition`はここになります。

https://github.com/Implem/Implem.Pleasanter/blob/24fb71aa12d54ce04dd1fbf2fc49b0862031904d/Implem.Pleasanter/Libraries/ServerScripts/ServerScriptModelContext.cs#L52

このプロパティには`ServerScriptModelContext`のコンストラクタで値がセットされています。このコンストラクタ、どこで呼ばれているかと言われると`Implem.Pleasanter.Libraries.ServerScripts.ServerScriptModel`です。

https://github.com/Implem/Implem.Pleasanter/blob/24fb71aa12d54ce04dd1fbf2fc49b0862031904d/Implem.Pleasanter/Libraries/ServerScripts/ServerScriptModel.cs#L96-L136

```csharp
Context = new ServerScriptModelContext(
    context: context,
    logBuilder: context.LogBuilder,
    userData: context.UserData,
    responseCollection: context.ResponseCollection,
    messages: context.Messages,
    errorData: context.ErrorData,
    redirectData: context.RedirectData,
    formStringRaw: context.FormStringRaw,
    formString: context.FormString,
    ajax: context.Ajax,
    mobile: context.Mobile,
    applicationPath: context.ApplicationPath,
    absoluteUri: context.AbsoluteUri,
    absolutePath: context.AbsolutePath,
    url: context.Url,
    urlReferrer: context.UrlReferrer,
    controller: context.Controller,
    query: context.Query,
    action: context.Action,
    tenantId: context.TenantId,
    siteId: context.SiteId,
    id: context.Id,
    groupIds: context.Groups,
    tenantTitle: context.TenantTitle,
    siteTitle: context.SiteTitle,
    recordTitle: context.RecordTitle,
    deptId: context.DeptId,
    userId: context.UserId,
    loginId: context.LoginId,
    language: context.Language,
    timeZoneInfo: context.TimeZoneInfo?.ToString(),
    hasPrivilege: context.HasPrivilege,
    apiVersion: context.ApiVersion,
    apiRequestBody: context.ApiRequestBody,
    requestDataString: context.RequestDataString,
    contentType: context.ContentType,
    onTesting: onTesting,
    scriptDepth: context.ServerScriptDepth,
    controlId: context.Forms.ControlId(),
    condition: condition.ToString());//ここです
```

`condition`は`ToString()`で`string`に変換されています。`condition`は`ServerScriptModel`のコンストラクタに引数で与えられているものになります。

https://github.com/Implem/Implem.Pleasanter/blob/24fb71aa12d54ce04dd1fbf2fc49b0862031904d/Implem.Pleasanter/Libraries/ServerScripts/ServerScriptModel.cs#L59-L70

```csharp
public ServerScriptModel(
    Context context,
    SiteSettings ss,
    GridData gridData,
    IEnumerable<(string Name, object Value)> data,
    IEnumerable<(string Name, object Value)> saved,
    IEnumerable<(string Name, ServerScriptModelColumn Value)> columns,
    View view,
    ServerScriptConditions condition,//これです
    DateTime timeOut,
    bool debug,
    bool onTesting)
```

型は`ServerScriptConditions`です。ではこの`ServerScriptConditions`を見てみます。

https://github.com/Implem/Implem.Pleasanter/blob/24fb71aa12d54ce04dd1fbf2fc49b0862031904d/Implem.Pleasanter/Libraries/ServerScripts/ServerScriptModel.cs#L40-L57

```csharp
public enum ServerScriptConditions
{
    None,
    WhenViewProcessing,
    WhenloadingSiteSettings,
    BeforeOpeningPage,
    BeforeOpeningRow,
    WhenloadingRecord,
    BeforeFormula,
    AfterFormula,
    AfterUpdate,
    BeforeUpdate,
    AfterCreate,
    BeforeCreate,
    AfterDelete,
    BeforeDelete,
    BackgroundServerScript
}
```

お、列挙体ですね。ということは`ServerScriptModelContext`で行われている`ToString()`では、この列挙体の列挙子がそのまま返されていることになります。これをサーバスクリプトの条件と対比させると下記の表になります。

|Condition|条件|
|--|--|
|None||
|WhenViewProcessing|ビュー処理時|
|WhenloadingSiteSettings|サイト設定の読み込み時|
|BeforeOpeningPage|画面表示の前|
|BeforeOpeningRow|行表示の前|
|WhenloadingRecord|「レコード」読み込み時|
|BeforeFormula|計算式の前|
|AfterFormula|計算式の後|
|AfterUpdate|更新後|
|BeforeUpdate|更新前|
|AfterCreate|作成後|
|BeforeCreate|作成前|
|AfterDelete|削除後|
|BeforeDelete|削除前|
|BackgroundServerScript|バックグラウンドサーバスクリプト|

これで、`context.Condition`で取得出来る「サーバースクリプトの条件の名称」が判明しました。

## まとめ
サーバスクリプトがどこで実行されているかを判断するのに`context.Action`を使うのは一般的な手法です。どの条件で使用されたかをそれに加えて使えるようになると、かなり細かい実行条件制御が出来るようになります。ぜひ、`context.Condition`を活用してみてください。