class MaestroInteractiveTask in Maestro 3.x
Same name and namespace in other branches
- 8.2 src/Plugin/EngineTasks/MaestroInteractiveTask.php \Drupal\maestro\Plugin\EngineTasks\MaestroInteractiveTask
Maestro Interactive Task Plugin.
The plugin annotations below should include: id: The task type ID for this task. For Maestro tasks, this is Maestro[TaskType]. So for example, the start task shipped by Maestro is MaestroStart. The Maestro End task has an id of MaestroEnd Those task IDs are what's used in the engine when a task is injected into the queue.
Plugin annotation
@Plugin(
id = "MaestroInteractive",
task_description = @Translation("The Maestro Engine's interactive task."),
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\maestro\Plugin\EngineTasks\MaestroInteractiveTask implements MaestroEngineTaskInterface uses MaestroTaskTrait
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of MaestroInteractiveTask
File
- src/
Plugin/ EngineTasks/ MaestroInteractiveTask.php, line 27
Namespace
Drupal\maestro\Plugin\EngineTasksView source
class MaestroInteractiveTask extends PluginBase implements MaestroEngineTaskInterface {
use MaestroTaskTrait;
/**
* Constructor.
*/
public function __construct($configuration = NULL) {
if (is_array($configuration)) {
$this->processID = $configuration[0];
$this->queueID = $configuration[1];
}
}
/**
* {@inheritDoc}
*/
public function isInteractive() {
return TRUE;
}
/**
* {@inheritDoc}
*/
public function shortDescription() {
return t('Interactive Task');
}
/**
* {@inheritDoc}
*/
public function description() {
return $this
->t('Interactive Task.');
}
/**
* {@inheritDoc}
*
* @see \Drupal\Component\Plugin\PluginBase::getPluginId()
*/
public function getPluginId() {
return 'MaestroInteractive';
}
/**
* {@inheritDoc}
*/
public function getTaskColours() {
return '#0000ff';
}
/**
* Part of the ExecutableInterface
* Execution of the interactive task does nothing except for setting the run_once flag
* {@inheritdoc}.
*/
public function execute() {
// Need to set the run_once flag here
// as interactive tasks are executed and completed by the user using the Maestro API.
$queueRecord = \Drupal::entityTypeManager()
->getStorage('maestro_queue')
->load($this->queueID);
$queueRecord
->set('run_once', 1);
$queueRecord
->save();
return FALSE;
}
/**
* {@inheritDoc}
*/
public function getExecutableForm($modal, MaestroExecuteInteractive $parent) {
// By default, we will provide a form that has a base queueID field and a submit/reject button set.
// you can override this with ease in your own handler.
// the task console should be looking at whether this requires a handler form or not.
// our implementation forces the handler to be a mandatory field, thus causing functions like: form maestro_accept_only_form in the maestro.module
// file to fire.
// We are hiding this for now, as you can override all of this with your own handler.
$form['queueID'] = [
// This is just a placeholder form to get you under way.
'#type' => 'hidden',
'#title' => $this
->t('The queue ID of this task'),
'#default_value' => $this->queueID,
'#description' => $this
->t('queueID'),
];
$form['information_text'] = [
'#plain_text' => $this
->t('Default Maestro Interactive Task.'),
'#suffix' => '<br><br>',
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this
->t('Complete'),
];
$form['actions']['reject'] = [
'#type' => 'submit',
'#value' => $this
->t('Reject'),
];
if ($modal == 'modal') {
$form['actions']['submit']['#ajax'] = [
'callback' => [
$parent,
'completeForm',
],
'wrapper' => '',
];
$form['actions']['reject']['#ajax'] = [
'callback' => [
$parent,
'completeForm',
],
'wrapper' => '',
];
}
return $form;
}
/**
* {@inheritDoc}
*/
public function handleExecuteSubmit(array &$form, FormStateInterface $form_state) {
$queueID = intval($form_state
->getValue('maestro_queue_id'));
$canExecute = MaestroEngine::canUserExecuteTask($queueID, \Drupal::currentUser()
->id());
$triggeringElement = $form_state
->getTriggeringElement();
if (strstr($triggeringElement['#id'], 'edit-submit') !== FALSE && $queueID > 0 && $canExecute) {
MaestroEngine::completeTask($queueID, \Drupal::currentUser()
->id());
}
elseif ($canExecute) {
// we'll complete the task, but we'll also flag it as TASK_STATUS_CANCEL.
MaestroEngine::completeTask($queueID, \Drupal::currentUser()
->id());
MaestroEngine::setTaskStatus($queueID, TASK_STATUS_CANCEL);
}
else {
//Note this as an exception? The user tried to complete without being assigned.
}
$task = MaestroEngine::getTemplateTaskByQueueID($queueID);
if (isset($task['data']['redirect_to'])) {
$response = new TrustedRedirectResponse($task['data']['redirect_to']);
$form_state
->setResponse($response);
}
}
/**
* {@inheritDoc}
*/
public function getTaskEditForm(array $task, $templateMachineName) {
$form = [
'#markup' => t('Interactive Task Edit'),
];
// Let modules signal the handlers they wish to share.
$handlers = \Drupal::moduleHandler()
->invokeAll('maestro_interactive_handlers', []);
$handler_desc = $this
->t('The function that contains the form definition for this instance of the interactive task.');
if (isset($task['handler']) && isset($handlers[$task['handler']])) {
$handler_desc = $handlers[$task['handler']];
}
// The handler will use a lookahead.
$form['handler'] = [
'#type' => 'textfield',
'#title' => $this
->t('Handler'),
'#default_value' => isset($task['handler']) ? $task['handler'] : '',
'#required' => FALSE,
'#autocomplete_route_name' => 'maestro.autocomplete.interactive_handlers',
'#ajax' => [
'callback' => [
$this,
'interactiveHandlerCallback',
],
'event' => 'autocompleteclose',
'wrapper' => 'handler-ajax-refresh-wrapper',
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
],
];
$form['handler_help_text'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $handler_desc,
'#readonly' => TRUE,
'#attributes' => [
'class' => [
'handler-help-message',
],
'id' => [
'handler-ajax-refresh-wrapper',
],
],
];
$form['redirect_to'] = [
'#type' => 'textfield',
'#title' => $this
->t('Return Path'),
'#description' => $this
->t('You can specify where your return path should go upon task completion.'),
'#default_value' => isset($task['data']['redirect_to']) ? $task['data']['redirect_to'] : 'taskconsole',
'#required' => TRUE,
];
$form['modal'] = [
'#type' => 'select',
'#title' => $this
->t('Task presentation'),
'#description' => $this
->t('Should this task be shown as a modal or full screen task.'),
'#default_value' => isset($task['data']['modal']) ? $task['data']['modal'] : 'modal',
'#options' => [
'modal' => $this
->t('Modal'),
'notmodal' => $this
->t('Full Page'),
],
'#required' => TRUE,
];
return $form;
}
/**
* Implements callback for Ajax event on objective selection.
*
* @param array $form
* From render array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Current state of form.
*
* @return array
* Objective selection section of the form.
*/
public function interactiveHandlerCallback(array &$form, FormStateInterface $form_state) {
$selected_handler = $new_objective_id = $form_state
->getValue('handler');
// Let modules signal the handlers they wish to share.
$handlers = \Drupal::moduleHandler()
->invokeAll('maestro_interactive_handlers', []);
if ($selected_handler != '' && !function_exists($selected_handler)) {
$handler_desc = \Drupal::translation()
->translate('This handler form function does not exist.');
}
elseif (isset($handlers[$selected_handler])) {
$handler_desc = $handlers[$selected_handler];
}
else {
$handler_desc = \Drupal::translation()
->translate('The function that contains the form definition for this instance of the interactive task.');
}
$form['handler_help_text'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $handler_desc,
'#readonly' => TRUE,
'#attributes' => [
'class' => [
'handler-help-message',
],
'id' => [
'handler-ajax-refresh-wrapper',
],
],
];
return $form['handler_help_text'];
}
/**
* {@inheritDoc}
*/
public function validateTaskEditForm(array &$form, FormStateInterface $form_state) {
$handler = $form_state
->getValue('handler');
/* Test if the interactive function name has comments in it's name
* Defined inside [] so they can appear in the auto-complete result to the user.
* Need to strip these comments out since they are not part of the real function name
*/
if (strpos($handler, '[') > 0) {
$string_parts = explode('[', $handler);
$handler = $string_parts[0];
}
// Let's validate the handler here to ensure that it actually exists.
if ($handler != '' && !function_exists($handler)) {
$form_state
->setErrorByName('handler', $this
->t('This handler form function does not exist.'));
}
}
/**
* {@inheritDoc}
*/
public function prepareTaskForSave(array &$form, FormStateInterface $form_state, array &$task) {
$task['handler'] = $form_state
->getValue('handler');
/* Test if the interactive function name has comments in it's name
* Defined inside [] so they can appear in the auto-complete result to the user.
* Need to strip these comments out since they are not part of the real function name
*/
if (strpos($task['handler'], '[') > 0) {
$string_parts = explode('[', $task['handler']);
$task['handler'] = $string_parts[0];
}
$task['data']['modal'] = $form_state
->getValue('modal');
$redirect = $form_state
->getValue('redirect_to');
if (isset($redirect)) {
$task['data']['redirect_to'] = $redirect;
}
else {
$task['data']['redirect_to'] = '';
}
}
/**
* {@inheritDoc}
*/
public function performValidityCheck(array &$validation_failure_tasks, array &$validation_information_tasks, array $task) {
// Pretty simple -- just ensure that there's a handler and modal set.
if (array_key_exists('handler', $task) && $task['handler'] == '' || !array_key_exists('handler', $task)) {
$validation_information_tasks[] = [
'taskID' => $task['id'],
'taskLabel' => $task['label'],
'reason' => t('The Interactive Task handler is missing and thus the engine will assign the default handler to this task.'),
];
}
if (array_key_exists('modal', $task['data']) && $task['data']['modal'] == '' || !array_key_exists('modal', $task['data'])) {
$validation_failure_tasks[] = [
'taskID' => $task['id'],
'taskLabel' => $task['label'],
'reason' => t('The Interactive Task has not been set up properly. The "Task Presentation" option is missing and thus the engine will be unable to execute this task.'),
];
}
// This task should have assigned users
// $task['assigned'] should have data.
if (array_key_exists('assigned', $task) && $task['assigned'] == '' || !array_key_exists('assigned', $task)) {
$validation_failure_tasks[] = [
'taskID' => $task['id'],
'taskLabel' => $task['label'],
'reason' => t('The Interactive Task has not been set up properly. The Interactive Task requires assignments to actors, roles or other assignment options.'),
];
}
}
/**
* {@inheritDoc}
*/
public function getTemplateBuilderCapabilities() {
return [
'edit',
'drawlineto',
'removelines',
'remove',
];
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
public | function | 2 | |
DependencySerializationTrait:: |
public | function | 2 | |
MaestroInteractiveTask:: |
public | function |
Longer description. This generally follows the short Description but can be used to be more descriptive if you
wish to surface this description in a UI element. Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function |
Part of the ExecutableInterface
Execution of the interactive task does nothing except for setting the run_once flag
. Overrides ExecutableInterface:: |
|
MaestroInteractiveTask:: |
public | function |
Gets the Maestro executable form for a task console. Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function |
Overrides PluginBase:: |
|
MaestroInteractiveTask:: |
public | function |
Returns the task's defined colours. This is useful if you want to let the tasks decide on what colours to paint themselves in the UI. Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function |
Method to allow a task to add their own fields to the task edit form. Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function |
Returns an array of consistenly keyed array elements that define what this task can do in the template builder.
Elements are:
edit, drawlineto, drawfalselineto, removelines, remove. Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function |
Interactive tasks, or tasks that signal themselves as requiring human interaction will have the resulting form submissions
sent to their own handler for processing to determine if the task should be completed or not or to carry out any task
processing… Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function | Implements callback for Ajax event on objective selection. | |
MaestroInteractiveTask:: |
public | function |
Returns TRUE or FALSE to denote if this task has an interactive interface that needs to be shown in the Task Console
and for any other requirements of the task. Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function |
Lets the task perform validation on itself. If the task is missing any internal requirements, it can flag itself as having an issue.
Return array MUST be in the format of array(
'taskID' => the task machine name,
'taskLabel'… Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function |
The specific task's manipulation of the values to save for a template save. Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function |
Get the task's short description. Useful for things like labels. Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function |
This method must be called by the template builder in order to validate the form entry values before saving. Overrides MaestroEngineTaskInterface:: |
|
MaestroInteractiveTask:: |
public | function |
Constructor. Overrides PluginBase:: |
|
MaestroTaskTrait:: |
protected | property | Default will be that the task completed normally. | |
MaestroTaskTrait:: |
protected | property | The default will be success for the execution status. | |
MaestroTaskTrait:: |
protected | property | The Maestro Process ID. | |
MaestroTaskTrait:: |
protected | property | The Maestro queue ID. | |
MaestroTaskTrait:: |
public | function | Retrieve the core Maestro form edit elements for Assignments and Notifications. | |
MaestroTaskTrait:: |
public | function | Retrieve the core Maestro form edit elements that all tasks MUST adhere to. | |
MaestroTaskTrait:: |
public | function | Returns the value of the completion status protected variable denoting any special completion status condition the task wishes to pass along. | |
MaestroTaskTrait:: |
public | function | Returns the value of the execution status protected variable denoting if the execution of this task is complete. | |
MaestroTaskTrait:: |
public | function | Available for all tasks -- this does the general task construction for us, ensuring we have sanity in the saved Config Entity for the task. Assignments and Notifications are the two main elements this method worries about. | |
MessengerTrait:: |
protected | property | The messenger. | 27 |
MessengerTrait:: |
public | function | Gets the messenger. | 27 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
2 |
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 4 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |