You are here

class PropertyNormalizer in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 vendor/symfony/serializer/Normalizer/PropertyNormalizer.php \Symfony\Component\Serializer\Normalizer\PropertyNormalizer

Converts between objects and arrays by mapping properties.

The normalization process looks for all the object's properties (public and private). The result is a map from property names to property values. Property values are normalized through the serializer.

The denormalization first looks at the constructor of the given class to see if any of the parameters have the same name as one of the properties. The constructor is then called with all parameters or an exception is thrown if any required parameters were not present as properties. Then the denormalizer walks through the given map of property names to property values to see if a property with the corresponding name exists. If found, the property gets the value.

@author Matthieu Napoli <matthieu@mnapoli.fr> @author Kévin Dunglas <dunglas@gmail.com>

Hierarchy

Expanded class hierarchy of PropertyNormalizer

1 file declares its use of PropertyNormalizer
PropertyNormalizerTest.php in vendor/symfony/serializer/Tests/Normalizer/PropertyNormalizerTest.php

File

vendor/symfony/serializer/Normalizer/PropertyNormalizer.php, line 35

Namespace

Symfony\Component\Serializer\Normalizer
View source
class PropertyNormalizer extends AbstractNormalizer {

  /**
   * {@inheritdoc}
   *
   * @throws CircularReferenceException
   */
  public function normalize($object, $format = null, array $context = array()) {
    if ($this
      ->isCircularReference($object, $context)) {
      return $this
        ->handleCircularReference($object);
    }
    $reflectionObject = new \ReflectionObject($object);
    $attributes = array();
    $allowedAttributes = $this
      ->getAllowedAttributes($object, $context, true);
    foreach ($reflectionObject
      ->getProperties() as $property) {
      if (in_array($property->name, $this->ignoredAttributes)) {
        continue;
      }
      if (false !== $allowedAttributes && !in_array($property->name, $allowedAttributes)) {
        continue;
      }

      // Override visibility
      if (!$property
        ->isPublic()) {
        $property
          ->setAccessible(true);
      }
      $attributeValue = $property
        ->getValue($object);
      if (isset($this->callbacks[$property->name])) {
        $attributeValue = call_user_func($this->callbacks[$property->name], $attributeValue);
      }
      if (null !== $attributeValue && !is_scalar($attributeValue)) {
        if (!$this->serializer instanceof NormalizerInterface) {
          throw new LogicException(sprintf('Cannot normalize attribute "%s" because injected serializer is not a normalizer', $property->name));
        }
        $attributeValue = $this->serializer
          ->normalize($attributeValue, $format, $context);
      }
      $propertyName = $property->name;
      if ($this->nameConverter) {
        $propertyName = $this->nameConverter
          ->normalize($propertyName);
      }
      $attributes[$propertyName] = $attributeValue;
    }
    return $attributes;
  }

  /**
   * {@inheritdoc}
   *
   * @throws RuntimeException
   */
  public function denormalize($data, $class, $format = null, array $context = array()) {
    $allowedAttributes = $this
      ->getAllowedAttributes($class, $context, true);
    $data = $this
      ->prepareForDenormalization($data);
    $reflectionClass = new \ReflectionClass($class);
    $object = $this
      ->instantiateObject($data, $class, $context, $reflectionClass, $allowedAttributes);
    foreach ($data as $propertyName => $value) {
      if ($this->nameConverter) {
        $propertyName = $this->nameConverter
          ->denormalize($propertyName);
      }
      $allowed = $allowedAttributes === false || in_array($propertyName, $allowedAttributes);
      $ignored = in_array($propertyName, $this->ignoredAttributes);
      if ($allowed && !$ignored && $reflectionClass
        ->hasProperty($propertyName)) {
        $property = $reflectionClass
          ->getProperty($propertyName);

        // Override visibility
        if (!$property
          ->isPublic()) {
          $property
            ->setAccessible(true);
        }
        $property
          ->setValue($object, $value);
      }
    }
    return $object;
  }

  /**
   * {@inheritdoc}
   */
  public function supportsNormalization($data, $format = null) {
    return is_object($data) && !$data instanceof \Traversable && $this
      ->supports(get_class($data));
  }

  /**
   * {@inheritdoc}
   */
  public function supportsDenormalization($data, $type, $format = null) {
    return $this
      ->supports($type);
  }

  /**
   * Checks if the given class has any non-static property.
   *
   * @param string $class
   *
   * @return bool
   */
  private function supports($class) {
    $class = new \ReflectionClass($class);

    // We look for at least one non-static property
    foreach ($class
      ->getProperties() as $property) {
      if (!$property
        ->isStatic()) {
        return true;
      }
    }
    return false;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AbstractNormalizer::$callbacks protected property
AbstractNormalizer::$camelizedAttributes protected property
AbstractNormalizer::$circularReferenceHandler protected property
AbstractNormalizer::$circularReferenceLimit protected property
AbstractNormalizer::$classMetadataFactory protected property
AbstractNormalizer::$ignoredAttributes protected property
AbstractNormalizer::$nameConverter protected property
AbstractNormalizer::formatAttribute Deprecated protected function Format an attribute name, for example to convert a snake_case name to camelCase.
AbstractNormalizer::getAllowedAttributes protected function Gets attributes to normalize using groups.
AbstractNormalizer::handleCircularReference protected function Handles a circular reference.
AbstractNormalizer::instantiateObject protected function Instantiates an object using constructor parameters when needed.
AbstractNormalizer::isCircularReference protected function Detects if the configured circular reference limit is reached.
AbstractNormalizer::prepareForDenormalization protected function Normalizes the given data to an array. It's particularly useful during the denormalization process.
AbstractNormalizer::setCallbacks public function Set normalization callbacks.
AbstractNormalizer::setCamelizedAttributes Deprecated public function Set attributes to be camelized on denormalize.
AbstractNormalizer::setCircularReferenceHandler public function Set circular reference handler.
AbstractNormalizer::setCircularReferenceLimit public function Set circular reference limit.
AbstractNormalizer::setIgnoredAttributes public function Set ignored attributes for normalization and denormalization.
AbstractNormalizer::__construct public function Sets the {@link ClassMetadataFactoryInterface} to use. 1
PropertyNormalizer::denormalize public function Overrides DenormalizerInterface::denormalize
PropertyNormalizer::normalize public function Overrides NormalizerInterface::normalize
PropertyNormalizer::supports private function Checks if the given class has any non-static property.
PropertyNormalizer::supportsDenormalization public function Checks whether the given class is supported for denormalization by this normalizer. Overrides DenormalizerInterface::supportsDenormalization
PropertyNormalizer::supportsNormalization public function Checks whether the given class is supported for normalization by this normalizer. Overrides NormalizerInterface::supportsNormalization
SerializerAwareNormalizer::$serializer protected property
SerializerAwareNormalizer::setSerializer public function Sets the owning Serializer object. Overrides SerializerAwareInterface::setSerializer