Skip to content

Fixed filters & matchers to allow copy private properties of ancestor objects #72

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

Merged
merged 6 commits into from
Sep 5, 2017

Conversation

vtsykun
Copy link

@vtsykun vtsykun commented May 29, 2017

Fix issue #62

Q A
Branch? master
Bug fix? yes
New feature? no
BC Breaks? no
Deprecations? no
Fix issue ? #62
License MIT
Doc -

@fsmeier
Copy link

fsmeier commented Jun 8, 2017

+1
this is exact what i need and atm i added nearly every filter by myself to add such private-property-access-function. This should be in the lastest version asap, otherwise you can not work with doctrine-proxies for example

return [
'public property' => ['a4'],
'private property' => ['a9'],
'private property of ancestor' => ['a3']
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unless I didn't understand what's going on properly, you're not supposed to access to the private properties of the parent entity

Copy link
Author

Choose a reason for hiding this comment

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

I agree with you, that I'm not supposed to access to the private properties of the parent entity. But this possibility for copying private properties of ancestor objects was added here. Currently the ReflectionHelper:getProperties() return all the properties from parent classes (include private from parent classes), but at the same time the Filters & Matchers is not support it, so in this PR I fixed BC break that was introduced after merge #23, keeping backward compatibility.

Copy link

Choose a reason for hiding this comment

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

@theofidry if you want to provide sth like a strict mode without parent-privates we can add an option. if the option is set to strict(or other way around), ReflectionHelper:getProperties() should not return privates from parent anymore and the current proposed solution should also check this option then. So you can have a strict mode but allow the possibility of accessing them.

the current version break and do not work properly like @vtsykun mentioned.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@trebi could you provide a use case for this parent private property? I would like to have one to make my opinion on this

Copy link

Choose a reason for hiding this comment

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

@theofidry i am not @trebi but I can give you one use-case:
If you work with entities handled by doctrine it is nearly impossible to get all the time the pure entity back. So the ProxyEntity is a Child of the actual entity. But the 'real' properties from the actual entity are most of the time private.
If we would implement what is proposed in issue#67 we could forward the 'power' to the matcher i.e.: Match just if the property is from the child-class or other way around.

Copy link
Contributor

Choose a reason for hiding this comment

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

@theofidry On one hand, accessing parent object clearly is violation of OOP encapsulation. But not supporting it during deep copy could result in violation of Liskov substitution principle, which is even worse (if your code is deigned to work with class Y and you subtitute it with class Z that inherits from Y, which is perfectly valid, it will suddenly break).

IMHO, it also contraditcs the intuition to use DeepCopy library in the first place, as it will not create completely isolated copy of the graph of objects, as shown on this image.

My use-case was that I had graph of various objects linked together and I wanted to create a copy of this graph (while preserving inner references), try out some changes and then decise whether or not to "commit" these changes (replace the original graph of objects with the new one). Before I implemented #23, it was not creating the isolated copy of object graph and therefore it was useless for me.

// this is how it worked before #23 was accepted
class X {}

class Y {
    private $x;
    public function __construct(X $x) { $this->x = $x; }
    public function getX() { return $this->x; }
}

class Z extends Y {}

$deepCopy = new DeepCopy;
$x = new X;

$y = new Y($x);
$yCopy = $deepCopy->copy($y);
var_dump($y->getX());
var_dump($yCopy->getX()); // X is copied as expected 

$z = new Z($x);
$zCopy = $deepCopy->copy($z);
var_dump($z->getX());
var_dump($zCopy->getX()); // X is not copied - violates Liskov substitution principle

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks @trebi, a use case was all I needed :)

Copy link

Choose a reason for hiding this comment

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

And what arethe next steps here?

@vtsykun vtsykun changed the title Fix: matches are expected to access private properties in a derived class Fixed filters & matchers to allow copy private properties of ancestor objects Jun 9, 2017
Copy link
Member

@mnapoli mnapoli left a comment

Choose a reason for hiding this comment

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

@theofidry is it good to you for merging? That looks good to me (except the extra interface but that's easily fixed) but given how widely the project is used I'd really appreciate extra eyes ;)


interface DeepCopyExceptionInterface
{
}
Copy link
Member

Choose a reason for hiding this comment

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

This interface was added but I don't think it's related to this pull request, could you remove it please?

Copy link
Author

Choose a reason for hiding this comment

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

Done.

Copy link
Collaborator

@theofidry theofidry left a comment

Choose a reason for hiding this comment

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

All good for me 👍

@fsmeier
Copy link

fsmeier commented Jun 26, 2017

Any update here?

@mjpvandenberg
Copy link

I'd love to see this pull request merged.

@theofidry
Copy link
Collaborator

Sorry, just need to merge this and tag it, might do over the weekend

@vtsykun
Copy link
Author

vtsykun commented Sep 5, 2017

ping @theofidry

@theofidry theofidry merged commit 74453ad into myclabs:master Sep 5, 2017
@theofidry
Copy link
Collaborator

Thank you guys, sorry for the delay

@vtsykun vtsykun deleted the fix/issue-62 branch September 19, 2017 22:50
theofidry added a commit to theofidry/DeepCopy that referenced this pull request Oct 16, 2017
theofidry added a commit that referenced this pull request Oct 16, 2017
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.

7 participants