wse-1.0.x-dev/src/WseWorkspaceManager.php
src/WseWorkspaceManager.php
<?php
namespace Drupal\wse;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\workspaces\WorkspaceInterface;
use Drupal\workspaces\WorkspaceManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Provides a workspace manager service override.
*/
class WseWorkspaceManager implements WorkspaceManagerInterface {
public function __construct(
protected WorkspaceManagerInterface $inner,
protected RequestStack $requestStack,
protected PrivateTempStoreFactory $tempStoreFactory,
protected TimeInterface $time,
protected StateInterface $state,
) {}
/**
* {@inheritdoc}
*/
public function isEntityTypeSupported(EntityTypeInterface $entity_type) {
return $this->inner->isEntityTypeSupported($entity_type);
}
/**
* {@inheritdoc}
*/
public function getSupportedEntityTypes() {
return $this->inner->getSupportedEntityTypes();
}
/**
* {@inheritdoc}
*/
public function hasActiveWorkspace() {
$request = $this->requestStack->getCurrentRequest();
if ($request && $request->request->has('wse_bypass_workspace')) {
return FALSE;
}
return $this->getActiveWorkspace() !== FALSE;
}
/**
* {@inheritdoc}
*/
public function getActiveWorkspace() {
$request = $this->requestStack->getCurrentRequest();
// When there is no request in the stack, return early and allow following
// calls to try and determine the active workspace.
if (!$request) {
return FALSE;
}
if ($request && $request->request->has('wse_bypass_workspace')) {
return FALSE;
}
// Don't allow closed workspaces to be activated.
$negotiated_workspace = $this->inner->getActiveWorkspace();
if ($negotiated_workspace instanceof WorkspaceInterface && wse_workspace_get_status($negotiated_workspace) == WSE_STATUS_CLOSED) {
return FALSE;
}
return $negotiated_workspace;
}
/**
* {@inheritdoc}
*/
public function setActiveWorkspace(WorkspaceInterface $workspace) {
$return = $this->inner->setActiveWorkspace($workspace);
// Record that we have activated this workspace.
$temp_store = $this->tempStoreFactory->get('wse');
$recent_workspaces = $temp_store->get('recent_workspaces') ?: [];
$recent_workspaces[$workspace->id()] = $this->time->getRequestTime();
$temp_store->set('recent_workspaces', $recent_workspaces);
$this->removeWorkspaceQueryParam();
return $return;
}
/**
* {@inheritdoc}
*/
public function switchToLive() {
$this->removeWorkspaceQueryParam();
return $this->inner->switchToLive();
}
/**
* Removes any trace of the current workspace from the query parameters.
*/
private function removeWorkspaceQueryParam() {
// When switching workspaces, ensure that there's no workspace query
// parameter, either standalone or in the destination.
$request = $this->requestStack->getCurrentRequest();
$request->query->remove('workspace');
$query_params = $request->query->all();
if (isset($query_params['destination'])) {
$destination = UrlHelper::parse($query_params['destination']);
unset($destination['query']['workspace']);
$new_destination = $destination['path'] . ($destination['query'] ? ('?' . UrlHelper::buildQuery($destination['query'])) : '');
$request->query->set('destination', $new_destination);
}
}
/**
* {@inheritdoc}
*/
public function executeInWorkspace($workspace_id, callable $function) {
return $this->inner->executeInWorkspace($workspace_id, $function);
}
/**
* {@inheritdoc}
*/
public function executeOutsideWorkspace(callable $function) {
return $this->inner->executeOutsideWorkspace($function);
}
/**
* {@inheritdoc}
*/
public function shouldAlterOperations(EntityTypeInterface $entity_type) {
return $this->inner->shouldAlterOperations($entity_type);
}
/**
* {@inheritdoc}
*/
public function purgeDeletedWorkspacesBatch(): void {
// Ensure that we don't try to clean up revisions for closed workspaces that
// have been deleted.
$deleted_workspace_ids = $this->state->get('workspace.deleted', []);
$deleted_closed_workspace_ids = $this->state->get('wse.deleted_closed', []);
$deleted_open_workspace_ids = array_diff_key($deleted_workspace_ids, $deleted_closed_workspace_ids);
if (array_diff_key($deleted_workspace_ids, $deleted_open_workspace_ids)) {
$this->state->set('workspace.deleted', $deleted_open_workspace_ids);
}
if ($deleted_closed_workspace_ids) {
$this->state->set('wse.deleted_closed', []);
}
$this->inner->purgeDeletedWorkspacesBatch();
}
}
