class MaestroTaskConsoleController in Maestro 3.x
Same name and namespace in other branches
- 8.2 modules/maestro_taskconsole/src/Controller/MaestroTaskConsoleController.php \Drupal\maestro_taskconsole\Controller\MaestroTaskConsoleController
Maestro Task Console Controller.
Hierarchy
- class \Drupal\Core\Controller\ControllerBase implements ContainerInjectionInterface uses LoggerChannelTrait, MessengerTrait, RedirectDestinationTrait, StringTranslationTrait
- class \Drupal\maestro_taskconsole\Controller\MaestroTaskConsoleController
Expanded class hierarchy of MaestroTaskConsoleController
File
- modules/
maestro_taskconsole/ src/ Controller/ MaestroTaskConsoleController.php, line 21
Namespace
Drupal\maestro_taskconsole\ControllerView source
class MaestroTaskConsoleController extends ControllerBase {
/**
* GetTasks method
* This method is called by the menu router for /taskconsole.
* The output of this method is the current user's task console.
*/
public function getTasks($highlightQueueID = 0) {
global $base_url;
$config = \Drupal::config('maestro.settings');
// Before we do anything, let's see if we should be running the orchestrator through task console refreshes:
if ($config
->get('maestro_orchestrator_task_console')) {
$orchestrator = new MaestroOrchestrator();
$orchestrator
->orchestrate($config
->get('maestro_orchestrator_token'));
}
$engine = new MaestroEngine();
$build = [];
$build['task_console_table'] = [
'#type' => 'table',
'#header' => [
$this
->t('Task'),
$this
->t('Flow'),
$this
->t('Assigned'),
$this
->t('Actions'),
$this
->t('Details'),
],
'#empty' => t('You have no tasks.'),
'#attributes' => [
'class' => [
'taskconsole-tasks',
],
],
];
// Fetch the user's queue items.
$queueIDs = MaestroEngine::getAssignedTaskQueueIds(\Drupal::currentUser()
->id());
foreach ($queueIDs as $queueID) {
$highlight = '';
$url_from_route = FALSE;
if ($highlightQueueID == $queueID) {
// Set the highlight for the queue entry.
$highlight = 'maestro-highlight-task';
}
/*
* Reset the internal static cache for this queue record and then reload it
* Doing this because we found in certain cases it was not reflecting actual queue record
*/
\Drupal::entityTypeManager()
->getStorage('maestro_queue')
->resetCache([
$queueID,
]);
$queueRecord = \Drupal::entityTypeManager()
->getStorage('maestro_queue')
->load($queueID);
$processID = MaestroEngine::getProcessIdFromQueueId($queueID);
$processRecord = MaestroEngine::getProcessEntryById($processID);
$build['task_console_table'][$queueID]['#attributes'] = [
'class' => $highlight,
];
$build['task_console_table'][$queueID]['task'] = [
'#plain_text' => $queueRecord->task_label
->getString(),
];
$build['task_console_table'][$queueID]['flow'] = [
'#plain_text' => $processRecord->process_name
->getString(),
];
$build['task_console_table'][$queueID]['assigned'] = [
'#plain_text' => \Drupal::service('date.formatter')
->format($queueRecord->created
->getString(), 'custom', 'Y-m-d H:i:s'),
];
$templateMachineName = $engine
->getTemplateIdFromProcessId($queueRecord->process_id
->getString());
$taskTemplate = $engine
->getTemplateTaskByID($templateMachineName, $queueRecord->task_id
->getString());
$template = MaestroEngine::getTemplate($templateMachineName);
// Default link title.
$link = 'Execute';
$use_modal = FALSE;
$query_options = [
'queueid' => $queueID,
];
if (array_key_exists('data', $taskTemplate) && array_key_exists('modal', $taskTemplate['data']) && $taskTemplate['data']['modal'] == 'modal') {
$use_modal = TRUE;
}
/*
* If this is an interactive Maestro task, it means we show an Operations Dropbutton form element
* This is a button with one or more links where the links can be to a node add/edit or
* to open up a modal window for an interactive task like a form approval action.
*
* We need to determine if we have any special handling for this interactive task. It could be
* a link to an external system.
*/
/*
* Test to see if this is a URL that can be deduced from a Drupal route or not.
* if it's not a route, then $url_from_route will be FALSE
*/
$handler = $queueRecord->handler
->getString();
if ($handler && !empty($handler) && $queueRecord->is_interactive
->getString() == '1') {
$handler = str_replace($base_url, '', $handler);
$handler_type = TaskHandler::getType($handler);
$handler_url_parts = UrlHelper::parse($handler);
$query_options += $handler_url_parts['query'];
// Let's call a hook here to let people change the name of the link to execute the task if they so choose to do so.
\Drupal::moduleHandler()
->invokeAll('maestro_task_console_interactive_link_alter', [
&$link,
$taskTemplate,
$queueRecord,
$templateMachineName,
]);
}
elseif ($queueRecord->is_interactive
->getString() == '1' && empty($handler)) {
// Handler is empty. If this is an interactive task and has no handler, we're still OK. This is an interactive function that uses a default handler then.
$handler_type = 'function';
}
else {
// We shouldn't be processing this. Skip the rest.
continue;
}
$links = [];
switch ($handler_type) {
case 'external':
$build['task_console_table'][$queueID]['execute']['maestro_link'] = [
'#type' => 'link',
'#title' => $this
->t($link),
'#url' => Url::fromUri($handler, [
'query' => $query_options,
]),
];
break;
case 'internal':
$build['task_console_table'][$queueID]['execute'] = [
'data' => [
'#type' => 'operations',
'#links' => [
'maestro_link' => [
'title' => $this
->t($link),
'url' => Url::fromUserInput($handler, [
'query' => $query_options,
]),
],
],
],
];
// Let's call a hook here to let people change the name of the link to execute the task if they so choose to do so.
\Drupal::moduleHandler()
->invokeAll('maestro_task_console_interactive_link_alter', [
&$link,
$taskTemplate,
$queueRecord,
$templateMachineName,
]);
break;
case 'function':
// Let's call a hook here to let people change the name of the link to execute the task if they so choose to do so.
\Drupal::moduleHandler()
->invokeAll('maestro_task_console_interactive_link_alter', [
&$link,
$taskTemplate,
$queueRecord,
$templateMachineName,
]);
if ($use_modal) {
$query_options += [
'modal' => 'modal',
];
$links[$link] = [
'title' => $this
->t($link),
'url' => Url::fromRoute('maestro.execute', $query_options),
'attributes' => [
'class' => [
'use-ajax',
],
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode([
'width' => 700,
]),
],
];
}
else {
$query_options += [
'modal' => 'notmodal',
];
$links[$link] = [
'title' => $this
->t($link),
'url' => Url::fromRoute('maestro.execute', $query_options),
];
}
$build['task_console_table'][$queueID]['execute'] = [
'data' => [
'#type' => 'operations',
'#links' => $links,
],
];
break;
default:
$build['task_console_table'][$queueID]['execute'] = [
'#plain_text' => $this
->t('Invalid Link'),
];
}
/*
* Provide your own execution links here if you wish
*/
\Drupal::moduleHandler()
->invokeAll('maestro_task_console_alter_execution_link', [
&$build['task_console_table'][$queueID]['execute'],
$taskTemplate,
$queueRecord,
$templateMachineName,
]);
$build['task_console_table'][$queueID]['expand'] = [
'#wrapper_attributes' => [
'class' => [
'maestro-expand-wrapper',
],
],
'#plain_text' => '',
];
$var_workflow_stage_count = intval(MaestroEngine::getProcessVariable('workflow_timeline_stage_count', $processID));
// If the show details is on OR the status bar is on, we'll show the toggler.
if (isset($template->show_details) && $template->show_details || isset($template->default_workflow_timeline_stage_count) && intval($template->default_workflow_timeline_stage_count) > 0 && $var_workflow_stage_count > 0) {
// Provide details expansion column. Clicking on it will show the status and/or the task detail information via ajax.
$build['task_console_table'][$queueID]['expand'] = [
'#wrapper_attributes' => [
'class' => [
'maestro-expand-wrapper',
'maestro-status-toggle-' . $queueID,
],
],
'#attributes' => [
'class' => [
'maestro-timeline-status',
'maestro-status-toggle',
],
'title' => $this
->t('Open Details'),
],
'#type' => 'link',
'#id' => 'maestro-id-ajax-' . $queueID,
'#url' => Url::fromRoute('maestro_taskconsole.status_ajax_open', [
'processID' => $processID,
'queueID' => $queueID,
]),
'#title' => $this
->t('Open Details'),
'#ajax' => [
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
],
];
// Gives the <tr> tag an ID we can target.
$build['task_console_table'][$queueID . '_ajax']['#attributes']['id'] = $queueID . '_ajax';
$build['task_console_table'][$queueID . '_ajax']['#attributes']['class'] = [
'maestro-ajax-row',
];
$build['task_console_table'][$queueID . '_ajax']['task'] = [
'#wrapper_attributes' => [
'colspan' => count($build['task_console_table'][$queueID]),
],
'#prefix' => '<div id="maestro-ajax-' . $queueID . '">',
'#suffix' => '</div>',
];
}
}
$build['#attached']['library'][] = 'maestro_taskconsole/maestro_taskconsole_css';
// Css for the status bar.
$build['#attached']['library'][] = 'maestro/maestro-engine-css';
$build['#attached']['drupalSettings'] = [
'baseURL' => base_path(),
];
return $build;
}
/**
* Method to fetch the status of a process.
*/
public function getStatus($processID, $queueID) {
$build = [];
$replace = [];
$status_bar = '';
$canExecute = MaestroEngine::canUserExecuteTask($queueID, \Drupal::currentUser()
->id());
if ($canExecute) {
$queueRecord = \Drupal::entityTypeManager()
->getStorage('maestro_queue')
->load($queueID);
$templateMachineName = MaestroEngine::getTemplateIdFromProcessId($processID);
$taskTemplate = MaestroEngine::getTemplateTaskByID($templateMachineName, $queueRecord->task_id
->getString());
$template = MaestroEngine::getTemplate($templateMachineName);
$var_workflow_stage_count = intval(MaestroEngine::getProcessVariable('workflow_timeline_stage_count', $processID));
$build = MaestroStatus::getMaestroStatusBar($processID, $queueID, FALSE);
// Now determine if we should show the views attached.
$taskDetails = '';
$customInformation = '';
if (isset($template->show_details) && $template->show_details) {
// We provide an invokation here to allow other modules to inject their own
// custom information into the task display.
\Drupal::moduleHandler()
->invokeAll('maestro_task_console_custominformation_alter', [
&$customInformation,
$taskTemplate,
$queueRecord,
$templateMachineName,
]);
// Lets see if there's any views attached that we should be showing.
if (isset($template->views_attached)) {
foreach ($template->views_attached as $machine_name => $arr) {
$view = Views::getView($machine_name);
if ($view) {
$display = explode(';', $arr['view_display']);
$display_to_use = isset($display[0]) ? $display[0] : 'default';
$render_build = $view
->buildRenderable($display_to_use, [
$processID,
$queueID,
], FALSE);
if ($render_build) {
$thisViewOutput = \Drupal::service('renderer')
->render($render_build);
if ($thisViewOutput) {
$task_information_render_array = [
'#theme' => 'taskconsole_views',
'#task_information' => $thisViewOutput,
'#title' => $view->storage
->label(),
];
$taskDetails .= \Drupal::service('renderer')
->render($task_information_render_array);
}
}
}
}
}
// Anyone want to override the task details display?
\Drupal::moduleHandler()
->invokeAll('maestro_task_console_taskdetails_alter', [
&$taskDetails,
$taskTemplate,
$queueRecord,
$templateMachineName,
]);
$build['custom_information_bar'] = [
'#children' => '<div class="custom-information">' . $customInformation . '</div>',
];
$build['views_bar'] = [
'#children' => '<div class="maestro-task-details">' . $taskDetails . '</div>',
];
$replace['expand'] = [
'#attributes' => [
'class' => [
'maestro-timeline-status',
'maestro-status-toggle-up',
],
'title' => $this
->t('Close Details'),
],
'#type' => 'link',
'#id' => 'maestro-id-ajax-' . $queueID,
'#url' => Url::fromRoute('maestro_taskconsole.status_ajax_close', [
'processID' => $processID,
'queueID' => $queueID,
]),
'#title' => $this
->t('Close Details'),
'#ajax' => [
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
],
];
}
}
// We can target the ID of DIV within the table row associated to the expanded task's information as we're able to inject a DIV via the #prefix/#suffix
// However, we can only inject CSS as a #wrapper_attribute for the "link" and as such, we target the unique class wrapper TD element for the link for replacement.
$response = new AjaxResponse();
// Row.
$response
->addCommand(new HtmlCommand('#maestro-ajax-' . $queueID, $build));
// Wrapper attribute TD tag.
$response
->addCommand(new HtmlCommand('.maestro-status-toggle-' . $queueID . '', $replace['expand']));
$response
->addCommand(new CssCommand('#' . $queueID . '_ajax', [
'display' => 'table-row',
]));
return $response;
}
/**
* Internal method to close the project status.
*/
public function closeStatus($processID, $queueID) {
$build = [];
$build['expand'] = [
'#attributes' => [
'class' => [
'maestro-timeline-status',
'maestro-status-toggle',
],
'title' => $this
->t('Open Details'),
],
'#type' => 'link',
'#id' => 'maestro-id-ajax-' . $queueID,
'#url' => Url::fromRoute('maestro_taskconsole.status_ajax_open', [
'processID' => $processID,
'queueID' => $queueID,
]),
'#title' => $this
->t('Open Details'),
'#ajax' => [
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
],
];
$response = new AjaxResponse();
$response
->addCommand(new HtmlCommand('#maestro-ajax-' . $queueID, ''));
$response
->addCommand(new HtmlCommand('.maestro-status-toggle-' . $queueID, $build['expand']));
$response
->addCommand(new CssCommand('#' . $queueID . '_ajax', [
'display' => 'none',
]));
return $response;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ControllerBase:: |
protected | property | The configuration factory. | |
ControllerBase:: |
protected | property | The current user service. | 1 |
ControllerBase:: |
protected | property | The entity form builder. | |
ControllerBase:: |
protected | property | The entity type manager. | |
ControllerBase:: |
protected | property | The form builder. | 2 |
ControllerBase:: |
protected | property | The key-value storage. | 1 |
ControllerBase:: |
protected | property | The language manager. | 1 |
ControllerBase:: |
protected | property | The module handler. | 2 |
ControllerBase:: |
protected | property | The state service. | |
ControllerBase:: |
protected | function | Returns the requested cache bin. | |
ControllerBase:: |
protected | function | Retrieves a configuration object. | |
ControllerBase:: |
private | function | Returns the service container. | |
ControllerBase:: |
public static | function |
Instantiates a new instance of this class. Overrides ContainerInjectionInterface:: |
46 |
ControllerBase:: |
protected | function | Returns the current user. | 1 |
ControllerBase:: |
protected | function | Retrieves the entity form builder. | |
ControllerBase:: |
protected | function | Retrieves the entity type manager. | |
ControllerBase:: |
protected | function | Returns the form builder service. | 2 |
ControllerBase:: |
protected | function | Returns a key/value storage collection. | 1 |
ControllerBase:: |
protected | function | Returns the language manager service. | 1 |
ControllerBase:: |
protected | function | Returns the module handler. | 2 |
ControllerBase:: |
protected | function | Returns a redirect response object for the specified route. | |
ControllerBase:: |
protected | function | Returns the state storage service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MaestroTaskConsoleController:: |
public | function | Internal method to close the project status. | |
MaestroTaskConsoleController:: |
public | function | Method to fetch the status of a process. | |
MaestroTaskConsoleController:: |
public | function | GetTasks method This method is called by the menu router for /taskconsole. The output of this method is the current user's task console. | |
MessengerTrait:: |
protected | property | The messenger. | 27 |
MessengerTrait:: |
public | function | Gets the messenger. | 27 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
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. |