Skip to content

Commit

Permalink
[TASK] Implement way to reduce initial flickering
Browse files Browse the repository at this point in the history
  • Loading branch information
kitzberger committed Sep 26, 2024
1 parent b458f7b commit ac2d2e5
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 72 deletions.
78 changes: 8 additions & 70 deletions Classes/Controller/ConditionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,21 @@

namespace In2code\PowermailCond\Controller;

use function array_key_exists;
use In2code\Powermail\Domain\Model\Field;
use In2code\Powermail\Domain\Model\Form;
use In2code\Powermail\Domain\Model\Page;
use In2code\Powermail\Domain\Repository\FormRepository;
use In2code\PowermailCond\Domain\Repository\ConditionContainerRepository;
use In2code\PowermailCond\Exception\MissingPowermailParameterException;
use In2code\PowermailCond\Exception\UnsupportedVariableTypeException;
use function is_array;
use function is_string;
use function json_encode;
use const JSON_THROW_ON_ERROR;
use In2code\PowermailCond\Service\ConditionService;
use Psr\Http\Message\ResponseInterface;
use Throwable;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

use const JSON_THROW_ON_ERROR;
use function json_encode;

class ConditionController extends ActionController
{
protected FormRepository $formRepository;
protected ConditionService $conditionService;

protected ConditionContainerRepository $conditionContainerRepository;

protected TypoScriptFrontendController $typoscriptFrontendController;

public function __construct()
public function injectConditionService(ConditionService $conditionService): void
{
$this->typoscriptFrontendController = $GLOBALS['TSFE'];
}

public function injectFormRepository(FormRepository $formRepository): void
{
$this->formRepository = $formRepository;
}

public function injectConditionContainerRepository(ConditionContainerRepository $conditionContainerRepository): void
{
$this->conditionContainerRepository = $conditionContainerRepository;
$this->conditionService = $conditionService;
}

/**
Expand All @@ -52,47 +29,8 @@ public function injectConditionContainerRepository(ConditionContainerRepository
public function buildConditionAction(): ResponseInterface
{
$requestBody = $this->request->getParsedBody();
if (empty($requestBody['tx_powermail_pi1']['mail']['form'])) {
throw new MissingPowermailParameterException();
}
$powermailArguments = $requestBody['tx_powermail_pi1'];
unset($powermailArguments['__referrer'], $powermailArguments['__trustedProperties']);

/** @var Form $form */
$form = $this->formRepository->findByIdentifier($powermailArguments['mail']['form']);

/** @var array<string, Field> $fields */
$fields = [];

/** @var Page $page */
foreach ($form->getPages() as $page) {
/** @var Field $field */
foreach ($page->getFields() as $field) {
$fields[$field->getMarker()] = $field;
}
}

foreach ($powermailArguments['field'] as $fieldName => $fieldValue) {
if (!array_key_exists($fieldName, $fields)) {
continue;
}
if (is_array($fieldValue)) {
$fieldValue = json_encode($fieldValue, JSON_THROW_ON_ERROR);
}
if (!is_string($fieldValue)) {
throw new UnsupportedVariableTypeException();
}
$fields[$fieldName]->setText($fieldValue);
}

$arguments = [];
// Use the forms non-localized UID, because the field is l10n_mode exclude
$conditionContainer = $this->conditionContainerRepository->findOneByForm($form->getUid());
if ($conditionContainer !== null) {
$arguments = $conditionContainer->applyConditions($form, $powermailArguments);
$this->typoscriptFrontendController->fe_user->setAndSaveSessionData('tx_powermail_cond', $arguments);
unset($arguments['backup'], $arguments['field']);
}
$arguments = $this->conditionService->getArguments($requestBody['tx_powermail_pi1']);

return $this->jsonResponse(json_encode($arguments, JSON_THROW_ON_ERROR));
}
Expand Down
81 changes: 81 additions & 0 deletions Classes/Service/ConditionService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

declare(strict_types=1);

namespace In2code\PowermailCond\Service;

use In2code\Powermail\Domain\Repository\FormRepository;
use In2code\PowermailCond\Domain\Repository\ConditionContainerRepository;
use In2code\PowermailCond\Exception\MissingPowermailParameterException;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

class ConditionService
{
protected FormRepository $formRepository;

protected ConditionContainerRepository $conditionContainerRepository;

protected TypoScriptFrontendController $typoscriptFrontendController;

public function __construct()
{
$this->typoscriptFrontendController = $GLOBALS['TSFE'];
}

public function injectFormRepository(FormRepository $formRepository): void
{
$this->formRepository = $formRepository;
}

public function injectConditionContainerRepository(ConditionContainerRepository $conditionContainerRepository): void
{
$this->conditionContainerRepository = $conditionContainerRepository;
}

public function getArguments(array $powermailArguments = []): array
{
if (empty($powermailArguments['mail']['form'])) {
throw new MissingPowermailParameterException();
}

unset($powermailArguments['__referrer'], $powermailArguments['__trustedProperties']);

/** @var Form $form */
$form = $this->formRepository->findByIdentifier($powermailArguments['mail']['form']);

/** @var array<string, Field> $fields */
$fields = [];

/** @var Page $page */
foreach ($form->getPages() as $page) {
/** @var Field $field */
foreach ($page->getFields() as $field) {
$fields[$field->getMarker()] = $field;
}
}

foreach ($powermailArguments['field'] ?? [] as $fieldName => $fieldValue) {
if (!array_key_exists($fieldName, $fields)) {
continue;
}
if (is_array($fieldValue)) {
$fieldValue = json_encode($fieldValue, JSON_THROW_ON_ERROR);
}
if (!is_string($fieldValue)) {
throw new UnsupportedVariableTypeException();
}
$fields[$fieldName]->setText($fieldValue);
}

$arguments = [];
// Use the forms non-localized UID, because the field is l10n_mode exclude
$conditionContainer = $this->conditionContainerRepository->findOneByForm($form->getUid());
if ($conditionContainer !== null) {
$arguments = $conditionContainer->applyConditions($form, $powermailArguments);
$this->typoscriptFrontendController->fe_user->setAndSaveSessionData('tx_powermail_cond', $arguments);
unset($arguments['backup'], $arguments['field']);
}

return $arguments;
}
}
49 changes: 49 additions & 0 deletions Classes/ViewHelpers/ConditionsViewHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace In2code\PowermailCond\ViewHelpers;

use In2code\Powermail\Domain\Model\Form;
use In2code\PowermailCond\Service\ConditionService;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;

/**
* Class ConditionsViewHelper
*/
class ConditionsViewHelper extends AbstractViewHelper
{
protected ConditionService $conditionService;

public function injectConditionService(ConditionService $conditionService): void
{
$this->conditionService = $conditionService;
}

public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('form', Form::class, 'Form', true);
}

/**
* Returns Data Attribute Array to enable validation
*
* @return string
*/
public function render(): string
{
/** @var Form $field */
$form = $this->arguments['form'];

if ($this->renderingContext->getRequest()->getParsedBody()) {
$params = $this->renderingContext->getRequest()->getParsedBody()['tx_powermail_pi1'];
} else {
$params = ['mail' => ['form' => $form->getUid()]];
}

$arguments = $this->conditionService->getArguments($params);

return json_encode($arguments, JSON_THROW_ON_ERROR);
}
}
22 changes: 21 additions & 1 deletion Resources/Private/Build/JavaScript/PowermailConditions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,19 @@ class PowermailConditions {

initialize = function () {
const that = this;
that.#sendFormValuesToPowermailCond();

let formUid = this.#form.querySelector('input.powermail_form_uid').value;
let formActionSelector = '#form-' + formUid + '-actions';

if (document.querySelector(formActionSelector) === null) {
// Loading conditions via AJAX
that.#sendFormValuesToPowermailCond();
} else {
// Using prerendered conditions
let actions = JSON.parse(document.querySelector(formActionSelector).textContent);
that.#processActions(actions);
}

that.#fieldListener();
}

Expand Down Expand Up @@ -72,6 +84,14 @@ class PowermailConditions {
}
}
}
let fieldsets = this.#form.querySelectorAll('.powermail_fieldset');
fieldsets.forEach(function(fieldset) {
if (window.getComputedStyle(fieldset).visibility === 'hidden') {
// Making initially invisible fieldset visible
fieldset.style.visibility = 'visible';
fieldset.style.opacity = 1;
}
});
};

#enableAllFields() {
Expand Down
2 changes: 1 addition & 1 deletion Resources/Public/JavaScript/PowermailCondition.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ac2d2e5

Please sign in to comment.