Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Less flickering #94

Merged
merged 3 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 5 additions & 68 deletions Classes/Controller/ConditionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,20 @@

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 In2code\PowermailCond\Service\ConditionService;
use function json_encode;
use const JSON_THROW_ON_ERROR;
use Psr\Http\Message\ResponseInterface;
use Throwable;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

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

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
public function injectConditionService(ConditionService $conditionService): void
{
$this->conditionContainerRepository = $conditionContainerRepository;
$this->conditionService = $conditionService;
}

/**
Expand All @@ -52,47 +28,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/Private/Build/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Small guide

* Go to Recources/Private/Build
* Go to Resources/Private/Build
* `nvm use` will change to needed npm version
* `npm i` will install the node modules (if not yet installed)
* Then start with `npm run build` or the watch task with `npm run watch`
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
Loading