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

DBComposite::writeToManipulation() is never called #8800

Closed
kinglozzer opened this issue Feb 14, 2019 · 9 comments · Fixed by #10913
Closed

DBComposite::writeToManipulation() is never called #8800

kinglozzer opened this issue Feb 14, 2019 · 9 comments · Fixed by #10913

Comments

@kinglozzer
Copy link
Member

kinglozzer commented Feb 14, 2019

Affected Version

4.0.0 - 4.3.0

Description

Noticed this when implementing a custom DBComposite field type - before a DataObject is written, DBField::writeToManipulation() should be called against all database fields, but it isn’t called on DBComposite fields.

Looks like there was a subtle behavioural change in commit 11bbed4.

Before:

// Check if this record pertains to this table, and
// we're not attempting to reset the BaseTable->ID
if( empty($this->changed[$fieldName])
|| ($table === $baseTable && $fieldName === 'ID')
|| (!self::has_own_table_database_field($class, $fieldName)
&& !self::is_composite_field($class, $fieldName, false))
) {
continue;
}

After:
// we're not attempting to reset the BaseTable->ID
// Ignore unchanged fields or attempts to reset the BaseTable->ID
if (empty($this->changed[$fieldName]) || ($table === $baseTable && $fieldName === 'ID')) {
continue;
}
// Ensure this field pertains to this table
$specification = $schema->fieldSpec($class, $fieldName, ['dbOnly', 'uninherited']);
if (!$specification) {
continue;
}

The config option 'dbOnly' (since replaced by the bitmask DataObjectSchema::DB_ONLY) shouldn’t be set here - as that explicitly excludes “virtual” (i.e. composite) fields.

Marking as low impact as the composite values are still saved - by virtue of DBComposite::setField() calling $record->setField() for each of the composite values

Related PRs

@lekoala
Copy link
Contributor

lekoala commented May 31, 2023

This is still a thing. Any plans to fix it? Why is this PR closed #8816 ?

@michalkleiner
Copy link
Contributor

Not sure why the PR was closed. We can rebase the branch, reopen and retarget the PR I guess.

@kinglozzer
Copy link
Member Author

I think it was automatically closed when the target branch was deleted

@michalkleiner
Copy link
Contributor

Probably. GitHub doesn't allow me to reopen it, so it probably needs to be edited first or recreated completely.

@lekoala
Copy link
Contributor

lekoala commented May 31, 2023

:-) i'm just asking because i have a module with a composite field where this could be really handy

@kinglozzer
Copy link
Member Author

I recreated it here but looks like it had a failing test: #9182. If someone else wants to recreate the PR and fix it up - or just pinch some of the code - then feel free 🙂

@beerbohmdo
Copy link
Contributor

beerbohmdo commented Aug 3, 2023

This is still broken in Silverstripe 5. DBMoney fields are not written to database.

@lekoala
Copy link
Contributor

lekoala commented Aug 10, 2023

@kinglozzer i took the liberty to take your PR and fix it
#10913

@GuySartorelli
Copy link
Member

PR merged. This will be automatically tagged once CI has finished running on the branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants