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

Compatibility issues with MP_Forms and Notification Center #22

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
239 changes: 128 additions & 111 deletions src/EventListener/FormHookListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Contao\Widget;
use InspiredMinds\ContaoFieldsetDuplication\Helper\FieldHelper;
use MPFormsFormManager;
use MPFormsSessionManager;
use Symfony\Component\HttpFoundation\RequestStack;

class FormHookListener
Expand Down Expand Up @@ -59,14 +60,13 @@ public function onLoadFormField(Widget $widget, string $formId, array $data, For

public function onCompileFormFields(array $fields, $formId, Form $objForm): array
{
static $alreadyProcessed = false;

// Ensure the listener is called only once (e.g. in combination with MPForms)
if ($alreadyProcessed) {
return $fields;
// Return if the fields were already cloned by this listener (e.g. in combination with MPForms)
foreach ($fields as $field) {
if (false !== (strpos($field->name, '_duplicate_'))) {
return $fields;
}
}

$alreadyProcessed = true;
$submittedData = [];

// Get the submitted data from the request
Expand All @@ -75,116 +75,14 @@ public function onCompileFormFields(array $fields, $formId, Form $objForm): arra
}

// Get the submitted data from MPForms
if (count($submittedData) === 0 && class_exists(\MPFormsFormManager::class)) {
$manager = new MPFormsFormManager($objForm->id);
if (count($submittedData) === 0 && class_exists(\MPFormsSessionManager::class)) {
$manager = new MPFormsSessionManager($objForm->id);
$submittedData = $manager->getDataOfStep($manager->getCurrentStep())['originalPostData'] ?? [];
}

// check if form was submitted
if (($submittedData['FORM_SUBMIT'] ?? null) === $formId) {
$fieldsetGroups = $this->buildFieldsetGroups($fields);

$processed = [];
$fieldsetDuplicates = [];

// search for duplicates
foreach (array_keys($submittedData) as $duplicateName) {
// check if already processed
if (\in_array($duplicateName, $processed, true)) {
continue;
}

// check if it is a duplicate
if (false !== ($intPos = strpos($duplicateName, '_duplicate_'))) {
// get the non duplicate name
$originalName = substr($duplicateName, 0, $intPos);

// get the duplicate number
$duplicateNumber = (int) (substr($duplicateName, -1));

// clone the fieldset
foreach ($fieldsetGroups as $fieldsetGroup) {
foreach ($fieldsetGroup as $field) {
if ($field->name === $originalName) {
// new sorting base number
$sorting = $fieldsetGroup[\count($fieldsetGroup) - 1]->sorting;

$duplicatedFields = [];

foreach ($fieldsetGroup as $field) {
// set the actual duplicate name
$duplicateName = $field->name.'_duplicate_'.$duplicateNumber;

// clone the field
$clone = clone $field;

// remove allow duplication class
if ($this->fieldHelper->isFieldsetStart($clone)) {
$clone->class = implode(' ', array_diff(explode(' ', $clone->class), ['allow-duplication']));
$clone->class .= ($clone->class ? ' ' : '').'duplicate-fieldset-'.$field->id.' duplicate';
}

// set the id
$clone->id = $field->id.'_duplicate_'.$duplicateNumber;

// set the original id
$clone->originalId = $field->id;

// set the name
$clone->name = $duplicateName;

// set the sorting
$clone->sorting = ++$sorting;

// add the clone
$duplicatedFields[] = $clone;

// add to processed
$processed[] = $duplicateName;
}

$fieldsetDuplicates[] = $duplicatedFields;

break 2;
}
}
}
}
}

// reverse the fieldset duplicates
$fieldsetDuplicates = array_reverse($fieldsetDuplicates);

// process $fields
$fields = array_values($fields);

// go through the duplicated fieldsets
foreach ($fieldsetDuplicates as $duplicatedFieldset) {
// search for the stop field
$stopId = null;
foreach ($duplicatedFieldset as $duplicatedField) {
if ($this->fieldHelper->isFieldsetStop($duplicatedField)) {
$stopId = $duplicatedField->originalId;
break;
}
}

// search for the index position of the original stop field
if (null !== $stopId) {
$stopIdx = null;
for ($i = 0; $i < \count($fields); ++$i) {
if ($fields[$i]->id === $stopId) {
$stopIdx = $i;
break;
}
}

// insert fields after original stop field
if (null !== $stopIdx) {
array_splice($fields, $stopIdx + 1, 0, $duplicatedFieldset);
}
}
}
$fields = $this->cloneFields($fields, $submittedData);
}

// return the fields
Expand Down Expand Up @@ -214,6 +112,15 @@ public function onStoreFormData(array $set, Form $form): array

public function onPrepareFormData(array &$submittedData, array $labels, array $fields, Form $form): void
{
if (class_exists(\MPFormsFormManager::class)) {
$manager = new MPFormsFormManager($form->id);

if ($manager->getNumberOfSteps() > 1) {
$fields = $manager->getFieldsWithoutPageBreaks();
$fields = $this->cloneFields($fields, $submittedData);
}
}

$fieldsetGroups = $this->buildFieldsetGroups($fields);
$values = $this->groupFieldsetValues($fieldsetGroups, $submittedData);

Expand Down Expand Up @@ -249,6 +156,116 @@ public function onPrepareFormData(array &$submittedData, array $labels, array $f
Config::set('debugMode', $debugMode);
}

private function cloneFields(array $fields, array $submittedData): array
{
$fieldsetGroups = $this->buildFieldsetGroups($fields);

$processed = [];
$fieldsetDuplicates = [];

// search for duplicates
foreach (array_keys($submittedData) as $duplicateName) {
// check if already processed
if (\in_array($duplicateName, $processed, true)) {
continue;
}

// check if it is a duplicate
if (false !== ($intPos = strpos($duplicateName, '_duplicate_'))) {
// get the non duplicate name
$originalName = substr($duplicateName, 0, $intPos);

// get the duplicate number
$duplicateNumber = (int) (substr($duplicateName, -1));

// clone the fieldset
foreach ($fieldsetGroups as $fieldsetGroup) {
foreach ($fieldsetGroup as $field) {
if ($field->name === $originalName) {
// new sorting base number
$sorting = $fieldsetGroup[\count($fieldsetGroup) - 1]->sorting;

$duplicatedFields = [];

foreach ($fieldsetGroup as $field) {
// set the actual duplicate name
$duplicateName = $field->name.'_duplicate_'.$duplicateNumber;

// clone the field
$clone = clone $field;

// remove allow duplication class
if ($this->fieldHelper->isFieldsetStart($clone)) {
$clone->class = implode(' ', array_diff(explode(' ', $clone->class), ['allow-duplication']));
$clone->class .= ($clone->class ? ' ' : '').'duplicate-fieldset-'.$field->id.' duplicate';
}

// set the id
$clone->id = $field->id.'_duplicate_'.$duplicateNumber;

// set the original id
$clone->originalId = $field->id;

// set the name
$clone->name = $duplicateName;

// set the sorting
$clone->sorting = ++$sorting;

// add the clone
$duplicatedFields[] = $clone;

// add to processed
$processed[] = $duplicateName;
}

$fieldsetDuplicates[] = $duplicatedFields;

break 2;
}
}
}
}
}

// reverse the fieldset duplicates
$fieldsetDuplicates = array_reverse($fieldsetDuplicates);

// process $fields
$fields = array_values($fields);

// go through the duplicated fieldsets
foreach ($fieldsetDuplicates as $duplicatedFieldset) {
// search for the stop field
$stopId = null;
foreach ($duplicatedFieldset as $duplicatedField) {
if ($this->fieldHelper->isFieldsetStop($duplicatedField)) {
$stopId = $duplicatedField->originalId;
break;
}
}

// search for the index position of the original stop field
if (null !== $stopId) {
$stopIdx = null;
for ($i = 0; $i < \count($fields); ++$i) {
if ($fields[$i]->id === $stopId) {
$stopIdx = $i;
break;
}
}

// insert fields after original stop field
if (null !== $stopIdx) {
array_splice($fields, $stopIdx + 1, 0, $duplicatedFieldset);
}
}
}

// return the fields
return $fields;
}

/**
* @param array|Widget[]|FormFieldModel[] $fields
*/
Expand Down
12 changes: 11 additions & 1 deletion src/Resources/public/jquery.fieldset.duplication.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,17 @@
return false;
}
});

// determine the highest existing duplicate number
$(selector).each(function()
{
$(this).find('input[name], select[name], textarea[name]').each(function() {
var match = $(this).attr('id').match(/_duplicate_(\d+)/);
if (match && match[1] > duplicateIndex) {
duplicateIndex = match[1];
}
});
});

var updateFieldsets = function()
{
$fieldsets = $(selector);
Expand Down