headless_cms-1.0.3/modules/headless_cms_preview/src/PreviewToken/PreviewTokenManager.php
modules/headless_cms_preview/src/PreviewToken/PreviewTokenManager.php
<?php
declare(strict_types=1);
namespace Drupal\headless_cms_preview\PreviewToken;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\encrypt\EncryptServiceInterface;
use Drupal\encrypt\EncryptionProfileInterface;
use Drupal\encrypt\EncryptionProfileManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
/**
* Manage preview tokens.
*/
class PreviewTokenManager implements PreviewTokenManagerInterface {
public function __construct(
protected readonly EntityTypeManagerInterface $entityTypeManager,
protected readonly ConfigFactoryInterface $configFactory,
#[Autowire('@logger.channel.headless_cms_preview')]
protected readonly LoggerInterface $logger,
protected ?EncryptServiceInterface $encrypt = NULL,
protected ?EncryptionProfileManagerInterface $encryptionProfileManager = NULL,
) {}
/**
* Set the encrypt service.
*/
public function setEncrypt(EncryptServiceInterface $encrypt) {
$this->encrypt = $encrypt;
}
/**
* Set the encryption profile manager.
*/
public function setEncryptionProfileManager(EncryptionProfileManagerInterface $encryptionProfileManager) {
$this->encryptionProfileManager = $encryptionProfileManager;
}
/**
* {@inheritdoc}
*/
public function encode(string $ownerUid, string $entityUuid, string $entityTypeId, string $entityBundleId): string {
$rawValue = sprintf('%s:%s:%s:%s', $ownerUid, $entityUuid, $entityTypeId, $entityBundleId);
$encodedValue = base64_encode($rawValue);
// Encrypt the value if a profile is set.
if ($encryptionProfile = $this->getEncryptionProfile()) {
return $this->encrypt->encrypt($rawValue, $encryptionProfile);
}
return $encodedValue;
}
/**
* {@inheritdoc}
*/
public function decode(string $tokenValue): ?PreviewToken {
try {
if ($encryptionProfile = $this->getEncryptionProfile()) {
$rawValue = $this->encrypt->decrypt($tokenValue, $encryptionProfile);
}
else {
$rawValue = base64_decode($tokenValue);
}
@[$ownerUid, $entityUuid, $entityTypeId, $entityBundleId] = explode(':', $rawValue);
if (!$entityUuid || !$ownerUid || !$entityTypeId || !$entityBundleId) {
return NULL;
}
$result = $this->entityTypeManager->getStorage($entityTypeId)->loadByProperties([
'uuid' => $entityUuid,
]);
$entity = reset($result) ?: NULL;
return new PreviewToken($ownerUid, $entityUuid, $entity?->id(), $entityTypeId, $entityBundleId);
}
catch (\Exception $e) {
$this->logger->error('Could not decrypt/decode the headless cms preview token: @message', [
'@message' => $e->getMessage(),
]);
return NULL;
}
}
/**
* Get the set encryption profile.
*
* If NULL, no encryption is used.
*/
protected function getEncryptionProfile(): ?EncryptionProfileInterface {
if (!$this->encrypt || !$this->encryptionProfileManager) {
return NULL;
}
$profileId = $this->configFactory->get('headless_cms_preview.settings')->get('encryption_profile');
if (!$profileId) {
return NULL;
}
return $this->encryptionProfileManager->getEncryptionProfile($profileId);
}
}
