niobi-8.x-2.0-alpha4/modules/niobi_form/modules/niobi_app/src/Controller/NiobiAppController.php
modules/niobi_form/modules/niobi_app/src/Controller/NiobiAppController.php
<?php
namespace Drupal\niobi_app\Controller;
use Drupal\contextual_reports\ContextualReportsUtilities;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\niobi_app\Entity\NiobiApplicationReviewerPool;
use Drupal\niobi_app\Entity\NiobiApplicationWorkflow;
use Drupal\niobi_app\Entity\NiobiApplicationWorkflowInterface;
use Drupal\niobi_app\Entity\NiobiApplication;
use Drupal\niobi_app\Entity\NiobiApplicationInterface;
use Drupal\niobi_app\Plugin\task\Bundle\ApplicationReviewTask;
use Drupal\niobi_app\Utilities\NiobiAppPromoteUtilities;
use Drupal\task\Entity\Task;
use Drupal\task\Entity\TaskInterface;
use Drupal\task\TaskUtilities;
use Drupal\niobi_app\Plugin\task\Action\DeclineReview;
use Drupal\niobi_app\Plugin\task\Action\DismissAsConflict;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Access\AccessResult;
/**
* Provides the route controller for niobi_group.
*
*/
class NiobiAppController extends ControllerBase {
/**
* @return RedirectResponse
*/
public function redirectToPrevious() {
// Return to where we came from
$server = Request::createFromGlobals()->server;
$return = $server->get('HTTP_REFERER');
$http = $server->get('HTTPS') ? 'https://' : 'http://';
$domain = $http . $server->get('SERVER_NAME');
$port = ':' . $server->get('SERVER_PORT');
$return = str_replace($domain, '', $return);
$return = str_replace($port, '', $return);
$url = Url::fromUserInput($return ? $return : '/');
$response = new RedirectResponse($url->toString());
$request = \Drupal::request();
// Save the session so things like messages get saved.
$request->getSession()->save();
$response->prepare($request);
return $response;
}
/**
* @param NiobiApplicationWorkflow $niobi_application_workflow
* @return array
*/
public function launchChecklists($niobi_application_workflow) {
return ['#type' => 'markup', '#markup' => ''];
}
/**
* @param NiobiApplicationWorkflow $niobi_application_workflow
* @return array
*/
public function applicationWorkflowReports($niobi_application_workflow) {
$custom_links = $niobi_application_workflow->get('field_custom_reports')->getValue();
if (!empty($custom_links)) {
$links = [
'#theme' => 'item_list',
'#items' => []
];
foreach ($custom_links as $l) {
$url = Url::fromUri($l['uri'], $l['options']);
$link = Link::fromTextAndUrl($l['title'], $url);
$links['#items'][] = $link;
}
return [
'header' => [
'#type' => 'html_tag',
'#tag' => 'h2',
'#value' => $this->t('Custom reports'),
'#attributes' => [
'class' => ['niobi-app-custom-reports']
]
],
'links' => $links,
];
}
else {
return ['#type' => 'markup', '#markup' => ''];
}
}
/**
* @param $niobi_application_workflow
* @return array
*/
public function applicationWorkflowReportReviewScores($niobi_application_workflow) {
return [
'#type' => 'view',
'#name' => 'niobi_application_review_scores',
'#display_id' => 'block_1',
'#arguments' => [
'niobi_application_workflow' => $niobi_application_workflow->id(),
],
];
}
/**
* @param $niobi_application_workflow
* @return array
*/
public function applicationWorkflowReportApplicationStatistics($niobi_application_workflow) {
$params['application_workflow'] = $niobi_application_workflow->id();
return ContextualReportsUtilities::generateReport('apm_app_application_submissions', 'apm_app_workflow_submissions','niobi_app_app_stats', $params);
}
/**
* @param NiobiApplicationWorkflow $niobi_application_workflow
* @return array
*/
public function manageWorkflow($niobi_application_workflow) {
return ['#type' => 'markup', '#markup' => ''];
}
/**
* @param NiobiApplicationWorkflow $niobi_application_workflow
* @return array
*/
public function launchChecklistsEmailTemplates($niobi_application_workflow) {
return [
'#type' => 'view',
'#name' => 'niobi_applications_email_templates',
'#display_id' => 'block_1',
'#arguments' => [
'niobi_application_workflow' => $niobi_application_workflow->id(),
],
];
}
/**
* @param $niobi_application_workflow
*
* @return array
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function manageUserReviewAssignments($niobi_application_workflow) {
$reviews = [];
$uid = \Drupal::currentUser()->id();
$applications = \Drupal::entityTypeManager()->getStorage('niobi_application')
->loadByProperties(['field_application_workflow' => $niobi_application_workflow->id()]);
$query = \Drupal::entityQuery('task')
->condition('type', 'application_review_task')
->condition('assigned_to', $uid)
->condition('field_application', array_keys($applications), 'IN')
->condition('status', 'closed', '!=')
->sort('created', 'DESC');
$tasks = Task::loadMultiple($query->execute());
foreach ($tasks as $task) {
$application = $applications[$task->field_application->target_id];
$review = [
'application' => $application,
'task' => $task,
'status' => ApplicationReviewTask::getReviewTaskStatus($task, $application),
'taskOptions' => TaskUtilities::getTaskOptions($task)
];
$reviews[] = $review;
}
return [
'#theme' => 'niobi_review_assignments',
'#reviews' => $reviews,
// disable caching
'#cache' => [
'max-age' => 0,
],
];
}
/**
* @param NiobiApplicationWorkflow $niobi_application_workflow
* @return array
*/
public function manageReviews($niobi_application_workflow) {
return [
'#type' => 'view',
'#name' => 'niobi_application_manage_reviews',
'#display_id' => 'block_1',
'#arguments' => [
'niobi_application_workflow' => $niobi_application_workflow->id(),
],
];
}
/**
* @param NiobiApplicationWorkflow $niobi_application_workflow
* @return array
*/
public function manageWorkflowStages($niobi_application_workflow) {
return [
'#type' => 'view',
'#name' => 'niobi_applications_application_manager',
'#display_id' => 'block_1',
'#arguments' => [
'niobi_application_workflow' => $niobi_application_workflow->id(),
],
];
}
/**
* @param NiobiApplicationWorkflow $application_workflow
* @param string $status
* @return \Drupal\Core\Entity\EntityInterface|NiobiApplication
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function createApplicationEntity(NiobiApplicationWorkflow $application_workflow, $status = 'application') {
$data = [
'user_id' => \Drupal::currentUser()->id(),
'name' => \Drupal::currentUser()->getAccountName() . ' - ' . $application_workflow->label(),
'field_application_status' => $status,
'field_application_workflow' => $application_workflow->id(),
'field_current_stage' => $application_workflow->getFirstStage()->id(),
];
$application = NiobiApplication::create($data);
$application->save();
return $application;
}
/**
* @param NiobiApplicationWorkflow $niobi_application_workflow
* @return RedirectResponse
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function createApplication(NiobiApplicationWorkflow $niobi_application_workflow) {
$application = $this->createApplicationEntity($niobi_application_workflow, 'application');
$application_form = $niobi_application_workflow->getFirstStage()->getApplicationForm();
$params = [
'niobi_form' => $application_form->id()
];
$options = [
'query' => [
'application_id' => $application->get('uuid')->value,
]
];
$url = Url::fromRoute('entity.niobi_form.canonical', $params, $options);
$response = new RedirectResponse($url->toString());
return $response;
}
/**
* @param NiobiApplicationWorkflow $niobi_application_workflow
* @return RedirectResponse
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function createNomination(NiobiApplicationWorkflow $niobi_application_workflow) {
$nomination = $this->createApplicationEntity($niobi_application_workflow, 'nomination');
$nomination_form = $niobi_application_workflow->getFirstStage()->getNominationForm();
$params = [
'niobi_form' => $nomination_form->id()
];
$options = [
'query' => [
'application_id' => $nomination->get('uuid')->value,
]
];
$url = Url::fromRoute('entity.niobi_form.canonical', $params, $options);
$response = new RedirectResponse($url->toString());
return $response;
}
/**
* @param $uuid
* @return array|\Drupal\Core\Access\AccessResultForbidden|RedirectResponse
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function acceptNomination($uuid) {
$check = FALSE;
if (is_string($uuid) && (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/', $uuid) === 1)) {
$check = TRUE;
}
if ($check) {
$a = \Drupal::entityTypeManager()->getStorage('niobi_application')->loadByProperties(['uuid' => $uuid]);
$id = array_keys($a)[0];
if ($id) {
if (\Drupal::currentUser()->isAnonymous()) {
$params = ['destination' => Url::fromRoute('niobi_application.accept_nomination', ['uuid' => $uuid])->getInternalPath()];
$url = Url::fromRoute('user.login',[],$params);
$response = new RedirectResponse($url->toString());
return $response;
}
// User is logged in. Determine if they have access.
if (\Drupal::currentUser()->hasPermission('edit niobi application entities')) {
$application = NiobiApplication::load($id);
$workflow = $application->getApplicationWorkflow();
$application->set('field_application_status', 'application');
$application->set('user_id', \Drupal::currentUser()->id());
$application->save();
$params = [
'niobi_application_workflow' => $workflow->id()
];
$url = Url::fromRoute('entity.niobi_application_workflow.canonical', $params);
$response = new RedirectResponse($url->toString());
return $response;
}
else {
return AccessResult::forbidden();
}
}
}
// If we didn't get the redirect, return an error message.
return ['#type' => 'markup' , '#markup' => '<h2>Invalid Application Code</h2>'];
}
/**
* @param $uuid
* @return array|RedirectResponse
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function declineNomination($uuid) {
$check = FALSE;
if (is_string($uuid) && (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/', $uuid) === 1)) {
$check = TRUE;
}
if ($check) {
$a = \Drupal::entityTypeManager()->getStorage('niobi_application')->loadByProperties(['uuid' => $uuid]);
$id = array_keys($a)[0];
if ($id) {
$application = NiobiApplication::load($id);
$workflow = $application->getApplicationWorkflow();
$application->set('field_application_status', 'complete');
$application->save();
$params = [
'niobi_application_workflow' => $workflow->id()
];
$url = Url::fromRoute('entity.niobi_application_workflow.canonical', $params);
$response = new RedirectResponse($url->toString());
return $response;
}
}
// If we didn't get the redirect, return an error message.
return ['#type' => 'markup' , '#markup' => '<h2>Invalid Application Code</h2>'];
}
/**
* @param NiobiApplicationWorkflowInterface $niobi_application_workflow
* @param NiobiApplicationInterface $niobi_application
* @return RedirectResponse
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function submitNomination(NiobiApplicationWorkflowInterface $niobi_application_workflow, NiobiApplicationInterface $niobi_application) {
$niobi_application->set('field_application_status', 'nomination_claim');
$niobi_application->save();
$params = [
'niobi_application_workflow' => $niobi_application_workflow->id()
];
$url = Url::fromRoute('entity.niobi_application_workflow.canonical', $params);
$response = new RedirectResponse($url->toString());
return $response;
}
/**
* Submit an application for review
* @param NiobiApplicationWorkflowInterface $niobi_application_workflow
* @param NiobiApplicationInterface $niobi_application
* @return RedirectResponse
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function submitApplication(NiobiApplicationWorkflowInterface $niobi_application_workflow, NiobiApplicationInterface $niobi_application) {
NiobiAppPromoteUtilities::submitApplication($niobi_application);
// Redirect to application dashboard.
$params = [
'niobi_application_workflow' => $niobi_application_workflow->id()
];
$url = Url::fromRoute('entity.niobi_application_workflow.canonical', $params);
$response = new RedirectResponse($url->toString());
return $response;
}
public static function runAutoAssignment(NiobiApplication $niobi_application) {
// Run auto-assignments.
$stage = $niobi_application->getCurrentApplicationStage();
$auto_assign_info = $stage->getReviewAutoAssignmentInfo($niobi_application);
if ($auto_assign_info) {
// If there is no maximum, assign to everyone.
if (!$auto_assign_info['max'] || $auto_assign_info['pool_count'] <= $auto_assign_info['max']) {
$reviewers = $auto_assign_info['pool']->getAutoAssignmentReviewers($niobi_application, $stage);
foreach ($reviewers as $id => $reviewer) {
// Get data for application owner
$label_info = [
'@reviewer' => $reviewer->label(),
'@app' => $niobi_application->label(),
];
$data = [
'type' => 'application_review_task',
'status' => 'active',
'name' => t('Assign @reviewer to @app', $label_info),
'assigned_by_type' => 'system',
'assigned_by' => '0',
'assigned_to' => $id,
'assigned_to_type' => 'user',
'field_application' => $niobi_application->id(),
'field_review_form' => $auto_assign_info['form']->id(),
];
TaskUtilities::createTask($data);
}
}
}
}
/**
* @param TaskInterface $task
* @return \Drupal\Core\Access\AccessResultForbidden|RedirectResponse
*/
public function DeclineReviewAssignment(TaskInterface $task) {
$assignee = $task->get('assigned_to')->getValue();
if (isset($assignee[0]['target_id'])) {
DeclineReview::doAction($task);
return $this->redirectToPrevious();
}
else {
\Drupal::messenger()->addError('This review assignment was already dismissed, or has missing information.');
return $this->redirectToPrevious();
}
}
/**
* @param TaskInterface $task
* @return \Drupal\Core\Access\AccessResultForbidden|RedirectResponse
*/
public function DeclineReviewAssignmentAndMarkCOI(TaskInterface $task) {
$assignee = $task->get('assigned_to')->getValue();
if (isset($assignee[0]['target_id'])) {
DismissAsConflict::doAction($task);
return $this->redirectToPrevious();
}
else {
\Drupal::messenger()->addError('This review assignment was already dismissed, or has missing information.');
return $this->redirectToPrevious();
}
}
/**
* @param NiobiApplicationInterface $niobi_application
* @return RedirectResponse
*/
public function moveToDecision(NiobiApplicationInterface $niobi_application) {
NiobiAppPromoteUtilities::moveToDecision($niobi_application);
return $this->redirectToPrevious();
}
/**
* @param $uuid
* @return array
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function joinReviewerPool($uuid) {
$check = FALSE;
if (is_string($uuid) && (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/', $uuid) === 1)) {
$check = TRUE;
}
if ($check) {
$a = \Drupal::entityTypeManager()->getStorage('niobi_application_reviewer_pool')->loadByProperties(['uuid' => $uuid]);
$id = array_shift(array_keys($a));
if ($id) {
$pool = NiobiApplicationReviewerPool::load($id);
$account = \Drupal::currentUser();
// The access checks were done in the route.
// We filter out Anonymous as that count is not compatible with the review system.
if (!$account->isAnonymous()) {
$reviewers = array_keys($pool->getReviewers());
$reviewers = array_merge($reviewers, [$account->id()]);
$reviewers = array_unique($reviewers);
$pool->set('field_reviewers', $reviewers);
$pool->save();
$message = $this->t('You have been added to the %t reviewer pool.', ['%t' => $pool->label()]);
$ret = [
'message' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $message
],
'home' => Link::fromTextAndUrl('Return to Home', Url::fromUserInput('/'))->toRenderable(),
];
return $ret;
}
}
$message = $this->t('No reviewer pool was found for the given ID.');
return ['#markup' => $message];
}
}
}
