eliashaeussler / typo3-form-consent

🏁 Extension for TYPO3 CMS that adds double opt-in functionality to EXT:form

Home Page:https://docs.typo3.org/p/eliashaeussler/typo3-form-consent/main/en-us/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[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.