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

API Remove custom logic in favour of Form::saveInto() #1269

Merged

Conversation

GuySartorelli
Copy link
Member

@GuySartorelli GuySartorelli commented Nov 6, 2024

I don't think this warrants a note in the changelog beyond what will be automatically generated for the removed API - though feel free to disagree and if so I'll add a docs PR.

Issue

@GuySartorelli GuySartorelli marked this pull request as draft November 6, 2024 02:05
@GuySartorelli GuySartorelli force-pushed the pulls/6/form-saveinto-element branch 2 times, most recently from 9ec3203 to 13c1efe Compare November 6, 2024 03:19
* Arrive here from FormRequestHandler::httpSubmission() during a POST request to
* /admin/linkfield/linkForm/<LinkID>
* Arrive here from FormRequestHandler::httpSubmission() during a POST request.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated change here to remove copy/paste error that references linkfield

/**
* Remove the pseudo namespaces that were added in namespaceFields()
*/
public function removeNamespaceFromFields(FieldList $fields, array $context): void
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the same method signature as the corresponding namespaceFields() since they're essentially the reverse of one another.

/**
* Remove the pseudo namespaces that were added in namespaceFields()
*/
public function removeNamespaceFromFields(FieldList $fields, array $context): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a unit test

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no test for namespaceFields() nor for the old removeNamespacesFromFields() method on ElementalAreaController... these methods are both indirectly tested already.
But to avoid ping pong, I'll add tests for both of these methods after rebasing on top of the CMS 5 PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

$dataWithoutNamespaces = static::removeNamespacesFromFields($data, $element->ID);
// Remove the namespace prefixes
$factory = Injector::inst()->get(EditFormFactory::class);
$factory->removeNamespaceFromFields($form->Fields(), ['Record' => $element]);
Copy link
Member

@emteknetnz emteknetnz Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way these methods are being called on a factory class (whose purpose to a to create objects) looks weird as they're essentially utility methods. Change them to be statics and don't instantiate the factory, or just move them both to a standalone utility class as statics

Copy link
Member Author

@GuySartorelli GuySartorelli Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to do that, because the factory is injected and the existing namespaceFields() method could be altered in a project-specific customisation. Breaking that customisation option for the sake of "it looks weird" doesn't sit well with me.

The namespacing is intrinsic to the building of this specific form, so it makes sense for the factory to own that process.

Copy link
Member

@emteknetnz emteknetnz Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this again, renaming the fields on an existing form twice in order to save it seems kind of wrong

Wouldn't it make more sense to just get the factory to create an entirely new form without the namespaces, load the submitted $data into that and then call $newFormWithoutNamespaces->saveInto($element)

That would allow us to keep keep namespaceFields() as a protected method and we wouldn't even need removeNamespacesFromFields()

Update: ignore this, just occured to me the the submitted data will include namespaces

@GuySartorelli
Copy link
Member Author

None of the things you've pointed out in this review block the CMS 5 PRs. Please merge the CMS 5 PRs.

$dataWithoutNamespaces = static::removeNamespacesFromFields($data, $element->ID);
// Remove the namespace prefixes
$factory = Injector::inst()->get(EditFormFactory::class);
$factory->removeNamespaceFromFields($form->Fields(), ['Record' => $element]);
Copy link
Member

@emteknetnz emteknetnz Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this again, renaming the fields on an existing form twice in order to save it seems kind of wrong

Wouldn't it make more sense to just get the factory to create an entirely new form without the namespaces, load the submitted $data into that and then call $newFormWithoutNamespaces->saveInto($element)

That would allow us to keep keep namespaceFields() as a protected method and we wouldn't even need removeNamespacesFromFields()

Update: ignore this, just occured to me the the submitted data will include namespaces

@GuySartorelli GuySartorelli marked this pull request as ready for review November 7, 2024 00:21

class EditFormFactoryTest extends SapphireTest
{
protected static $fixture_file = 'EditFormFactoryTest.yml';

public function testFormFieldsHaveNamespaces()
{
/** @var ElementContent $record */
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated, but that's not needed anymore due to the addition of generics

$factory = new EditFormFactory();
$fields = new FieldList([
new TextField('FieldOne'),
new LiteralField('IgnoredField', ''),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LiteralField is ignored because it's not a "data field" so it doesn't affect form submission

$factory = new EditFormFactory();
$fields = new FieldList([
new TextField('PageElements_' . $record->ID . '_FieldOne'),
new LiteralField('IgnoredField', ''),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how the literal field will look when passed in, so we're just including it here to validate it doesn't get mangled

@emteknetnz emteknetnz merged commit cce5110 into silverstripe:6 Nov 7, 2024
17 checks passed
@emteknetnz emteknetnz deleted the pulls/6/form-saveinto-element branch November 7, 2024 01:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants