You can use hook_entity_operation
to add a custom entity operation for webform submissions. With the Webform Views Integration module you should already be able to add an "Operations" field to your view. It lists the default operations depending on access levels (Edit, Delete etc.). There your custom operation will appear.
MYMODULE.module
<?php
/**
* @file
* Hooks implemented by the MYMODULE module.
*/
use Drupal\Core\Entity\EntityInterface;
use Drupal\webform\WebformSubmissionInterface;
/**
* Implements hook_entity_operation().
*/
function MYMODULE_entity_operation(EntityInterface $submission) {
$operations = [];
if ($submission instanceof WebformSubmissionInterface) {
if ($submission->getElementData('MY_HIDDEN_REVIEW_ELEMENT') !== 'approved') {
$operations['approve'] = [
'title' => t('Approve'),
'weight' => 15,
'url' => Url::fromRoute('MYMODULE.webform_submission_approve', [
'submission' => $submission->id(),
], [
'query' => \Drupal::destination()->getAsArray(),
]),
];
}
}
return $operations;
}
MYMODULE.routing.yml
MYMODULE.webform_submission_approve:
path: '/admin/MYMODULE/submission/{submission}/approve'
defaults:
_controller: '\Drupal\MYMODULE\Controller\WebformSubmissionApproveController::approve'
options:
parameters:
submission:
type: 'entity:webform_submission'
requirements:
_custom_access: '\Drupal\MYMODULE\Controller\WebformSubmissionApproveController::access'
src/Controller/WebformSubmissionApproveController.php
<?php
namespace Drupal\MYMODULE\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Controller\ControllerBase;
use Drupal\webform\Entity\WebformSubmission;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
/**
* Class WebformSubmissionApproveController.
*
* @package Drupal\MYMODULE\Controller
*/
class WebformSubmissionApproveController extends ControllerBase {
/**
* Approve method.
*
* @param \Drupal\webform\Entity\WebformSubmission $submission
* A webform submission.
* @param \Symfony\Component\HttpFoundation\Request $request
* The current HTTP request.
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
* The response.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function approve(WebformSubmission $submission, Request $request) {
$submission->setElementData('MY_HIDDEN_REVIEW_ELEMENT', 'approved');
$submission->save();
$this->messenger()->addMessage($this->t('Submission @serial approved.', [
'@serial' => $submission->serial(),
]));
return $request->query->get('destination') ? new RedirectResponse($request->query->get('destination')) : [];
}
/**
* Checks access for a specific request.
*
* @return \Drupal\Core\Access\AccessResult
* The access result.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function access(WebformSubmission $submission) {
return AccessResult::allowedIf(!$submission->isDraft() && in_array('administrator', $this->currentUser()->getRoles()));
}
}