[FEATURE] Resend confirmation emails
sven513 opened this issue · comments
Is your feature request related to a problem?
Our SMTP account was temporarily blocked during a large contest, so a huge number (~1000) of our form entries did not receive an email with their confirmation link.
Is there a possibility to resend some emails from the form consent table?
Describe the solution you'd like
A new button in the list view: "Resend confirmation email" in the list view of the plugin.
Describe alternatives you've considered
We considered using a select query on the tx_formconsent_domain_model_consent table and triggering the mail function of the plugin. We just need to find this function ;)
Additional context
No response
Code of Conduct
- I agree to follow this project's Code of Conduct.
Hi @sven513, thanks for your issue. Unfortunately, this is not possible at the moment. I may add such functionality in the future, but it's currently not planned.
For the moment, you may have a look at https://github.com/eliashaeussler/typo3-form-consent/blob/0.7.1/Classes/Event/Listener/InvokeFinishersListener.php where a similar scenario is described: The original form is re-rendered with a concrete consent being applied. This is used to invoke finishers that were scheduled for execution in case a consent was approved or dismissed. You could copy some of the methods and adapt it to your needs (omit the search for appropriate conditions).
Something like this could work (untested):
<?php
declare(strict_types=1);
use EliasHaeussler\Typo3FormConsent\Domain\Model\Consent;
use EliasHaeussler\Typo3FormConsent\Domain\Repository\ConsentRepository;
use EliasHaeussler\Typo3FormConsent\Type\JsonType;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\Http\Response;
use TYPO3\CMS\Core\Http\ServerRequestFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Core\Bootstrap;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
final class ConsentMailDispatcher
{
public function __construct(
private readonly PageRepository $pageRepository,
private readonly ConsentRepository $consentRepository,
) {
}
public function resendConsentMail(int $consentUid): void
{
$consent = $this->consentRepository->findByUid($consentUid);
if ($consent !== null) {
$this->dispatchFormReRendering($consent);
}
}
private function dispatchFormReRendering(Consent $consent): void
{
// Early return if original request is missing
if (empty($consent->getOriginalRequestParameters()) || $consent->getOriginalContentElementUid() === 0) {
return;
}
// Recreate original request
$request = $this->createRequestFromOriginalRequestParameters($consent->getOriginalRequestParameters());
// Fetch record of original content element
$contentElementRecord = $this->fetchOriginalContentElementRecord($consent->getOriginalContentElementUid());
// Early return if content element record cannot be resolved
if (!\is_array($contentElementRecord)) {
return;
}
// Backup original server request object
$originalRequest = $GLOBALS['TYPO3_REQUEST'];
$GLOBALS['TYPO3_REQUEST'] = $request;
// Build extbase bootstrap object
$contentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
$contentObjectRenderer->start($contentElementRecord, 'tt_content'/**, $serverRequest */);
$contentObjectRenderer->setUserObjectType(ContentObjectRenderer::OBJECTTYPE_USER_INT);
$bootstrap = GeneralUtility::makeInstance(Bootstrap::class);
if (method_exists($bootstrap, 'setContentObjectRenderer')) {
$bootstrap->setContentObjectRenderer($contentObjectRenderer);
} else {
$bootstrap->cObj = $contentObjectRenderer;
}
$configuration = [
'extensionName' => 'Form',
'pluginName' => 'Formframework',
];
try {
// Dispatch extbase request
$content = $bootstrap->run('', $configuration/**, $serverRequest */);
$response = new Response();
$response->getBody()->write($content);
} finally {
// Restore original server request object
$GLOBALS['TYPO3_REQUEST'] = $originalRequest;
}
}
/**
* @return array<string, mixed>|null
*/
private function fetchOriginalContentElementRecord(int $contentElementUid): ?array
{
// Early return if content element UID cannot be determined
if ($contentElementUid === 0) {
return null;
}
// Fetch content element record
$record = $this->pageRepository->checkRecord('tt_content', $contentElementUid);
// Early return if content element record cannot be resolved
if (!\is_array($record)) {
return null;
}
return $this->pageRepository->getLanguageOverlay('tt_content', $record);
}
/**
* @param JsonType<string, array<string, array<string, mixed>>> $originalRequestParameters
*/
private function createRequestFromOriginalRequestParameters(JsonType $originalRequestParameters): ServerRequestInterface
{
return $this->getServerRequest()
->withMethod('POST')
->withParsedBody($originalRequestParameters->toArray());
}
private function getServerRequest(): ServerRequestInterface
{
return $GLOBALS['TYPO3_REQUEST'] ?? ServerRequestFactory::fromGlobals();
}
}
Now, just pass the consent uid to ConsentMailDispatcher::resendConsentMail()
.
Closing as not planned. Maybe I'll come back later with an implementation.