-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[PropertyAccess] Allow custom methods on property accesses #18016
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
Changes from 1 commit
af3a824
5b82237
00a26eb
e4aaac9
e46df98
5f206e6
94e6157
09707ad
d02d93a
748b894
688cbda
003efdb
dc5cacb
1a35d45
1e29523
7c6a79c
d0bd777
6b7eeff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\PropertyAccess\Annotation; | ||
|
||
/** | ||
* Property accessor adder configuration annotation. | ||
* | ||
* @Annotation | ||
* @Target({"METHOD"}) | ||
* | ||
* @author Luis Ramón López <lrlopez@gmail.com> | ||
*/ | ||
class Adder | ||
{ | ||
/** | ||
* Associates this method to the setter of this property. | ||
* | ||
* @var string | ||
*/ | ||
public $property; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\PropertyAccess\Annotation; | ||
|
||
/** | ||
* Property accessor getter configuration annotation. | ||
* | ||
* @Annotation | ||
* @Target({"METHOD"}) | ||
* | ||
* @author Luis Ramón López <lrlopez@gmail.com> | ||
*/ | ||
class Getter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure! |
||
{ | ||
/** | ||
* Associates this method to the getter of this property. | ||
* | ||
* @var string | ||
*/ | ||
public $property; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\PropertyAccess\Annotation; | ||
|
||
/** | ||
* Property accessor remover configuration annotation. | ||
* | ||
* @Annotation | ||
* @Target({"METHOD"}) | ||
* | ||
* @author Luis Ramón López <lrlopez@gmail.com> | ||
*/ | ||
class Remover | ||
{ | ||
/** | ||
* Associates this method to the setter of this property. | ||
* | ||
* @var string | ||
*/ | ||
public $property; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\PropertyAccess\Annotation; | ||
|
||
/** | ||
* Property accessor setter configuration annotation. | ||
* | ||
* @Annotation | ||
* @Target({"METHOD"}) | ||
* | ||
* @author Luis Ramón López <lrlopez@gmail.com> | ||
*/ | ||
class Setter | ||
{ | ||
/** | ||
* Associates this method to the setter of this property. | ||
* | ||
* @var string | ||
*/ | ||
public $property; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,9 @@ | |
|
||
use Doctrine\Common\Annotations\AnnotationReader; | ||
use Doctrine\Common\Annotations\AnnotationRegistry; | ||
use Symfony\Component\PropertyAccess\Annotation\Adder; | ||
use Symfony\Component\PropertyAccess\Annotation\Getter; | ||
use Symfony\Component\PropertyAccess\Annotation\Remover; | ||
use Symfony\Component\PropertyAccess\Mapping\Factory\ClassMetadataFactory; | ||
use Symfony\Component\PropertyAccess\Mapping\Loader\AnnotationLoader; | ||
use Symfony\Component\PropertyAccess\PropertyAccessor; | ||
|
@@ -39,6 +42,10 @@ public function addAxis($axis) | |
} | ||
|
||
// In the test, use a name that StringUtil can't uniquely singularify | ||
/** | ||
* @Adder(property="customVirtualAxes") | ||
* @param $axis | ||
*/ | ||
public function addAxisTest($axis) | ||
{ | ||
$this->customAxes[] = $axis; | ||
|
@@ -55,6 +62,10 @@ public function removeAxis($axis) | |
} | ||
} | ||
|
||
/** | ||
* @Remover(property="customVirtualAxes") | ||
* @param $axis | ||
*/ | ||
public function removeAxisTest($axis) | ||
{ | ||
foreach ($this->customAxes as $key => $value) { | ||
|
@@ -71,6 +82,10 @@ public function getAxes() | |
return $this->axes; | ||
} | ||
|
||
/** | ||
* @Getter(property="customVirtualAxes") | ||
* @return null | ||
*/ | ||
public function getCustomAxes() | ||
{ | ||
return $this->customAxes; | ||
|
@@ -202,6 +217,28 @@ public function testSetValueCallsCustomAdderAndRemoverForCollections() | |
$this->assertEquals($axesMergedCopy, $axesMerged); | ||
} | ||
|
||
public function testSetValueCallsCustomAdderAndRemoverForCollectionsMethodAnnotation() | ||
{ | ||
$axesBefore = $this->getContainer(array(1 => 'second', 3 => 'fourth', 4 => 'fifth')); | ||
$axesMerged = $this->getContainer(array(1 => 'first', 2 => 'second', 3 => 'third')); | ||
$axesAfter = $this->getContainer(array(1 => 'second', 5 => 'first', 6 => 'third')); | ||
$axesMergedCopy = is_object($axesMerged) ? clone $axesMerged : $axesMerged; | ||
|
||
// Don't use a mock in order to test whether the collections are | ||
// modified while iterating them | ||
$car = new PropertyAccessorCollectionTest_Car($axesBefore); | ||
|
||
AnnotationRegistry::registerAutoloadNamespace('Symfony\Component\PropertyAccess\Annotation', __DIR__.'/../../../..'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
$this->propertyAccessor = new PropertyAccessor(false, false, new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()))); | ||
|
||
$this->propertyAccessor->setValue($car, 'customVirtualAxes', $axesMerged); | ||
|
||
$this->assertEquals($axesAfter, $car->getCustomAxes()); | ||
|
||
// The passed collection was not modified | ||
$this->assertEquals($axesMergedCopy, $axesMerged); | ||
} | ||
|
||
/** | ||
* @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException | ||
* @expectedExceptionMessage Neither the property "axes" nor one of the methods "addAx()"/"removeAx()", "addAxe()"/"removeAxe()", "addAxis()"/"removeAxis()", "setAxes()", "axes()", "__set()" or "__call()" exist and have public access in class "Mock_PropertyAccessorCollectionTest_CarNoAdderAndRemover | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be named
PropertyAdder
for more clarity.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw you should make it possible to omit
property
when using the annotation:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch. I didn't add the
Property
prefix as there was aproperty
used as a parameter. Changing the annotation name it has sense to allow it be omitted.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm... I've doing some experiments. If you omit
property
in the parameter still works because by default it assigns its value to the first public field in the annotation class. So, no code changes are needed. If we add another parameter, we just have to make sure it is not the first one in the class.