Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 94ca275

Browse files
committed
merged branch jfsimon/issue-7069 (PR #7271)
This PR was merged into the master branch. Commits ------- b6a5457 [Validator] Fixed member (getter/property) metadata readers. [Validator] added overridden getter metadata test [Validator] class member reflection build requires object instance [Validator] fixed error [Validation] fixed member metadata reflection cache [Validation] added property metedata test [Validation] fixed class/member metadata mapping [Validation] removed var_dump 9b6cd80 Update src/Symfony/Component/Validator/Mapping/GetterMetadata.php Discussion ---------- [Validator] Use concrete Class Methods to check validations This PR just adds a test to #7069. | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | yes | Deprecations? | no | Tests pass? | yes | Fixed tickets | #7069 --------------------------------------------------------------------------- by vicb at 2013-03-05T18:21:02Z @jfsimon Do you have a response about my comment in the original PR ? At least we now have a BC break (ie new is no more called). --------------------------------------------------------------------------- by jfsimon at 2013-03-05T18:30:43Z @vicb I didn't saw it. I update the description. --------------------------------------------------------------------------- by vicb at 2013-03-05T18:34:01Z np, do you have a reply ? _BCB = yes should trigger a note in the changelog_ --------------------------------------------------------------------------- by jfsimon at 2013-03-05T18:51:15Z @vicb a response about the `newReflectionMember` method update? --------------------------------------------------------------------------- by vicb at 2013-03-05T19:08:54Z Yep "Jean-François Simon" <[email protected]> wrote: >@vicb a response about the `newReflectionMember` method update? > >--- >Reply to this email directly or view it on GitHub: >#7271 (comment) --------------------------------------------------------------------------- by Gladhon at 2013-03-06T08:04:38Z @vicb newReflectionMember is a Method that comes from the parent and has no argument "object". So it can only get the reflection Member of the configured class, while we need once (in this special case) need the method of the concrete class. --------------------------------------------------------------------------- by jfsimon at 2013-03-06T08:29:11Z @vicb @Gladhon correct me if I'm wrong. This method is only used to check the member scope. In the case of a getter, this scope is always public (`method_exists` returns true only if method is visible, then is this case public, isn'it?), so the `isPublic`, `isProtected` and `isPrivate` methods can be safely overriden. Am I right? --------------------------------------------------------------------------- by Gladhon at 2013-03-06T08:43:54Z Yes i am in agreement with that. But I just think about to change the getPropertyValue also in PropertyMetadata. Can that make sense in any case ? --------------------------------------------------------------------------- by vicb at 2013-03-06T08:56:21Z @jfsimon `method_exists` returns `true` when the method exists, whatever its visibility. My question is whether it would make sense to change the signature of `newReflectionMember` to accept an objet ? That would be a BC break but the implementation proposed here is also a BC break (`newReflectionMember` which was called from `getReflectionMember` is no more called with this PR - it could have been overriden by a dev) Finally `PropertyMetadata` should probably be updated in the same way. --------------------------------------------------------------------------- by vicb at 2013-03-06T08:57:33Z _and fyi you can both work on the same PR, ie @Gladhon you can send some changes (a PR) to the repo of @jfsimon_ --------------------------------------------------------------------------- by Gladhon at 2013-03-06T10:22:07Z Well, i like it how it is now. Cause if we change that, you also need to have a object if calling "isPublic". For me it makes more sence to have only the object parameter if its realy needed. Where do you see a real benefit if we change the `newReflectionMember` instead ? --------------------------------------------------------------------------- by jfsimon at 2013-03-07T13:43:43Z @vicb I think passing object instance to `getReflectionMember` is **required** for consistency. I just pushed it.
2 parents 3a11efe + b6a5457 commit 94ca275

File tree

9 files changed

+67
-22
lines changed

9 files changed

+67
-22
lines changed

src/Symfony/Component/Validator/Mapping/ClassMetadata.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ public function mergeConstraints(ClassMetadata $source)
252252

253253
$this->addMemberMetadata($member);
254254

255-
if (!$member->isPrivate()) {
255+
if (!$member->isPrivate($this->name)) {
256256
$property = $member->getPropertyName();
257257

258258
if ($member instanceof PropertyMetadata && !isset($this->properties[$property])) {

src/Symfony/Component/Validator/Mapping/GetterMetadata.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ public function __construct($class, $property)
4444
*/
4545
public function getPropertyValue($object)
4646
{
47-
return $this->getReflectionMember()->invoke($object);
47+
return $this->newReflectionMember($object)->invoke($object);
4848
}
4949

5050
/**
5151
* {@inheritDoc}
5252
*/
53-
protected function newReflectionMember()
53+
protected function newReflectionMember($objectOrClassName)
5454
{
55-
return new \ReflectionMethod($this->getClassName(), $this->getName());
55+
return new \ReflectionMethod($objectOrClassName, $this->getName());
5656
}
5757
}

src/Symfony/Component/Validator/Mapping/MemberMetadata.php

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ abstract class MemberMetadata extends ElementMetadata implements PropertyMetadat
2626
public $cascaded = false;
2727
public $collectionCascaded = false;
2828
public $collectionCascadedDeeply = false;
29-
private $reflMember;
29+
private $reflMember = array();
3030

3131
/**
3232
* Constructor.
@@ -123,31 +123,37 @@ public function getPropertyName()
123123
/**
124124
* Returns whether this member is public
125125
*
126+
* @param object|string $objectOrClassName The object or the class name
127+
*
126128
* @return Boolean
127129
*/
128-
public function isPublic()
130+
public function isPublic($objectOrClassName)
129131
{
130-
return $this->getReflectionMember()->isPublic();
132+
return $this->getReflectionMember($objectOrClassName)->isPublic();
131133
}
132134

133135
/**
134136
* Returns whether this member is protected
135137
*
138+
* @param object|string $objectOrClassName The object or the class name
139+
*
136140
* @return Boolean
137141
*/
138-
public function isProtected()
142+
public function isProtected($objectOrClassName)
139143
{
140-
return $this->getReflectionMember()->isProtected();
144+
return $this->getReflectionMember($objectOrClassName)->isProtected();
141145
}
142146

143147
/**
144148
* Returns whether this member is private
145149
*
150+
* @param object|string $objectOrClassName The object or the class name
151+
*
146152
* @return Boolean
147153
*/
148-
public function isPrivate()
154+
public function isPrivate($objectOrClassName)
149155
{
150-
return $this->getReflectionMember()->isPrivate();
156+
return $this->getReflectionMember($objectOrClassName)->isPrivate();
151157
}
152158

153159
/**
@@ -202,21 +208,26 @@ public function getValue($object)
202208
/**
203209
* Returns the Reflection instance of the member
204210
*
211+
* @param object|string $objectOrClassName The object or the class name
212+
*
205213
* @return object
206214
*/
207-
public function getReflectionMember()
215+
public function getReflectionMember($objectOrClassName)
208216
{
209-
if (!$this->reflMember) {
210-
$this->reflMember = $this->newReflectionMember();
217+
$className = is_string($objectOrClassName) ? $objectOrClassName : get_class($objectOrClassName);
218+
if (!isset($this->reflMember[$className])) {
219+
$this->reflMember[$className] = $this->newReflectionMember($objectOrClassName);
211220
}
212221

213-
return $this->reflMember;
222+
return $this->reflMember[$className];
214223
}
215224

216225
/**
217226
* Creates a new Reflection instance for the member
218227
*
219-
* @return object
228+
* @param object|string $objectOrClassName The object or the class name
229+
*
230+
* @return mixed Reflection class
220231
*/
221-
abstract protected function newReflectionMember();
232+
abstract protected function newReflectionMember($objectOrClassName);
222233
}

src/Symfony/Component/Validator/Mapping/PropertyMetadata.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,20 @@ public function __construct($class, $name)
3737
*/
3838
public function getPropertyValue($object)
3939
{
40-
return $this->getReflectionMember()->getValue($object);
40+
return $this->getReflectionMember($object)->getValue($object);
4141
}
4242

4343
/**
4444
* {@inheritDoc}
4545
*/
46-
protected function newReflectionMember()
46+
protected function newReflectionMember($objectOrClassName)
4747
{
48-
$member = new \ReflectionProperty($this->getClassName(), $this->getName());
48+
$class = new \ReflectionClass($objectOrClassName);
49+
while (!$class->hasProperty($this->getName())) {
50+
$class = $class->getParentClass();
51+
}
52+
53+
$member = new \ReflectionProperty($class->getName(), $this->getName());
4954
$member->setAccessible(true);
5055

5156
return $member;

src/Symfony/Component/Validator/Tests/Fixtures/Entity.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ class Entity extends EntityParent implements EntityInterface
3333
protected $firstName;
3434
protected $lastName;
3535
public $reference;
36-
3736
private $internal;
37+
public $data = 'Overridden data';
3838

3939
public function __construct($internal = null)
4040
{
@@ -53,4 +53,9 @@ public function getLastName()
5353
{
5454
return $this->lastName;
5555
}
56+
57+
public function getData()
58+
{
59+
return 'Overridden data';
60+
}
5661
}

src/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@ class EntityParent
1717
{
1818
protected $firstName;
1919
private $internal;
20+
private $data = 'Data';
2021

2122
/**
2223
* @NotNull
2324
*/
2425
protected $other;
26+
27+
public function getData()
28+
{
29+
return 'Data';
30+
}
2531
}

src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,12 @@ public function testGetPropertyValueFromPublicGetter()
3535

3636
$this->assertEquals('foobar from getter', $metadata->getPropertyValue($entity));
3737
}
38+
39+
public function testGetPropertyValueFromOverriddenPublicGetter()
40+
{
41+
$entity = new Entity();
42+
$metadata = new GetterMetadata(self::CLASSNAME, 'data');
43+
44+
$this->assertEquals('Overridden data', $metadata->getPropertyValue($entity));
45+
}
3846
}

src/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function getPropertyValue($object)
7777
{
7878
}
7979

80-
protected function newReflectionMember()
80+
protected function newReflectionMember($object)
8181
{
8282
}
8383
}

src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
class PropertyMetadataTest extends \PHPUnit_Framework_TestCase
1818
{
1919
const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
20+
const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent';
2021

2122
public function testInvalidPropertyName()
2223
{
@@ -32,4 +33,13 @@ public function testGetPropertyValueFromPrivateProperty()
3233

3334
$this->assertEquals('foobar', $metadata->getPropertyValue($entity));
3435
}
36+
37+
public function testGetPropertyValueFromOverriddenPrivateProperty()
38+
{
39+
$entity = new Entity('foobar');
40+
$metadata = new PropertyMetadata(self::PARENTCLASS, 'data');
41+
42+
$this->assertTrue($metadata->isPublic($entity));
43+
$this->assertEquals('Overridden data', $metadata->getPropertyValue($entity));
44+
}
3545
}

0 commit comments

Comments
 (0)