|
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 | }
|
@@ -310,33 +315,54 @@ private function getAccessorMethod($class, $property)
|
310 | 315 | private function getMutatorMethod($class, $property)
|
311 | 316 | {
|
312 | 317 | $ucProperty = ucfirst($property);
|
| 318 | + $ucSingulars = (array) Inflector::singularize($ucProperty); |
313 | 319 |
|
314 | 320 | foreach (self::$mutatorPrefixes as $prefix) {
|
315 |
| - try { |
316 |
| - $reflectionMethod = new \ReflectionMethod($class, $prefix.$ucProperty); |
| 321 | + $names = array($ucProperty); |
| 322 | + if (in_array($prefix, self::$arrayMutatorPrefixes)) { |
| 323 | + $names = array_merge($names, $ucSingulars); |
| 324 | + } |
317 | 325 |
|
318 |
| - // Parameter can be optional to allow things like: method(array $foo = null) |
319 |
| - if ($reflectionMethod->getNumberOfParameters() >= 1) { |
320 |
| - return array($reflectionMethod, $prefix); |
| 326 | + foreach ($names as $name) { |
| 327 | + try { |
| 328 | + $reflectionMethod = new \ReflectionMethod($class, $prefix.$name); |
| 329 | + |
| 330 | + // Parameter can be optional to allow things like: method(array $foo = null) |
| 331 | + if ($reflectionMethod->getNumberOfParameters() >= 1) { |
| 332 | + return array($reflectionMethod, $prefix); |
| 333 | + } |
| 334 | + } catch (\ReflectionException $reflectionException) { |
| 335 | + // Try the next one if method does not exist |
321 | 336 | }
|
322 |
| - } catch (\ReflectionException $reflectionException) { |
323 |
| - // Try the next prefix if the method doesn't exist |
324 | 337 | }
|
325 | 338 | }
|
326 | 339 | }
|
327 | 340 |
|
328 | 341 | /**
|
329 | 342 | * Extracts a property name from a method name.
|
330 | 343 | *
|
331 |
| - * @param string $methodName |
| 344 | + * @param string $methodName |
| 345 | + * @param \ReflectionProperty[] $reflectionProperties |
332 | 346 | *
|
333 | 347 | * @return string
|
334 | 348 | */
|
335 |
| - private function getPropertyName($methodName) |
| 349 | + private function getPropertyName($methodName, array $reflectionProperties) |
336 | 350 | {
|
337 | 351 | $pattern = implode('|', array_merge(self::$accessorPrefixes, self::$mutatorPrefixes));
|
338 | 352 |
|
339 | 353 | if (preg_match('/^('.$pattern.')(.+)$/i', $methodName, $matches)) {
|
| 354 | + if (!in_array($matches[1], self::$arrayMutatorPrefixes)) { |
| 355 | + return $matches[2]; |
| 356 | + } |
| 357 | + |
| 358 | + foreach ($reflectionProperties as $reflectionProperty) { |
| 359 | + foreach ((array) Inflector::singularize($reflectionProperty->name) as $name) { |
| 360 | + if (strtolower($name) === strtolower($matches[2])) { |
| 361 | + return $reflectionProperty->name; |
| 362 | + } |
| 363 | + } |
| 364 | + } |
| 365 | + |
340 | 366 | return $matches[2];
|
341 | 367 | }
|
342 | 368 | }
|
|
0 commit comments