class MaestroIfTask in Maestro 3.x
Same name and namespace in other branches
- 8.2 src/Plugin/EngineTasks/MaestroIfTask.php \Drupal\maestro\Plugin\EngineTasks\MaestroIfTask
Maestro If 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 = "MaestroIf",
task_description = @Translation("The Maestro Engine's If task."),
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\maestro\Plugin\EngineTasks\MaestroIfTask implements MaestroEngineTaskInterface uses MaestroTaskTrait
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of MaestroIfTask
File
- src/
Plugin/ EngineTasks/ MaestroIfTask.php, line 26
Namespace
Drupal\maestro\Plugin\EngineTasksView source
class MaestroIfTask 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 FALSE;
}
/**
* {@inheritDoc}
*/
public function shortDescription() {
return t('If Task');
}
/**
* {@inheritDoc}
*/
public function description() {
return $this
->t('Performs logic on task completion or variables.');
}
/**
* {@inheritDoc}
*
* @see \Drupal\Component\Plugin\PluginBase::getPluginId()
*/
public function getPluginId() {
return 'MaestroIf';
}
/**
* {@inheritDoc}
*/
public function getTaskColours() {
return '#daa520';
}
/**
* Part of the ExecutableInterface
* Execution of the Batch Function task will use the handler for this task as the executable function.
* {@inheritdoc}.
*/
public function execute() {
$templateMachineName = MaestroEngine::getTemplateIdFromProcessId($this->processID);
$taskMachineName = MaestroEngine::getTaskIdFromQueueId($this->queueID);
$task = MaestroEngine::getTemplateTaskByID($templateMachineName, $taskMachineName);
$statusFlag = NULL;
$ifData = $task['data']['if'];
$variable = $ifData['variable'];
$variableValue = $ifData['variable_value'];
$method = $ifData['method'];
// This is one of our constants defined in the engine.
$status = $ifData['status'];
// = , !=, < , >
$operator = $ifData['operator'];
switch ($method) {
case 'byvariable':
$processVariableValue = MaestroEngine::getProcessVariable($variable, $this->processID);
// we're being optimistic here in that we're going to have a status match.
$statusFlag = TRUE;
// We need to determine if the variable chosen contains the value we are testing against based on the condition.
switch ($operator) {
case '=':
// Not equal!
if (strcmp($variableValue, $processVariableValue) != 0) {
$statusFlag = FALSE;
}
break;
case '!=':
// equal!
if (strcmp($variableValue, $processVariableValue) == 0) {
$statusFlag = FALSE;
}
break;
case '<':
if (floatval($processVariableValue) > floatval($variableValue)) {
$statusFlag = FALSE;
}
break;
case '>':
if (floatval($processVariableValue) < floatval($variableValue)) {
$statusFlag = FALSE;
}
break;
}
break;
case 'bylasttaskstatus':
// Need to find out who points to this task. If there is more than one pointer to this task,
// we have no real way to know what to do other than if any other task that DOESN'T have the
// status, we return false.
$pointers = MaestroEngine::getTaskPointersFromTemplate($templateMachineName, $taskMachineName);
// Pointers now holds the task machine names (taskIDs). we fetch these from the queue now.
$query = \Drupal::entityQuery('maestro_queue');
$andMainConditions = $query
->andConditionGroup()
->condition('process_id', $this->processID)
->condition('status', '0', '<>')
->condition('archived', '1');
$orConditionGroup = $query
->orConditionGroup();
foreach ($pointers as $taskID) {
$orConditionGroup
->condition('task_id', $taskID);
}
$andMainConditions
->condition($orConditionGroup);
$query
->condition($andMainConditions);
$entity_ids = $query
->execute();
foreach ($entity_ids as $entityID) {
$queueRecord = \Drupal::entityTypeManager()
->getStorage('maestro_queue')
->load($entityID);
if (strcmp($status, $queueRecord->status
->getString()) != 0) {
$statusFlag = FALSE;
}
}
// At this point, if the statusFlag is not false, it must be OK as the default is NULL.
if ($statusFlag === NULL) {
$statusFlag = TRUE;
}
break;
}
// At this point, we have a statusFlag variable that denotes whether the pointed-from tasks in the queue have
// a status that is equal to the status that was provided in the template. If it's false, then we complete this
// IF task with the execution status as success with a completion status of use the false branch.
if ($statusFlag !== NULL) {
if ($statusFlag == TRUE) {
// Normal condition here. we've not aborted or done anything different.
$this->executionStatus = TASK_STATUS_SUCCESS;
// This will follow the true branch.
$this->completionStatus = MAESTRO_TASK_COMPLETION_NORMAL;
}
else {
// again, nothing unusual. just set the task status.
$this->executionStatus = TASK_STATUS_SUCCESS;
// ahh.. last status doesn't equal what we tested for. Use the false branch for nextstep.
$this->completionStatus = MAESTRO_TASK_COMPLETION_USE_FALSE_BRANCH;
}
// Nothing really stopping us from always completing this task in the engine.
return TRUE;
}
\Drupal::logger('maestro')
->error('If task does not have a statusFlag set and is unable to complete');
// Problem here - we have a situation where the IF statement is stuck because the statusFlag was never set.
return FALSE;
// This will hold the engine at the IF task forever.
}
/**
* {@inheritDoc}
*/
public function getExecutableForm($modal, MaestroExecuteInteractive $parent) {
}
/**
* {@inheritDoc}
*/
public function handleExecuteSubmit(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritDoc}
*/
public function getTaskEditForm(array $task, $templateMachineName) {
$ifParms = isset($task['data']['if']) ? $task['data']['if'] : [];
$form = [
'#markup' => $this
->t('Edit the logic for this IF task'),
];
$form['method'] = [
'#type' => 'radios',
'#title' => $this
->t('Execute the IF:'),
'#options' => [
'byvariable' => $this
->t('By Variable'),
'bylasttaskstatus' => $this
->t('By Last Task Status'),
],
'#default_value' => isset($ifParms['method']) ? $ifParms['method'] : '',
'#required' => TRUE,
'#attributes' => [
// 'onclick' => 'document.getElementById("byvar").setAttribute("open", "open");'
'onclick' => 'maestro_if_task_toggle(this);',
],
'#attached' => [
'library' => [
'maestro/maestro-engine-task-edit',
],
],
];
/*
* By Variable options
*/
$variables = MaestroEngine::getTemplateVariables($templateMachineName);
$options = [];
foreach ($variables as $variableName => $arr) {
$options[$variableName] = $variableName;
}
$form['byvariable'] = [
'#id' => 'byvar',
'#tree' => TRUE,
'#type' => 'details',
'#title' => $this
->t('By Variable Options'),
'#open' => FALSE,
];
$form['byvariable']['variable'] = [
'#type' => 'select',
'#title' => $this
->t('Argument variable'),
'#required' => FALSE,
'#default_value' => isset($ifParms['variable']) ? $ifParms['variable'] : '',
'#options' => $options,
];
$form['byvariable']['operator'] = [
'#type' => 'select',
'#title' => $this
->t('Operator'),
'#required' => FALSE,
'#default_value' => isset($ifParms['operator']) ? $ifParms['operator'] : '',
'#options' => [
'=' => '=',
'>' => '>',
'<' => '<',
'!=' => '!=',
],
];
$form['byvariable']['variable_value'] = [
'#type' => 'textfield',
'#title' => $this
->t('Variable value'),
'#description' => $this
->t('The IF will check against this value during execution'),
'#default_value' => isset($ifParms['variable_value']) ? $ifParms['variable_value'] : '',
'#required' => FALSE,
];
/*
* The by status section
*/
$form['bystatus'] = [
'#id' => 'bystatus',
'#tree' => TRUE,
'#type' => 'details',
'#title' => $this
->t('By Last Task Status'),
'#open' => FALSE,
'#markup' => $this
->t('This method is only useful if ONLY ONE task points to this IF.
If more than one task points to this IF task, a FALSE will be returned if ANY of those
tasks do not have a status of the status chosen in the status selector.'),
];
$form['bystatus']['status'] = [
'#type' => 'select',
'#title' => $this
->t('Status'),
'#required' => FALSE,
'#default_value' => isset($ifParms['status']) ? $ifParms['status'] : '',
'#options' => [
TASK_STATUS_SUCCESS => $this
->t('Last Task Status is Success'),
TASK_STATUS_CANCEL => $this
->t('Last Task Status is Cancel'),
TASK_STATUS_HOLD => $this
->t('Last Task Status is Hold'),
TASK_STATUS_ABORTED => $this
->t('Last Task Status is Aborted'),
],
];
if (isset($ifParms['method']) && $ifParms['method'] == 'byvariable') {
$form['byvariable']['#open'] = TRUE;
$form['bystatus']['#open'] = FALSE;
}
else {
$form['byvariable']['#open'] = FALSE;
$form['bystatus']['#open'] = TRUE;
}
return $form;
}
/**
* {@inheritDoc}
*/
public function validateTaskEditForm(array &$form, FormStateInterface $form_state) {
$method = $form_state
->getValue('method');
switch ($method) {
case 'byvariable':
$byvars = $form_state
->getValue('byvariable');
if (empty($byvars['variable'])) {
$form_state
->setErrorByName('byvariable][variable', $this
->t('When doing an IF by variable, you must provide a variable to IF on.'));
}
if (empty($byvars['operator'])) {
$form_state
->setErrorByName('byvariable][operator', $this
->t('When doing an IF by variable, you must provide a operator.'));
}
if (empty($byvars['variable_value'])) {
$form_state
->setErrorByName('byvariable][variable_value', $this
->t('When doing an IF by variable, you must provide a variable value.'));
}
$form['byvariable']['#open'] = TRUE;
$form['bystatus']['#open'] = FALSE;
break;
case 'bystatus':
// This condition may not even occur, but if for some reason the form is corrupt, we need to ensure we have a value.
$byvars = $form_state
->getValue('bystatus');
if (empty($byvars['status'])) {
$form_state
->setErrorByName('bystatus][status', $this
->t('When doing an IF by statys, you must provide a status value.'));
}
$form['byvariable']['#open'] = FALSE;
$form['bystatus']['#open'] = TRUE;
break;
}
}
/**
* {@inheritDoc}
*/
public function prepareTaskForSave(array &$form, FormStateInterface $form_state, array &$task) {
// variable, operator, variable_value, status.
$method = $form_state
->getValue('method');
$byvariable = $form_state
->getValue('byvariable');
$bystatus = $form_state
->getValue('bystatus');
$task['data']['if'] = [
'method' => $method,
'variable' => $byvariable['variable'],
'operator' => $byvariable['operator'],
'variable_value' => $byvariable['variable_value'],
'status' => $bystatus['status'],
];
}
/**
* {@inheritDoc}
*/
public function performValidityCheck(array &$validation_failure_tasks, array &$validation_information_tasks, array $task) {
// We have a number of fields that we know MUST be filled in.
// the issue is that we have a to and falseto branches that we really don't know if they should be connected or not
// so for the time being, we'll leave the to and falseto branches alone.
$data = $task['data']['if'];
// First check the method. if it's blank, the whole thing will simply fail out.
if (array_key_exists('method', $data) && $data['method'] == '' || !array_key_exists('method', $data)) {
$validation_failure_tasks[] = [
'taskID' => $task['id'],
'taskLabel' => $task['label'],
'reason' => t('The IF task has not been set up properly. The method of "By Variable" or "By Status" is missing and thus the engine will be unable to execute this task.'),
];
}
else {
// Method IS filled in. Let's validate the rest now
// operator is important for both.
if (array_key_exists('operator', $data) && $data['operator'] == '' || !array_key_exists('operator', $data)) {
$validation_failure_tasks[] = [
'taskID' => $task['id'],
'taskLabel' => $task['label'],
'reason' => t('The IF task has not been set up properly. The operator has not been set. The engine will be unable to execute this task.'),
];
}
switch ($data['method']) {
case 'byvariable':
// Check that the variable has been set.
if (array_key_exists('variable', $data) && $data['variable'] == '' || !array_key_exists('variable', $data)) {
$validation_failure_tasks[] = [
'taskID' => $task['id'],
'taskLabel' => $task['label'],
'reason' => t('The IF task has not been set up properly. The variable has not been set. The engine will be unable to execute this task.'),
];
}
// It is conceivable that the variable value could be tested against a blank. So just make sure the value key exists.
if (!array_key_exists('variable_value', $data)) {
$validation_failure_tasks[] = [
'taskID' => $task['id'],
'taskLabel' => $task['label'],
'reason' => t('The IF task has not been set up properly. The variable value has not been set. The engine will be unable to execute this task.'),
];
}
break;
case 'bystatus':
if (array_key_exists('status', $data) && $data['status'] == '' || !array_key_exists('status', $data)) {
$validation_failure_tasks[] = [
'taskID' => $task['id'],
'taskLabel' => $task['label'],
'reason' => t('The IF task has not been set up properly. The status has not been set. The engine will be unable to execute this task.'),
];
}
break;
}
}
}
/**
* {@inheritDoc}
*/
public function getTemplateBuilderCapabilities() {
return [
'edit',
'drawlineto',
'drawfalselineto',
'removelines',
'remove',
];
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
public | function | 2 | |
DependencySerializationTrait:: |
public | function | 2 | |
MaestroIfTask:: |
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:: |
|
MaestroIfTask:: |
public | function |
Part of the ExecutableInterface
Execution of the Batch Function task will use the handler for this task as the executable function.
. Overrides ExecutableInterface:: |
|
MaestroIfTask:: |
public | function |
Gets the Maestro executable form for a task console. Overrides MaestroEngineTaskInterface:: |
|
MaestroIfTask:: |
public | function |
Overrides PluginBase:: |
|
MaestroIfTask:: |
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:: |
|
MaestroIfTask:: |
public | function |
Method to allow a task to add their own fields to the task edit form. Overrides MaestroEngineTaskInterface:: |
|
MaestroIfTask:: |
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:: |
|
MaestroIfTask:: |
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:: |
|
MaestroIfTask:: |
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:: |
|
MaestroIfTask:: |
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:: |
|
MaestroIfTask:: |
public | function |
The specific task's manipulation of the values to save for a template save. Overrides MaestroEngineTaskInterface:: |
|
MaestroIfTask:: |
public | function |
Get the task's short description. Useful for things like labels. Overrides MaestroEngineTaskInterface:: |
|
MaestroIfTask:: |
public | function |
This method must be called by the template builder in order to validate the form entry values before saving. Overrides MaestroEngineTaskInterface:: |
|
MaestroIfTask:: |
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. |