Skip to content

Latest commit

 

History

History
367 lines (302 loc) · 23.4 KB

02-process_ui_options.md

File metadata and controls

367 lines (302 loc) · 23.4 KB

Process UI options

The way a process is displayed and launched from the UI is configured in the process definition itself, under the ui key of its options (see the process definition).

YAML Configuration

clever_age_process:
    configurations:
        <process_code>:
            public: <true|false>
            entry_point: <task_code>
            options:
                ui:
                    source: <string>
                    target: <string>
                    ui_launch_mode: <modal|form|null>
                    form:
                        input:                          # <null|field spec>
                            type: <FQCN>                # form type, default: TextType
                            options: <array>            # form type options, default: []
                            default: <mixed>            # initial value, default: null
                        context:
                            <key>: <null|field spec>    # same keys as "input"
                        allow_extra_context: <bool>     # default: true
                        constraints: <array of constraints>
                    # Deprecated since 3.5, use "form" instead
                    entrypoint_type: <text|file>
                    default:
                        input: <mixed>
                        context:
                            - key: <string>
                              value: <string>
                    constraints: <array of constraints>
            tasks:
                # ...

Every key is optional: a process without options.ui is displayed and launched with a confirmation modal. Unknown keys, or invalid values, raise an options resolver error when the process list is displayed. The ui, notification and logs options are resolved separately: an invalid one does not break the others (e.g. an invalid ui option does not prevent the notification of the executions nor the purge of the logs). The form option (and its interaction with the deprecated options) is not resolved by the process list.

An optional cache warmer checks these options on cache:clear and cache:warmup, with a message naming the process: the ui (except form), notification and logs options of every process (the other keys of options are free, for other bundles or the application, and ignored); the structure of the launch form (form option, or the deprecated options of a process launched with the form mode): types, keys (e.g. a reserved execution_user context key), file fields, default values of the enum fields, constraints, conflicts with the deprecated options. The warmer does not run on the automatic rebuild of the container in debug mode, and cache:warmup --no-optional-warmers skips it (e.g. when the environment variables used by the process options are not available at build time).

The form itself is only built when the launch form of the process is displayed, since building it may depend on the runtime (a form type querying the database, the current user, the request): the options of the form types, the default values of the fields and the validators of the constraints are checked there.

The notification key, next to ui, configures the notification of the end of the process executions. The logs key, next to ui, configures the log retention of the process.

Options

Key Type Default Description
source string, null null Free label describing where the data comes from. Displayed in the process list and in the executions list.
target string, null null Free label describing where the data goes. Displayed in the process list and in the executions list.
ui_launch_mode string, null modal Behaviour of the "Launch" (rocket) action of the process list. See launch modes.
form array [] Fields, default values and constraints of the launch form (form launch mode only). See form fields.
entrypoint_type string text Deprecated since 3.5, use form.input.type. text or file: type of the input field of the launch form.
default array {input: null, context: []} Deprecated since 3.5, use form.input.default and form.context.<key>.default. See default values.
constraints array [] Deprecated since 3.5, use form.constraints. Constraints applied to the launch form. See constraints.
run mixed null Accepted for backward compatibility, not used.

Process visibility

Only public processes (public: true, the default of the process bundle) are displayed in the process list and can be launched from it (the launch URL of a private process answers 404), can be selected in the scheduler and can be launched through the HTTP API. Private processes are still recorded in the executions when they run (e.g. as sub-processes or from the console).

Launch modes

ui_launch_mode Behaviour of the "Launch" action
modal (default) Opens a confirmation modal, then queues the process without input nor context.
form Opens a form to set the process input and context, then queues the process.
~ (null) Queues the process immediately, without any confirmation.

Without form (modal and ~), the process is launched by a POST request with a CSRF token: a GET request to the launch URL is refused (405), as is a request without a valid token (403). The form mode relies on the CSRF protection of the form.

In every mode, the process is not executed by the web request: a message is dispatched to the execute_process Messenger transport and a worker runs it (see messenger). The UI adds the email of the connected user to the process context, under the execution_user key: this key is reserved, it cannot be set by the launch form (see free context pairs), declared in form.context or in default.context.

Launch form

The launch form (/process/launch?process=<process_code>) contains:

  • an input field, of the type declared by form.input (a text field by default). It is required (HTML attribute) if the process defines an entry_point, unless form.input.options.required says otherwise.
  • a context group: one field per key declared in form.context, followed (when form.allow_extra_context is true, the default) by a collection of free key/value pairs (both are required when a line is added). Each field or pair becomes a process context value, like -c key:value on the cleverage:process:execute console command.

The input can be of any type, but only a single uploaded file is saved: when the input is a FileType field, the uploaded file is saved to the cleverage_ui_process.upload_directory directory (see bundle configuration) with a random name keeping the original extension (its letters and digits only, at most 16), and its absolute path is passed as process input. The file is deleted once the process has been executed, unless cleverage_ui_process.delete_uploaded_files is false. When the input is a TextType field, a file path given as input is never deleted.

Form fields

form declares the fields of the launch form:

options:
    ui:
        ui_launch_mode: form
        form:
            input:
                type: Symfony\Component\Form\Extension\Core\Type\FileType
                options:
                    label: CSV file
                    constraints:
                        - NotNull: ~
                        - File:
                              # A CSV file is often detected as "text/plain" (semicolon delimiter, few lines): allow it explicitly
                              extensions:
                                  csv: ['text/csv', 'text/plain', 'application/csv', 'text/x-csv', 'text/x-comma-separated-values']
            context:
                delimiter:
                    type: Symfony\Component\Form\Extension\Core\Type\ChoiceType
                    default: ','
                    options:
                        label: Delimiter
                        choices: { 'Comma (,)': ',', 'Semicolon (;)': ';' }
                        required: true
                dry_run:
                    type: Symfony\Component\Form\Extension\Core\Type\CheckboxType
                    default: false   # not required by default: it can be left unchecked
                comment: ~        # a TextType field without default value
            allow_extra_context: true
            constraints: []
Key Type Default Description
form.input field spec, null null The input field. null: a TextType field (or the deprecated entrypoint_type).
form.context map of field specs [] The declared context fields, by context key, in their display order. null is a TextType field without default.
form.allow_extra_context bool true Whether free key/value pairs can be added to the context, for the keys that are not declared.
form.constraints array [] Constraints applied to the whole form data, see constraints.

Field spec

A field spec (form.input, form.context.<key>) accepts exactly three keys:

Key Type Default Description
type string TextType The FQCN of a Symfony form type (e.g. Symfony\Component\Form\Extension\Core\Type\ChoiceType).
options array [] The options of the form type (label, help, attr, choices, constraints...).
default mixed null The initial value of the field.

The context keys must be valid form field names (letters, digits, _, - and :, starting with a letter, a digit or _). A purely numeric key (e.g. 123, even quoted in YAML) is not supported: PHP casts it to an integer. The extra key (the free context pairs) and the execution_user key (the email of the connected user) are reserved.

type is the FQCN of a form type: a Symfony core type (Symfony\Component\Form\Extension\Core\Type\*), a type of a bridge (e.g. Symfony\Bridge\Doctrine\Form\Type\EntityType, if installed) or a type of your project. It must implement Symfony\Component\Form\FormTypeInterface and must not be a button type; the short names (text, choice...) are not supported. A form type with dependencies must be a service (tag form.type, autoconfigured by default). An option that the type does not define (e.g. choices on a TextType field), or an invalid option value, fails when the launch form is displayed (see YAML configuration).

Constraints of a field

options.constraints uses the same syntax as the constraints option: a list of constraint short names (or FQCN) with their options. A violation is displayed under the field.

The extensions option of the File constraint also checks the detected MIME type of the file. A CSV file is often detected as text/plain (semicolon delimiter, single column, few lines): list the accepted MIME types per extension (extensions: { csv: ['text/csv', 'text/plain'] }).

options.required is only the HTML required attribute: the server-side validation relies on options.constraints (e.g. NotBlank). The declared context fields are not required by default (unlike the Symfony default, a required CheckboxType must be checked, and a select that is not required has an empty choice): set options.required: true to mark one as required. The input is required when the process defines an entry_point (see launch form).

The data, mapped, property_path and inherit_data options are not supported (they break the mapping of the context and of the default values): use default for the initial value.

Default values of the fields

default is the initial value of the field, in the model format of its type:

  • a FileType field cannot have a default value;
  • for DateType, DateTimeType and TimeType, the YAML value is a string: set options.input: string (with the matching options.input_format), or keep a null default, otherwise the string cannot be transformed;
  • for ChoiceType, the default value is one of the choices values;
  • for EnumType, the default value is a case of the enum of options.class (a list of cases with options.multiple: true), given with the !php/enum YAML tag: default: !php/enum App\Enum\Status::Active. Any other value is refused when the launch form is resolved;
  • for DateIntervalType, the YAML value is a string: set options.input: string (an ISO 8601 duration such as P1D), or keep a null default.

File fields

A FileType field is only supported for the input, and for a single file (options.multiple: true is refused). A form type whose parent is FileType (through getParent()) is not detected as a file field.

Free context pairs

With allow_extra_context: true, the free key/value pairs are displayed after the declared fields, under a "Context (key/value)" label (no label when no context key is declared). With allow_extra_context: false, no free pair can be added.

A free pair whose key is a declared field is reported as a validation error on its key (The context key "delimiter" is a field of the launch form, use this field instead.), and the process is not launched. So is a free pair with the execution_user key (The context key "execution_user" is reserved: it is set to the email of the connected user.): it cannot replace the connected user.

Free pairs and placeholders. A free pair gives a value to any context key, so to any {{ key }} placeholder of the options of the process tasks, not only to the keys declared in form.context. As soon as a process declares its context fields in form.context, set allow_extra_context: false so that only these keys can be set from the UI (the default stays true, for backward compatibility).

The HTML names of the fields are launch[input], launch[context][<key>] for the declared fields and launch[context][extra][<index>][key|value] for the free pairs.

Context values

The values of the form are converted before being given to the process (after the validation, so that the constraints apply to the typed values):

Form data Process value
null, bool, int, float, string unchanged
array converted recursively, keys kept
backed enum its value
pure enum its name
DateTimeInterface formatted as DATE_ATOM (2026-01-02T03:04:05+01:00)
DateInterval an ISO 8601 duration with every part (P0Y0M1DT0H0M0S), - prefixed when inverted
file refused: file fields are only supported for the input
Stringable object its string
other object refused

A declared field left empty gives the null value (false for a CheckboxType). A value that cannot be converted is reported as an error under its field (under the free context pairs for a free pair), and the process is not launched.

Object data. The data of some form types is an object (e.g. the entity of an EntityType): the choice_value option only changes the HTML value of the options, not the data given to the process. Such an object must implement \Stringable: its string becomes the context value. Otherwise an error is displayed under the field ("cannot be used as a process context value") and the process is not launched. Prefer a ChoiceType field with scalar choices (e.g. the identifiers of the entities).

Default values

Deprecated since 3.5, use form.input.default and form.context.<key>.default (see migrating from the deprecated options).

default.input pre-fills the input field. It is ignored when entrypoint_type is file (a file field cannot be pre-filled).

default.context is a list of key/value pairs (both required) pre-filling the context collection. The user can change, remove or add pairs before launching. A pair whose key is declared in form.context pre-fills this field (if the field has no default); when a key appears several times, the last pair wins.

options:
    ui:
        ui_launch_mode: form
        entrypoint_type: text
        default:
            input: 'Steven King'
            context:
                - key: firstname
                  value: Steven
                - key: lastname
                  value: King

Constraints

The constraints option is deprecated since 3.5, use form.constraints, which has the same syntax.

form.constraints (or the deprecated constraints) uses the same syntax as the ValidatorTask of the process bundle (and as Symfony YAML validation mapping): a list of constraint short names (or FQCN) with their options. Constraints are applied to the whole form data, which is an array with two keys:

  • input: the data of the input field (e.g. a string, or the UploadedFile object of a FileType field),
  • context: the context as an associative array (key => value), the declared keys first, with their typed values.

A violation on a declared context key ([context][<key>]) is displayed under its field.

While a constraint is violated, the process is not launched and the form is displayed again with the violation messages.

options:
    ui:
        ui_launch_mode: form
        form:
            input:
                type: Symfony\Component\Form\Extension\Core\Type\FileType
            context:
                delimiter:
                    default: ','
            constraints:
                - Collection:
                      fields:
                          input:
                              - File:
                                    # A CSV file is often detected as "text/plain" (semicolon delimiter, few lines): allow it explicitly
                                    extensions:
                                        csv: ['text/csv', 'text/plain', 'application/csv', 'text/x-csv', 'text/x-comma-separated-values']
                          context:
                              - Collection:
                                    fields:
                                        delimiter:
                                            - Choice:
                                                  choices: [',', ';']
                                                  message: 'delimiter context must be , or ;. {{ value }} given.'

The constraints of a single field are simpler to declare in its options.constraints (see form fields).

Note that the Collection constraint rejects missing and extra fields by default: use allowExtraFields: true (or allowMissingFields: true) if users may add other context values.

See the form with file upload cookbook for a complete example.

Migrating from the deprecated options

Since 3.5, entrypoint_type, default and constraints are deprecated (a deprecation is triggered each time the launch form of the process is displayed, when the option is set, even to an empty value), and will be removed in 4.0:

Deprecated option Replacement
entrypoint_type form.input.type
default.input form.input.default
default.context form.context.<key>.default (or a free pair with form.allow_extra_context)
constraints form.constraints

Until then, the deprecated options are folded into form. Mixing a deprecated option and its replacement raises an InvalidOptionsException:

  • entrypoint_type with form.input;
  • constraints with form.constraints (even empty);
  • default.input with form.input.default;
  • a default.context pair with the default of the same declared key;
  • a default.context pair whose key is not declared, with form.allow_extra_context: false.

See the upgrade guide for an example.