[PropertyInfo] Support singular adder and remover
This commit is contained in:
parent
3a165e551d
commit
4cbb60c382
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\PropertyInfo\Extractor;
|
namespace Symfony\Component\PropertyInfo\Extractor;
|
||||||
|
|
||||||
|
use Symfony\Component\Inflector\Inflector;
|
||||||
use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
|
use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
|
||||||
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
|
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
|
||||||
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
|
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
|
||||||
@ -55,13 +56,17 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$reflectionProperties = $reflectionClass->getProperties();
|
||||||
|
|
||||||
$properties = array();
|
$properties = array();
|
||||||
foreach ($reflectionClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflectionProperty) {
|
foreach ($reflectionProperties as $reflectionProperty) {
|
||||||
|
if ($reflectionProperty->isPublic()) {
|
||||||
$properties[$reflectionProperty->name] = true;
|
$properties[$reflectionProperty->name] = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
|
foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
|
||||||
$propertyName = $this->getPropertyName($reflectionMethod->name);
|
$propertyName = $this->getPropertyName($reflectionMethod->name, $reflectionProperties);
|
||||||
if (!$propertyName || isset($properties[$propertyName])) {
|
if (!$propertyName || isset($properties[$propertyName])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -312,17 +317,25 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
|
|||||||
private function getMutatorMethod($class, $property)
|
private function getMutatorMethod($class, $property)
|
||||||
{
|
{
|
||||||
$ucProperty = ucfirst($property);
|
$ucProperty = ucfirst($property);
|
||||||
|
$ucSingulars = (array) Inflector::singularize($ucProperty);
|
||||||
|
|
||||||
foreach (self::$mutatorPrefixes as $prefix) {
|
foreach (self::$mutatorPrefixes as $prefix) {
|
||||||
|
$names = array($ucProperty);
|
||||||
|
if (in_array($prefix, self::$arrayMutatorPrefixes)) {
|
||||||
|
$names = array_merge($names, $ucSingulars);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($names as $name) {
|
||||||
try {
|
try {
|
||||||
$reflectionMethod = new \ReflectionMethod($class, $prefix.$ucProperty);
|
$reflectionMethod = new \ReflectionMethod($class, $prefix.$name);
|
||||||
|
|
||||||
// Parameter can be optional to allow things like: method(array $foo = null)
|
// Parameter can be optional to allow things like: method(array $foo = null)
|
||||||
if ($reflectionMethod->getNumberOfParameters() >= 1) {
|
if ($reflectionMethod->getNumberOfParameters() >= 1) {
|
||||||
return array($reflectionMethod, $prefix);
|
return array($reflectionMethod, $prefix);
|
||||||
}
|
}
|
||||||
} catch (\ReflectionException $reflectionException) {
|
} catch (\ReflectionException $reflectionException) {
|
||||||
// Try the next prefix if the method doesn't exist
|
// Try the next one if method does not exist
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -331,14 +344,27 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
|
|||||||
* Extracts a property name from a method name.
|
* Extracts a property name from a method name.
|
||||||
*
|
*
|
||||||
* @param string $methodName
|
* @param string $methodName
|
||||||
|
* @param \ReflectionProperty[] $reflectionProperties
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function getPropertyName($methodName)
|
private function getPropertyName($methodName, array $reflectionProperties)
|
||||||
{
|
{
|
||||||
$pattern = implode('|', array_merge(self::$accessorPrefixes, self::$mutatorPrefixes));
|
$pattern = implode('|', array_merge(self::$accessorPrefixes, self::$mutatorPrefixes));
|
||||||
|
|
||||||
if (preg_match('/^('.$pattern.')(.+)$/i', $methodName, $matches)) {
|
if (preg_match('/^('.$pattern.')(.+)$/i', $methodName, $matches)) {
|
||||||
|
if (!in_array($matches[1], self::$arrayMutatorPrefixes)) {
|
||||||
|
return $matches[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($reflectionProperties as $reflectionProperty) {
|
||||||
|
foreach ((array) Inflector::singularize($reflectionProperty->name) as $name) {
|
||||||
|
if (strtolower($name) === strtolower($matches[2])) {
|
||||||
|
return $reflectionProperty->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $matches[2];
|
return $matches[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\PropertyInfo\Tests\Extractor;
|
namespace Symfony\Component\PropertyInfo\Tests\Extractor;
|
||||||
|
|
||||||
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
|
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
|
||||||
|
use Symfony\Component\PropertyInfo\Tests\Fixtures\AdderRemoverDummy;
|
||||||
use Symfony\Component\PropertyInfo\Type;
|
use Symfony\Component\PropertyInfo\Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,4 +120,11 @@ class ReflectionExtractorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'e', array()));
|
$this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'e', array()));
|
||||||
$this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'f', array()));
|
$this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'f', array()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSingularize()
|
||||||
|
{
|
||||||
|
$this->assertTrue($this->extractor->isWritable(AdderRemoverDummy::class, 'analyses'));
|
||||||
|
$this->assertTrue($this->extractor->isWritable(AdderRemoverDummy::class, 'feet'));
|
||||||
|
$this->assertEquals(array('analyses', 'feet'), $this->extractor->getProperties(AdderRemoverDummy::class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
<?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\PropertyInfo\Tests\Fixtures;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class AdderRemoverDummy
|
||||||
|
{
|
||||||
|
private $analyses;
|
||||||
|
private $feet;
|
||||||
|
|
||||||
|
public function addAnalyse(Dummy $analyse)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeFoot(Dummy $foot)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.5.9"
|
"php": ">=5.5.9",
|
||||||
|
"symfony/inflector": "~3.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/serializer": "~2.8|~3.0",
|
"symfony/serializer": "~2.8|~3.0",
|
||||||
|
Reference in New Issue
Block a user