/// <summary> /// Renders the specified context. /// </summary> /// <param name="context">The context.</param> /// <param name="result">The result.</param> public override void OnRender(ILavaRenderContext context, TextWriter result) { // first ensure that entity commands are allowed in the context if (!this.IsAuthorized(context)) { result.Write(string.Format(LavaBlockBase.NotAuthorizedMessage, this.SourceElementName)); return; } var attributes = new Dictionary <string, string>(); string parmWorkflowType = null; string parmWorkflowName = null; string parmWorkflowId = null; string parmActivityType = null; /* Parse the markup text to pull out configuration parameters. */ var parms = ParseMarkup(_markup, context); foreach (var p in parms) { if (p.Key.ToLower() == "workflowtype") { parmWorkflowType = p.Value; } else if (p.Key.ToLower() == "workflowname") { parmWorkflowName = p.Value; } else if (p.Key.ToLower() == "workflowid") { parmWorkflowId = p.Value; } else if (p.Key.ToLower() == "activitytype") { parmActivityType = p.Value; } else { attributes.AddOrReplace(p.Key, p.Value); } } /* Process inside a new stack level so our own created variables do not * persist throughout the rest of the workflow. */ context.ExecuteInChildScope((System.Action <ILavaRenderContext>)((newContext) => { var rockContext = LavaHelper.GetRockContextFromLavaContext(context); WorkflowService workflowService = new WorkflowService(rockContext); Rock.Model.Workflow workflow = null; WorkflowActivity activity = null; /* They provided a WorkflowType, so we need to kick off a new workflow. */ if (parmWorkflowType != null) { string type = parmWorkflowType; string name = parmWorkflowName ?? string.Empty; WorkflowTypeCache workflowType = null; /* Get the type of workflow */ if (type.AsGuidOrNull() != null) { workflowType = WorkflowTypeCache.Get(type.AsGuid()); } else if (type.AsIntegerOrNull() != null) { workflowType = WorkflowTypeCache.Get(type.AsInteger()); } /* Try to activate the workflow */ if (workflowType != null) { workflow = Rock.Model.Workflow.Activate(( WorkflowTypeCache )workflowType, ( string )parmWorkflowName); /* Set any workflow attributes that were specified. */ foreach (var attr in attributes) { if (workflow.Attributes.ContainsKey(attr.Key)) { workflow.SetAttributeValue(attr.Key, attr.Value.ToString()); } } if (workflow != null) { List <string> errorMessages; workflowService.Process(workflow, out errorMessages); if (errorMessages.Any()) { context["Error"] = string.Join("; ", errorMessages.ToArray()); } context["Workflow"] = workflow; } else { context["Error"] = "Could not activate workflow."; } } else { context["Error"] = "Workflow type not found."; } } /* They instead provided a WorkflowId, so we are working with an existing Workflow. */ else if (parmWorkflowId != null) { string id = parmWorkflowId.ToString(); /* Get the workflow */ if (id.AsGuidOrNull() != null) { workflow = workflowService.Get(id.AsGuid()); } else if (id.AsIntegerOrNull() != null) { workflow = workflowService.Get(id.AsInteger()); } if (workflow != null) { if (workflow.CompletedDateTime == null) { /* Currently we cannot activate an activity in a workflow that is currently * being processed. The workflow is held in-memory so the activity we would * activate would not show up for the processor and probably never run. */ if (!workflow.IsProcessing) { bool hasError = false; /* If they provided an ActivityType parameter then we need to activate * a new activity in the workflow. */ if (parmActivityType != null) { string type = parmActivityType.ToString(); WorkflowActivityTypeCache activityType = null; /* Get the type of activity */ if (type.AsGuidOrNull() != null) { activityType = WorkflowActivityTypeCache.Get(type.AsGuid()); } else if (type.AsIntegerOrNull() != null) { activityType = WorkflowActivityTypeCache.Get(type.AsInteger()); } if (activityType != null) { activity = WorkflowActivity.Activate(activityType, workflow); /* Set any workflow attributes that were specified. */ foreach (var attr in attributes) { if (activity.Attributes.ContainsKey(attr.Key)) { activity.SetAttributeValue(attr.Key, attr.Value.ToString()); } } } else { context["Error"] = "Activity type was not found."; hasError = true; } } /* Process the existing Workflow. */ if (!hasError) { List <string> errorMessages; workflowService.Process(workflow, out errorMessages); if (errorMessages.Any()) { context["Error"] = string.Join("; ", errorMessages.ToArray()); } context["Workflow"] = workflow; context["Activity"] = activity; } } else { context["Error"] = "Cannot activate activity on workflow that is currently being processed."; } } else { context["Error"] = "Workflow has already been completed."; } } else { context["Error"] = "Workflow not found."; } } else { context["Error"] = "Must specify one of WorkflowType or WorkflowId."; } base.OnRender(context, result); //RenderAll( NodeList, context, result ); // TODO: Test this! - NodeList is empty here, so the call to RenderAll seems unnecessary? })); }