|
11 | 11 |
|
12 | 12 | namespace Symfony\Component\PropertyInfo\Extractor; |
13 | 13 |
|
| 14 | +use Symfony\Component\Inflector\Inflector; |
14 | 15 | use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface; |
15 | 16 | use Symfony\Component\PropertyInfo\PropertyListExtractorInterface; |
16 | 17 | use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; |
@@ -55,13 +56,17 @@ public function getProperties($class, array $context = array()) |
55 | 56 | return; |
56 | 57 | } |
57 | 58 |
|
| 59 | + $reflectionProperties = $reflectionClass->getProperties(); |
| 60 | + |
58 | 61 | $properties = array(); |
59 | | - foreach ($reflectionClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflectionProperty) { |
60 | | - $properties[$reflectionProperty->name] = true; |
| 62 | + foreach ($reflectionProperties as $reflectionProperty) { |
| 63 | + if ($reflectionProperty->isPublic()) { |
| 64 | + $properties[$reflectionProperty->name] = true; |
| 65 | + } |
61 | 66 | } |
62 | 67 |
|
63 | 68 | foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) { |
64 | | - $propertyName = $this->getPropertyName($reflectionMethod->name); |
| 69 | + $propertyName = $this->getPropertyName($reflectionMethod->name, $reflectionProperties); |
65 | 70 | if (!$propertyName || isset($properties[$propertyName])) { |
66 | 71 | continue; |
67 | 72 | } |
@@ -312,33 +317,54 @@ private function getAccessorMethod($class, $property) |
312 | 317 | private function getMutatorMethod($class, $property) |
313 | 318 | { |
314 | 319 | $ucProperty = ucfirst($property); |
| 320 | + $ucSingulars = (array) Inflector::singularize($ucProperty); |
315 | 321 |
|
316 | 322 | foreach (self::$mutatorPrefixes as $prefix) { |
317 | | - try { |
318 | | - $reflectionMethod = new \ReflectionMethod($class, $prefix.$ucProperty); |
| 323 | + $names = array($ucProperty); |
| 324 | + if (in_array($prefix, self::$arrayMutatorPrefixes)) { |
| 325 | + $names = array_merge($names, $ucSingulars); |
| 326 | + } |
319 | 327 |
|
320 | | - // Parameter can be optional to allow things like: method(array $foo = null) |
321 | | - if ($reflectionMethod->getNumberOfParameters() >= 1) { |
322 | | - return array($reflectionMethod, $prefix); |
| 328 | + foreach ($names as $name) { |
| 329 | + try { |
| 330 | + $reflectionMethod = new \ReflectionMethod($class, $prefix.$name); |
| 331 | + |
| 332 | + // Parameter can be optional to allow things like: method(array $foo = null) |
| 333 | + if ($reflectionMethod->getNumberOfParameters() >= 1) { |
| 334 | + return array($reflectionMethod, $prefix); |
| 335 | + } |
| 336 | + } catch (\ReflectionException $reflectionException) { |
| 337 | + // Try the next one if method does not exist |
323 | 338 | } |
324 | | - } catch (\ReflectionException $reflectionException) { |
325 | | - // Try the next prefix if the method doesn't exist |
326 | 339 | } |
327 | 340 | } |
328 | 341 | } |
329 | 342 |
|
330 | 343 | /** |
331 | 344 | * Extracts a property name from a method name. |
332 | 345 | * |
333 | | - * @param string $methodName |
| 346 | + * @param string $methodName |
| 347 | + * @param \ReflectionProperty[] $reflectionProperties |
334 | 348 | * |
335 | 349 | * @return string |
336 | 350 | */ |
337 | | - private function getPropertyName($methodName) |
| 351 | + private function getPropertyName($methodName, array $reflectionProperties) |
338 | 352 | { |
339 | 353 | $pattern = implode('|', array_merge(self::$accessorPrefixes, self::$mutatorPrefixes)); |
340 | 354 |
|
341 | 355 | if (preg_match('/^('.$pattern.')(.+)$/i', $methodName, $matches)) { |
| 356 | + if (!in_array($matches[1], self::$arrayMutatorPrefixes)) { |
| 357 | + return $matches[2]; |
| 358 | + } |
| 359 | + |
| 360 | + foreach ($reflectionProperties as $reflectionProperty) { |
| 361 | + foreach ((array) Inflector::singularize($reflectionProperty->name) as $name) { |
| 362 | + if (strtolower($name) === strtolower($matches[2])) { |
| 363 | + return $reflectionProperty->name; |
| 364 | + } |
| 365 | + } |
| 366 | + } |
| 367 | + |
342 | 368 | return $matches[2]; |
343 | 369 | } |
344 | 370 | } |
|
0 commit comments