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

[BUGFIX] Fixes errors that occur when the same form is used multiple times on the same page #247

Closed
wants to merge 1 commit into from
Closed
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
62 changes: 60 additions & 2 deletions Classes/Controller/FormController.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function formAction()
$this->view->assignMultiple(
[
'form' => $form,
'ttContentData' => $this->contentObject->data,
'ttContentData' => $this->getCurrentContentObjectData(),
'messageClass' => $this->messageClass,
'action' => ($this->settings['main']['confirmation'] ? 'confirmation' : 'create')
]
Expand All @@ -63,6 +63,7 @@ public function formAction()
*/
public function initializeCreateAction()
{
$this->forwardIfTtContentUidDoesNotMatch();
$this->forwardIfFormParamsDoNotMatch();
$this->forwardIfMailParamEmpty();
$this->reformatParamsForAction();
Expand Down Expand Up @@ -134,6 +135,7 @@ public function createAction(Mail $mail, string $hash = null)
*/
public function initializeConfirmationAction()
{
$this->forwardIfTtContentUidDoesNotMatch();
$this->forwardIfFormParamsDoNotMatch();
$this->forwardIfMailParamEmpty();
$this->reformatParamsForAction();
Expand Down Expand Up @@ -216,7 +218,7 @@ protected function prepareOutput(Mail $mail)
'mail' => $mail,
'marketingInfos' => SessionUtility::getMarketingInfos(),
'messageClass' => $this->messageClass,
'ttContentData' => $this->contentObject->data,
'ttContentData' => $this->getCurrentContentObjectData(),
'uploadService' => $this->uploadService,
'powermail_rte' => $this->settings['thx']['body'],
'powermail_all' => TemplateUtility::powermailAll($mail, 'web', $this->settings, $this->actionMethodName)
Expand Down Expand Up @@ -313,13 +315,33 @@ public function initializeAction()
{
parent::initializeAction();

$this->storeCurrentContentObjectData();

// @codeCoverageIgnoreStart
if (!isset($this->settings['staticTemplate'])) {
$this->controllerContext = $this->buildControllerContext();
$this->addFlashMessage(LocalizationUtility::translate('error_no_typoscript'), '', AbstractMessage::ERROR);
}
}

/**
* Forward to formAction if content element uids do not match
* used for createAction() and confirmationAction()
*
* @return void
*/
protected function forwardIfTtContentUidDoesNotMatch()
{
$arguments = $this->request->getArguments();
$currentContentObjectData = $this->getCurrentContentObjectData();

if (isset($arguments['field']['__ttcontentuid']) && isset($currentContentObjectData['uid'])
&& (int) $arguments['field']['__ttcontentuid'] !== (int) $currentContentObjectData['uid']
) {
$this->forward('form');
}
}

/**
* Forward to formAction if wrong form in plugin variables given
* used for createAction() and confirmationAction()
Expand Down Expand Up @@ -452,4 +474,40 @@ public function injectPersistenceManager(PersistenceManager $persistenceManager)
{
$this->persistenceManager = $persistenceManager;
}

/**
* Storing the current content object data to a global variable. That is necessary
* because content object data gets lost after a request is being forwarded to its
* referring request after an errorAction
*
* @return void
*/
protected function storeCurrentContentObjectData()
{
if (!empty($this->contentObject->data)) {
$tsfe = ObjectUtility::getTyposcriptFrontendController();

if (!is_array($tsfe->applicationData['tx_powermail'])) {
$tsfe->applicationData['tx_powermail'] = [];
}

$tsfe->applicationData['tx_powermail']['currentContentObjectData'] = $this->contentObject->data;
}
}

/**
* Retrieving data of content object that is currently being rendered
*
* @return array
*/
protected function getCurrentContentObjectData(): array
{
$tsfe = ObjectUtility::getTyposcriptFrontendController();

if (isset($tsfe->applicationData['tx_powermail']['currentContentObjectData'])) {
return $tsfe->applicationData['tx_powermail']['currentContentObjectData'];
}

return [];
}
}
35 changes: 33 additions & 2 deletions Classes/ViewHelpers/Misc/PrefillFieldViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ protected function getFromMail($value)
*/
protected function getFromMarker($value)
{
if (empty($value) && isset($this->piVars['field'][$this->getMarker()])) {
if (empty($value) && isset($this->piVars['field'][$this->getMarker()]) && $this->isSameContentElement()) {
$value = $this->piVars['field'][$this->getMarker()];
}
return $value;
Expand All @@ -155,7 +155,7 @@ protected function getFromMarker($value)
*/
protected function getFromRawMarker($value)
{
if (empty($value) && isset($this->piVars[$this->getMarker()])) {
if (empty($value) && isset($this->piVars[$this->getMarker()]) && $this->isSameContentElement()) {
$value = $this->piVars[$this->getMarker()];
}
return $value;
Expand Down Expand Up @@ -365,4 +365,35 @@ public function initialize()
$configurationService = ObjectUtility::getObjectManager()->get(ConfigurationService::class);
$this->configuration = $configurationService->getTypoScriptConfiguration();
}

/**
* Check whether GET / POST values may be used by this form,
* because they are from the same content element as the form was submitted
*/
protected function isSameContentElement(): bool
{
$currentContentObjectData = $this->getCurrentContentObjectData();

if (isset($currentContentObjectData['uid']) && isset($this->piVars['field']['__ttcontentuid'])) {
return (int) $currentContentObjectData['uid'] === (int) $this->piVars['field']['__ttcontentuid'];
}

return true;
}

/**
* Retrieving data of content object that is currently being rendered
*
* @return array
*/
protected function getCurrentContentObjectData(): array
{
$tsfe = ObjectUtility::getTyposcriptFrontendController();

if (isset($tsfe->applicationData['tx_powermail']['currentContentObjectData'])) {
return $tsfe->applicationData['tx_powermail']['currentContentObjectData'];
}

return [];
}
}
35 changes: 33 additions & 2 deletions Classes/ViewHelpers/Misc/PrefillMultiFieldViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ protected function getFromMail()
protected function getFromMarker()
{
$selected = false;
if (isset($this->variables['field'][$this->getMarker()])) {
if (isset($this->variables['field'][$this->getMarker()]) && $this->isSameContentElement()) {
if (is_array($this->variables['field'][$this->getMarker()])) {
foreach (array_keys($this->variables['field'][$this->getMarker()]) as $key) {
if ($this->variables['field'][$this->getMarker()][$key] === $this->options[$this->index]['value'] ||
Expand Down Expand Up @@ -215,7 +215,7 @@ protected function getFromMarker()
protected function getFromRawMarker()
{
$selected = false;
if (isset($this->variables[$this->getMarker()])) {
if (isset($this->variables[$this->getMarker()]) && $this->isSameContentElement()) {
if (is_array($this->variables[$this->getMarker()])) {
foreach (array_keys($this->variables[$this->getMarker()]) as $key) {
if ($this->variables[$this->getMarker()][$key] === $this->options[$this->index]['value'] ||
Expand Down Expand Up @@ -530,4 +530,35 @@ public function initialize()
$configurationService = ObjectUtility::getObjectManager()->get(ConfigurationService::class);
$this->configuration = $configurationService->getTypoScriptConfiguration();
}

/**
* Check whether GET / POST values may be used by this form,
* because they are from the same content element as the form was submitted
*/
protected function isSameContentElement(): bool
{
$currentContentObjectData = $this->getCurrentContentObjectData();

if (isset($currentContentObjectData['uid']) && isset($this->piVars['field']['__ttcontentuid'])) {
return (int) $currentContentObjectData['uid'] === (int) $this->piVars['field']['__ttcontentuid'];
}

return true;
}

/**
* Retrieving data of content object that is currently being rendered
*
* @return array
*/
protected function getCurrentContentObjectData(): array
{
$tsfe = ObjectUtility::getTyposcriptFrontendController();

if (isset($tsfe->applicationData['tx_powermail']['currentContentObjectData'])) {
return $tsfe->applicationData['tx_powermail']['currentContentObjectData'];
}

return [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public function initializeArguments()
parent::initializeArguments();
$this->registerArgument('form', Form::class, 'Form', true);
$this->registerArgument('additionalAttributes', 'array', 'additionalAttributes', false, []);
$this->registerArgument('ttContentData', 'array', 'ttContentData', false, []);
}

/**
Expand All @@ -50,6 +51,7 @@ public function render(): array
if ($this->settings['misc']['ajaxSubmit'] === '1') {
$additionalAttributes['data-powermail-ajax'] = 'true';
$additionalAttributes['data-powermail-form'] = $form->getUid();
$additionalAttributes['data-powermail-ttcontentuid'] = $this->arguments['ttContentData']['uid'];

if ($this->addRedirectUri) {
/** @var RedirectUriService $redirectService */
Expand Down
6 changes: 3 additions & 3 deletions Resources/Private/JavaScripts/Powermail/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ function PowermailForm($) {
if ($this.data('powermail-ajax-uri')) {
redirectUri = $this.data('powermail-ajax-uri');
}
var formUid = $this.data('powermail-form');
var ttContentUid = $this.data('powermail-ttcontentuid');

if (!regularSubmitOnAjax) {
$.ajax({
Expand All @@ -207,9 +207,9 @@ function PowermailForm($) {
fireAjaxCompleteEvent($txPowermail);
},
success: function(data) {
var html = $('*[data-powermail-form="' + formUid + '"]:first', data);
var html = $('*[data-powermail-ttcontentuid="' + ttContentUid + '"]:first', data);
if (html.length) {
$('*[data-powermail-form="' + formUid + '"]:first').closest('.tx-powermail').html(html);
$('*[data-powermail-ttcontentuid="' + ttContentUid + '"]:first').closest('.tx-powermail').html(html);
// fire tabs and parsley again
if ($.fn.powermailTabs) {
$('.powermail_morestep').powermailTabs();
Expand Down
3 changes: 2 additions & 1 deletion Resources/Private/Templates/Form/Confirmation.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ <h1><f:translate key="confirmation_message" /></h1>
enctype="multipart/form-data"
class="visible-xs-inline-block visible-sm-inline-block visible-md-inline-block visible-lg-inline-block"
addQueryString="{settings.misc.addQueryString}"
additionalAttributes="{vh:Validation.EnableParsleyAndAjax(form: mail.form)}">
additionalAttributes="{vh:Validation.EnableParsleyAndAjax(form: mail.form, ttContentData: ttContentData)}">
<f:render section="HiddenFields" arguments="{_all}" />
<f:form.submit
value="{f:translate(key: 'confirmation_next')}"
Expand All @@ -73,5 +73,6 @@ <h1><f:translate key="confirmation_message" /></h1>
</f:if>
</f:for>

<f:form.hidden name="field[__ttcontentuid]" value="{ttContentData.uid}" />
<f:form.hidden name="mail[form]" value="{mail.form.uid}" class="powermail_form_uid" />
</f:section>
2 changes: 1 addition & 1 deletion Resources/Private/Templates/Form/Create.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</f:alias>


<div class="{settings.styles.framework.createClasses}" data-powermail-form="{mail.form.uid}">
<div class="{settings.styles.framework.createClasses}" data-powermail-form="{mail.form.uid}" data-powermail-ttcontentuid="{ttContentData.uid}">
<f:if condition="{optinActive}">
<f:else>
<vh:Misc.Variables mail="{mail}">
Expand Down
3 changes: 2 additions & 1 deletion Resources/Private/Templates/Form/Form.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
section="c{ttContentData.uid}"
name="field"
enctype="multipart/form-data"
additionalAttributes="{vh:Validation.EnableParsleyAndAjax(form:form)}"
additionalAttributes="{vh:Validation.EnableParsleyAndAjax(form:form,ttContentData:ttContentData)}"
addQueryString="{settings.misc.addQueryString}"
class="powermail_form powermail_form_{form.uid} {form.css} {settings.styles.framework.formClasses} {vh:Misc.MorestepClass(activate:settings.main.moresteps)}">

Expand All @@ -33,6 +33,7 @@ <h3>{form.title}</h3>
<f:render partial="Form/Page" arguments="{_all}" />
</f:for>

<f:form.hidden name="field[__ttcontentuid]" value="{ttContentData.uid}" />
<f:form.hidden name="mail[form]" value="{form.uid}" class="powermail_form_uid" />
<f:render partial="Misc/HoneyPod" arguments="{form:form}" />
</f:form>
Expand Down