Skip to content

Commit

Permalink
FIX Duplicate userforms using cascade_duplicates config (#1320)
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli authored Aug 27, 2024
1 parent 4c23cad commit db8adf5
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 40 deletions.
21 changes: 7 additions & 14 deletions code/Extension/UserFormFieldEditorExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class UserFormFieldEditorExtension extends DataExtension
);

private static $owns = [
// Note we explicitly cannot use $cascade_duplicates to duplicate this relation.
// See onAfterDuplicate()
'Fields'
];

Expand Down Expand Up @@ -228,13 +230,14 @@ public function onAfterUnpublish()
}

/**
* When duplicating a UserDefinedForm, duplicate all of its fields and display rules
* Duplicate the Fields() relation.
* When duplicating a UserDefinedForm, ensure the group ends aren't duplicated twice,
* but also ensure they are connected to the correct duplicated Group.
*
* @see DataObject::duplicate
* @param DataObject $oldPage
* @param bool $doWrite
* @param string $manyMany
* @return DataObject
* @param null|array $manyMany
*/
public function onAfterDuplicate($oldPage, $doWrite, $manyMany)
{
Expand All @@ -243,10 +246,7 @@ public function onAfterDuplicate($oldPage, $doWrite, $manyMany)
foreach ($oldPage->Fields() as $field) {
/** @var EditableFormField $newField */
$newField = $field->duplicate(false);
$newField->ParentID = $this->owner->ID;
$newField->ParentClass = $this->owner->ClassName;
$newField->Version = 0;
$newField->write();
$this->getOwner()->Fields()->add($newField);

// If we encounter a group start, record it for later use
if ($field instanceof EditableFieldGroup) {
Expand All @@ -259,13 +259,6 @@ public function onAfterDuplicate($oldPage, $doWrite, $manyMany)
$groupStart->EndID = $newField->ID;
$groupStart->write();
}

foreach ($field->DisplayRules() as $customRule) {
$newRule = $customRule->duplicate(false);
$newRule->ParentID = $newField->ID;
$newRule->Version = 0;
$newRule->write();
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion code/Model/EditableFormField.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ class EditableFormField extends DataObject
'DisplayRules',
];

private static $cascade_duplicates = false;
private static $cascade_duplicates = [
'DisplayRules',
];

/**
* This is protected rather that private so that it's unit testable
Expand Down
23 changes: 4 additions & 19 deletions code/Model/EditableFormField/EditableMultipleOptionField.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class EditableMultipleOptionField extends EditableFormField
'Options',
];

private static $cascade_duplicates = [
'Options',
];

private static $table_name = 'EditableMultipleOptionField';

/**
Expand Down Expand Up @@ -112,25 +116,6 @@ public function getCMSFields()
return $fields;
}

/**
* Duplicate a pages content. We need to make sure all the fields attached
* to that page go with it
* {@inheritDoc}
*/
public function duplicate(bool $doWrite = true, array|null $relations = null): static
{
$clonedNode = parent::duplicate(true);

foreach ($this->Options() as $field) {
$newField = $field->duplicate(false);
$newField->ParentID = $clonedNode->ID;
$newField->Version = 0;
$newField->write();
}

return $clonedNode;
}

/**
* Return whether or not this field has addable options such as a
* {@link EditableDropdown} or {@link EditableRadioField}
Expand Down
4 changes: 4 additions & 0 deletions code/Model/Recipient/EmailRecipient.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ class EmailRecipient extends DataObject
'CustomRules',
];

private static $cascade_duplicates = [
'CustomRules',
];

private static $summary_fields = [
'EmailAddress',
'EmailSubject',
Expand Down
9 changes: 5 additions & 4 deletions code/UserForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ trait UserForm
'EmailRecipients',
];

private static $cascade_duplicates = false;
private static $cascade_duplicates = [
'EmailRecipients',
];

/**
* @var array
Expand Down Expand Up @@ -161,9 +163,8 @@ trait UserForm
private static $non_live_permissions = ['SITETREE_VIEW_ALL'];

/**
* Temporary storage of field ids when the form is duplicated.
* Example layout: array('EditableCheckbox3' => 'EditableCheckbox14')
* @var array
* Unused property
* @deprecated 5.3.0 Will be removed without equivalent functionality to replace it
*/
protected $fieldsFromTo = [];

Expand Down
4 changes: 2 additions & 2 deletions tests/php/Model/UserDefinedFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ public function testDuplicatingForm()
$form2 = $this->objFromFixture(UserDefinedForm::class, 'page-with-group');
$form2Validator = new UserFormValidator();
$form2Validator->setForm(new Form(new Controller(), Form::class, new FieldList(), new FieldList()));
$this->assertTrue($form2Validator->php($form2->toMap()));
$this->assertTrue($form2Validator->php($form2->toMap()), json_encode($form2Validator->getResult()->getMessages()));

// Check field groups exist
$form2GroupStart = $form2->Fields()->filter('ClassName', EditableFieldGroup::class)->first();
Expand All @@ -374,7 +374,7 @@ public function testDuplicatingForm()
$form3 = $form2->duplicate();
$form3Validator = new UserFormValidator();
$form3Validator->setForm(new Form(new Controller(), Form::class, new FieldList(), new FieldList()));
$this->assertTrue($form3Validator->php($form3->toMap()));
$this->assertTrue($form3Validator->php($form3->toMap()), json_encode($form3Validator->getResult()->getMessages()));
// Check field groups exist
$form3GroupStart = $form3->Fields()->filter('ClassName', EditableFieldGroup::class)->first();
$form3GroupEnd = $form3->Fields()->filter('ClassName', EditableFieldGroupEnd::class)->first();
Expand Down

0 comments on commit db8adf5

Please sign in to comment.