ObjectProperty.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Hydrator;
  10. use ReflectionClass;
  11. use ReflectionProperty;
  12. class ObjectProperty extends AbstractHydrator
  13. {
  14. /**
  15. * @var array[] indexed by class name and then property name
  16. */
  17. private static $skippedPropertiesCache = [];
  18. /**
  19. * {@inheritDoc}
  20. *
  21. * Extracts the accessible non-static properties of the given $object.
  22. *
  23. * @throws Exception\BadMethodCallException for a non-object $object
  24. */
  25. public function extract($object)
  26. {
  27. if (!is_object($object)) {
  28. throw new Exception\BadMethodCallException(
  29. sprintf('%s expects the provided $object to be a PHP object)', __METHOD__)
  30. );
  31. }
  32. $data = get_object_vars($object);
  33. $filter = $this->getFilter();
  34. foreach ($data as $name => $value) {
  35. // Filter keys, removing any we don't want
  36. if (! $filter->filter($name)) {
  37. unset($data[$name]);
  38. continue;
  39. }
  40. // Replace name if extracted differ
  41. $extracted = $this->extractName($name, $object);
  42. if ($extracted !== $name) {
  43. unset($data[$name]);
  44. $name = $extracted;
  45. }
  46. $data[$name] = $this->extractValue($name, $value, $object);
  47. }
  48. return $data;
  49. }
  50. /**
  51. * {@inheritDoc}
  52. *
  53. * Hydrate an object by populating public properties
  54. *
  55. * Hydrates an object by setting public properties of the object.
  56. *
  57. * @throws Exception\BadMethodCallException for a non-object $object
  58. */
  59. public function hydrate(array $data, $object)
  60. {
  61. if (!is_object($object)) {
  62. throw new Exception\BadMethodCallException(
  63. sprintf('%s expects the provided $object to be a PHP object)', __METHOD__)
  64. );
  65. }
  66. $properties = & self::$skippedPropertiesCache[get_class($object)];
  67. if (! isset($properties)) {
  68. $reflection = new ReflectionClass($object);
  69. $properties = array_fill_keys(
  70. array_map(
  71. function (ReflectionProperty $property) {
  72. return $property->getName();
  73. },
  74. $reflection->getProperties(
  75. ReflectionProperty::IS_PRIVATE
  76. + ReflectionProperty::IS_PROTECTED
  77. + ReflectionProperty::IS_STATIC
  78. )
  79. ),
  80. true
  81. );
  82. }
  83. foreach ($data as $name => $value) {
  84. $property = $this->hydrateName($name, $data);
  85. if (isset($properties[$property])) {
  86. continue;
  87. }
  88. $object->$property = $this->hydrateValue($property, $value, $data);
  89. }
  90. return $object;
  91. }
  92. }