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

WIP SS4 compat, rewrite to DBField #44

Closed
wants to merge 3 commits into from
Closed

WIP SS4 compat, rewrite to DBField #44

wants to merge 3 commits into from

Conversation

chillu
Copy link
Contributor

@chillu chillu commented May 10, 2017

This started out as an innocent "fix tests for 4.x" task: The master branch of this module (3.x release line) has been made 4.x compatible a while ago, but the test config didn't reflect that

But it turns out the field is quite broken with the SS4 ORM:
The field is not a “composite” field, since it only has one database column.
The DBComposite API has changed a bit in SS4, which causes the field to break in weird ways
since it has overloaded so much of the underlying core functionality. For example,
the field never gets written since it doesn’t set MyFieldValue, and
DataObject->prepareManipulationTable() skips MyField because it’s not a database column.
Rather than fixing these quirks, it’s much easier to rewrite the field as a DBText.

TODO:

  • Document db column migration path (from MyFieldValue to MyField)
  • Change from serialise() to json_encode() for security reasons

@sanderha @wernerkrauss @digitall-it @brasileric Anybody keen to review and help get this over the line?

The master branch of this module (3.x release line) has been made 4.x compatible a while ago, but the test config didn't reflect that
The field is not a “composite” field, since it only has one database column.
The DBComposite API has changed a bit in SS4, which causes the field to break in weird ways
since it has overloaded so much of the underlying core functionality. For example,
the field never gets written since it doesn’t set MyFieldValue, and
DataObject->prepareManipulationTable() skips MyField because it’s not a database column.
Rather than fixing these quirks, it’s much easier to rewrite the field as a DBText.

TODO:
- Document db column migration path (from MyFieldValue to MyField)
- Change from serialise() to json_encode() for security reasons
@chillu chillu changed the title Only testing supported versions SS4 compat, rewrite to DBField May 10, 2017
@chillu chillu changed the title SS4 compat, rewrite to DBField WIP SS4 compat, rewrite to DBField May 10, 2017
@nyeholt
Copy link
Contributor

nyeholt commented May 11, 2017

  • Change from serialise() to json_encode() for security reasons

Yep, this is probably my biggest desire with the SS4 move :)

@jsirish
Copy link

jsirish commented Jul 7, 2017

closes #46

Copy link

@muskie9 muskie9 left a comment

Choose a reason for hiding this comment

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

This will need feedback, I'm basing this on prior feedback and may affect additional code with unserialize().

}
public function testSetSerialisedStringAsProperty() {
$obj = new MultiValueFieldTest_DataObject();
$obj->MVField = serialize(['One', 'Two']);
Copy link

Choose a reason for hiding this comment

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

Update to json_encode() if prior comments are correct.

$this->assertTrue($field->isChanged());
public function testSetSerialisedStringWithSetValue() {
$obj = new MultiValueFieldTest_DataObject();
$obj->obj('MVField')->setValue(serialize(['One', 'Two']));
Copy link

Choose a reason for hiding this comment

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

Update to json_encode() if prior comments are correct.

@muskie9
Copy link

muskie9 commented Jul 7, 2017

@nyeholt can you comment on what you were going for here and how it is reflected in the updated PR?

@nyeholt
Copy link
Contributor

nyeholt commented Jul 10, 2017

@muskie9 - rather than using serialize and unserialize in get/setValue, it should be using json_encode/json_decode. This could be done in a backwards compatible manner, by looking for "a:" as the starting characters of the field value and assuming the old format, otherwise using json_decode.

@muskie9
Copy link

muskie9 commented Jul 20, 2017

I've been digging into this a bit more and am wondering if some classes such as MultiValueListField would be more appropriate extending other classes like SelectField. This would add to the scope of this PR, but may make more sense based on what the fields are trying to accomplish.

@muskie9
Copy link

muskie9 commented Jul 20, 2017

After looking through this some more I did a rebase and pushed some work up to a fork not to muddy this PR. I have all tests passing with the exception of testing isChanged(). There seems to be quite a difference in how the setValue() methods are currently working in the 3 compatible branch to this PR. Have things changed in SS4 that drastically, or is it just an older PR that doesn't have existing logic brought over?

@nyeholt
Copy link
Contributor

nyeholt commented Jul 21, 2017

I believe Ingo's PR changes the field type that MultiValueField inherits from, so the way setValue works is quite different as it's not longer having to handle writing as a composite field would (which is a much simpler/better approach).

@muskie9
Copy link

muskie9 commented Jul 21, 2017

Thanks @nyeholt, after digging into this a bit more, and comparing to some things in framework DBCurrency... I'm seeing some noticeable differences. I'm going to try to digest what's going on in the module and framework class a bit more. Sorry for the spam 😬

@nyeholt
Copy link
Contributor

nyeholt commented Dec 7, 2017

FYI - Release 5.0.0 (https://packagist.org/packages/symbiote/silverstripe-multivaluefield) covers this off now; there's a few reasons that it needs to be a composite field (due to how normal text fields don't give you a chance to modify the field value when it's loaded from the DB if it's not a composite field). This also includes switching to json_encode instead of serialise, but in a BC manner.

@nyeholt nyeholt closed this Dec 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

5 participants