workflow::action::edit (public)

 workflow::action::edit [ -operation operation ] \
    [ -action_id action_id ] [ -workflow_id workflow_id ] \
    [ -array array ] [ -internal ] [ -no_complain ] \
    [ -handlers handlers ]

Defined in packages/workflow/tcl/action-procs.tcl

Edit an action. Attributes of the array:

  • short_name
  • pretty_name
  • pretty_past_tense
  • edit_fields
  • description
  • description_mime_type
  • sort_order
  • always_enabled_p
  • assigned_role
  • timeout_seconds
  • trigger_type
  • parent_action
  • parent_action_id
  • privileges
  • allowed_roles
  • callbacks
  • child_actions
Deprecated but still supported:
  • initial_action_p

Switches:
-operation (optional, defaults to "update")
insert, update, delete
-action_id (optional)
For update/delete: The action to update or delete. For insert: Optionally specify a pre-generated action_id for the action.
-workflow_id (optional)
For update/delete: Optionally specify the workflow_id. If not specified, we will execute a query to find it. For insert: The workflow_id of the new action.
-array (optional)
For insert/update: Name of an array in the caller's namespace with attributes to insert/update.
-internal (optional, boolean)
Set this flag if you're calling this proc from within the corresponding proc for a particular workflow model. Will cause this proc to not flush the cache or call workflow::definition_changed_handler, which the caller must then do.
-no_complain (optional, boolean)
Silently ignore extra attributes that we don't know how to handle.
-handlers (optional, defaults to " roles "workflow::role" actions "workflow::action" ")
Returns:
action_id
Author:
Lars Pind <lars@collaboraid.biz>
See Also:

Partial Call Graph (max 5 caller/called nodes):
%3 workflow::action::delete workflow::action::delete (public) workflow::action::edit workflow::action::edit workflow::action::delete->workflow::action::edit workflow::action::fsm::edit workflow::action::fsm::edit (public) workflow::action::fsm::edit->workflow::action::edit workflow::action::new workflow::action::new (public) workflow::action::new->workflow::action::edit db_boolean db_boolean (public) workflow::action::edit->db_boolean db_dml db_dml (public) workflow::action::edit->db_dml db_map db_map (public) workflow::action::edit->db_map db_nextval db_nextval (public) workflow::action::edit->db_nextval db_transaction db_transaction (public) workflow::action::edit->db_transaction

Testcases:
No testcase defined.
Source code:
    switch $operation {
        update - delete {
            if { $action_id eq "" } {
                error "You must specify the action_id of the action to $operation."
            }
        }
        insert {}
        default {
            error "Illegal operation '$operation'"
        }
    }
    switch $operation {
        insert - update {
            upvar 1 $array row
            if { ![array exists row] } {
                error "Array $array does not exist or is not an array"
            }
            foreach name [array names row] {
                set missing_elm($name) 1
            }
        }
    }
    switch $operation {
        insert {
            if { $workflow_id eq "" } {
                error "You must supply workflow_id"
            }
            # Default sort_order
            if { (![info exists row(sort_order)] || $row(sort_order) eq "") } {
                set row(sort_order) [workflow::default_sort_order  -workflow_id $workflow_id  -table_name "workflow_actions"]
            }
            # Default short_name on insert
            if { ![info exists row(short_name)] } {
                set row(short_name) {}
            }
        }
        update - delete {
            if { $workflow_id eq "" } {
                set workflow_id [workflow::action::get_element  -action_id $action_id  -element workflow_id]
            }
        }
    }

    # Parse column values
    switch $operation {
        insert - update {
            # Special-case: array entry parent_action (takes short_name) and parent_action_id (takes action_id) --
            # DB column is parent_action_id (takes action_id_id)
            if { [info exists row(parent_action)] } {
                if { [info exists row(parent_action_id)] } {
                    error "You cannot supply both parent_action ($row(parent_action)) (takes short_name) and parent_action_id ($row(parent_action_id)) (takes action_id)"
                }
                if { $row(parent_action) ne "" } {
                    set row(parent_action_id) [workflow::action::get_id  -workflow_id $workflow_id  -short_name $row(parent_action)]
                }
                unset row(parent_action)
                unset missing_elm(parent_action)
            }

            # Record if this is an initial action (deprecated)
            if { [info exists row(initial_action_p)] } {
                if { [info exists row(trigger_type)] && $row(trigger_type) ne "user" } {
                    error "You can't specify both initial_action_p (which is deprecated) and trigger_type (which has replaced it) at the same time. Stick to trigger_type."
                }
                if { [string is true -strict $row(initial_action_p)] } {
                    set row(trigger_type) "init"
                }
                unset row(initial_action_p)
                unset missing_elm(initial_action_p)
            }

            set update_clauses [list]
            set insert_names [list]
            set insert_values [list]
            # Handle columns in the workflow_actions table
            foreach attr {
                short_name
                pretty_name
                pretty_past_tense
                edit_fields
                description
                description_mime_type
                sort_order
                always_enabled_p
                assigned_role
                timeout_seconds
                trigger_type
                parent_action_id
            } {
                if { [info exists row($attr)] } {
                    set varname attr_$attr
                    # Convert the Tcl value to something we can use in the query
                    switch $attr {
                        short_name {
                            if { (![info exists row(pretty_name)] || $row(pretty_name) eq "") } {
                                if { $row(short_name) eq "" } {
                                    error "You cannot edit with an empty short_name without also setting pretty_name"
                                } else {
                                    set row(pretty_name) {}
                                }
                            }

                            set $varname [workflow::action::generate_short_name  -workflow_id $workflow_id  -pretty_name $row(pretty_name)  -short_name $row(short_name)  -action_id $action_id]
                        }
                        always_enabled_p {
                            set $varname [db_boolean [string is true -strict $row($attr)]]
                        }
                        assigned_role {
                            if { $row($attr) eq "" } {
                                set $varname ""
                            } else {
                                # Get role_id by short_name
                                set $varname [workflow::role::get_id  -workflow_id $workflow_id  -short_name $row($attr)]
                            }
                        }
                        default {
                            set $varname $row($attr)
                        }
                    }
                    # Add the column to the insert/update statement
                    switch $attr {
                        timeout_seconds {
                            lappend update_clauses "[db_map update_timeout_seconds_name] = [db_map update_timeout_seconds_value]"
                            lappend insert_names [db_map update_timeout_seconds_name]
                            lappend insert_values [db_map update_timeout_seconds_value]
                        }
                        default {
                            lappend update_clauses "$attr = :$varname"
                            lappend insert_names $attr
                            lappend insert_values :$varname
                        }
                    }
                    if { [info exists missing_elm($attr)] } {
                        unset missing_elm($attr)
                    }
                }
            }
        }
    }

    db_transaction {
        # Sort_order
        switch $operation {
            insert - update {
                if { [info exists row(sort_order)] } {
                    workflow::action::update_sort_order  -workflow_id $workflow_id  -sort_order $row(sort_order)
                }
            }
        }
        # Do the insert/update/delete
        switch $operation {
            insert {
                if { $action_id eq "" } {
                    set action_id [db_nextval "workflow_actions_seq"]
                }

                lappend insert_names action_id
                lappend insert_values :action_id
                lappend insert_names workflow_id
                lappend insert_values :workflow_id

                db_dml insert_action "
                    insert into workflow_actions
                    ([join $insert_names ""])
                    values
                    ([join $insert_values ""])
                "
            }
            update {
                if { [llength $update_clauses] > 0 } {
                    db_dml update_action "
                        update workflow_actions
                        set    [join $update_clauses ""]
                        where  action_id = :action_id
                    "
                }
            }
            delete {
                db_dml delete_action {
                    delete from workflow_actions
                    where action_id = :action_id
                }
            }
        }

        # Auxiliary rows
        switch $operation {
            insert - update {
                # Record which roles are allowed to take action
                if { [info exists row(allowed_roles)] } {
                    db_dml delete_allowed_roles {
                        delete from workflow_action_allowed_roles
                        where  action_id = :action_id
                    }
                    foreach allowed_role $row(allowed_roles) {
                        db_dml insert_allowed_role {}
                    }
                    unset missing_elm(allowed_roles)
                }

                # Record which privileges enable the action
                if { [info exists row(privileges)] } {
                    db_dml delete_privileges {
                        delete from workflow_action_privileges
                        where  action_id = :action_id
                    }
                    foreach privilege $row(privileges) {
                        db_dml insert_privilege {}
                    }
                    unset missing_elm(privileges)
                }

                # Callbacks
                if { [info exists row(callbacks)] } {
                    db_dml delete_callbacks {
                        delete from workflow_action_callbacks
                        where  action_id = :action_id
                    }
                    foreach callback_name $row(callbacks) {
                        workflow::action::callback_insert  -action_id $action_id  -name $callback_name
                    }
                    unset missing_elm(callbacks)
                }

                # Child actions
                foreach { type namespace } $handlers {
                    # type is 'roles', 'actions', 'states', etc.
                    if { [info exists row(child_${type})] } {

                        # First, delete existing objects
                        foreach existing_action_id [${namespace}::get_ids  -workflow_id $workflow_id  -parent_action_id $action_id]  {
                            # LARS: Ugly as hell with the string range to cut from 'actions' to 'action_id'
                            ${namespace}::edit -[string range $type 0 end-1]_id $existing_action_id
                        }

                        foreach { child_short_name child_spec } $row(child_${type}) {
                            array unset child
                            array set child $child_spec
                            set child(short_name) $child_short_name
                            set child(parent_action_id) $action_id

                            # string trim everything
                            foreach key [array names child] {
                                set child($key) [string trim $child($key)]
                            }

                            ${namespace}::edit  -internal  -handlers $handlers  -operation "insert"  -workflow_id $workflow_id  -array child
                        }
                        unset missing_elm(child_${type})
                    }
                }

                # Check that there are no unknown attributes
                if { [array size missing_elm] > 0 && !$no_complain_p } {
                    error "Trying to set illegal action attributes: [join [array names missing_elm] ""]"
                }
            }
        }

        if { !$internal_p } {
            workflow::definition_changed_handler -workflow_id $workflow_id
        }
    }

    return $action_id
Generic XQL file:
<fullquery name="workflow::action::edit.insert_privilege">
    <querytext>
        insert into workflow_action_privileges
                (action_id, privilege)
         values (:action_id, :privilege)
    </querytext>
</fullquery>

<fullquery name="workflow::action::edit.insert_initial_action">
    <querytext> 
        insert into workflow_initial_action
                (workflow_id, action_id)
         values (:workflow_id, :action_id)
    </querytext>
</fullquery>

<fullquery name="workflow::action::edit.insert_allowed_role">
    <querytext>
        insert into workflow_action_allowed_roles
        select :action_id,
                (select role_id
                from workflow_roles
                where workflow_id = :workflow_id
                and short_name = :allowed_role) as role_id
          from dual
    </querytext>
</fullquery>
packages/workflow/tcl/action-procs.xql

PostgreSQL XQL file:
<fullquery name="workflow::action::edit.update_timeout_seconds_name">
    <querytext>
      timeout
    </querytext>
</fullquery>

<fullquery name="workflow::action::edit.update_timeout_seconds_value">
    <querytext>
      [ad_decode $attr_timeout_seconds "" "null" "interval '$attr_timeout_seconds seconds'"]
    </querytext>
</fullquery>
packages/workflow/tcl/action-procs-postgresql.xql

Oracle XQL file:
<fullquery name="workflow::action::edit.update_timeout_seconds_name">
    <querytext>
      timeout_seconds
    </querytext>
</fullquery>

<fullquery name="workflow::action::edit.update_timeout_seconds_value">
    <querytext>
      :attr_timeout_seconds
    </querytext>
</fullquery>
packages/workflow/tcl/action-procs-oracle.xql

[ hide source ] | [ make this the default ]
Show another procedure: