Update to Drupal 8.1.0. For more information, see https://www.drupal.org/drupal-8.1.0-release-notes

This commit is contained in:
Pantheon Automation 2016-04-20 09:56:34 -07:00 committed by Greg Anderson
parent b11a755ba8
commit c0a0d5a94c
6920 changed files with 64395 additions and 57312 deletions

View file

@ -27,30 +27,40 @@ use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
*/
abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface
{
const CIRCULAR_REFERENCE_LIMIT = 'circular_reference_limit';
const OBJECT_TO_POPULATE = 'object_to_populate';
const GROUPS = 'groups';
/**
* @var int
*/
protected $circularReferenceLimit = 1;
/**
* @var callable
*/
protected $circularReferenceHandler;
/**
* @var ClassMetadataFactoryInterface|null
*/
protected $classMetadataFactory;
/**
* @var NameConverterInterface|null
*/
protected $nameConverter;
/**
* @var array
*/
protected $callbacks = array();
/**
* @var array
*/
protected $ignoredAttributes = array();
/**
* @var array
*/
@ -185,16 +195,16 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
{
$objectHash = spl_object_hash($object);
if (isset($context['circular_reference_limit'][$objectHash])) {
if ($context['circular_reference_limit'][$objectHash] >= $this->circularReferenceLimit) {
unset($context['circular_reference_limit'][$objectHash]);
if (isset($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash])) {
if ($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash] >= $this->circularReferenceLimit) {
unset($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash]);
return true;
}
++$context['circular_reference_limit'][$objectHash];
++$context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash];
} else {
$context['circular_reference_limit'][$objectHash] = 1;
$context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash] = 1;
}
return false;
@ -248,18 +258,18 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
*/
protected function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false)
{
if (!$this->classMetadataFactory || !isset($context['groups']) || !is_array($context['groups'])) {
if (!$this->classMetadataFactory || !isset($context[static::GROUPS]) || !is_array($context[static::GROUPS])) {
return false;
}
$allowedAttributes = array();
foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesMetadata() as $attributeMetadata) {
if (count(array_intersect($attributeMetadata->getGroups(), $context['groups']))) {
if (count(array_intersect($attributeMetadata->getGroups(), $context[static::GROUPS]))) {
$allowedAttributes[] = $attributesAsString ? $attributeMetadata->getName() : $attributeMetadata;
}
}
return array_unique($allowedAttributes);
return $allowedAttributes;
}
/**
@ -279,7 +289,9 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
* Instantiates an object using constructor parameters when needed.
*
* This method also allows to denormalize data into an existing object if
* it is present in the context with the object_to_populate key.
* it is present in the context with the object_to_populate. This object
* is removed from the context before being returned to avoid side effects
* when recursively normalizing an object graph.
*
* @param array $data
* @param string $class
@ -294,11 +306,14 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes)
{
if (
isset($context['object_to_populate']) &&
is_object($context['object_to_populate']) &&
$class === get_class($context['object_to_populate'])
isset($context[static::OBJECT_TO_POPULATE]) &&
is_object($context[static::OBJECT_TO_POPULATE]) &&
$context[static::OBJECT_TO_POPULATE] instanceof $class
) {
return $context['object_to_populate'];
$object = $context[static::OBJECT_TO_POPULATE];
unset($context[static::OBJECT_TO_POPULATE]);
return $object;
}
$constructor = $reflectionClass->getConstructor();

View file

@ -0,0 +1,77 @@
<?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\Serializer\Normalizer;
use Symfony\Component\Serializer\Exception\BadMethodCallException;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
/**
* Denormalizes arrays of objects.
*
* @author Alexander M. Turek <me@derrabus.de>
*/
class ArrayDenormalizer implements DenormalizerInterface, SerializerAwareInterface
{
/**
* @var SerializerInterface|DenormalizerInterface
*/
private $serializer;
/**
* {@inheritdoc}
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
if ($this->serializer === null) {
throw new BadMethodCallException('Please set a serializer before calling denormalize()!');
}
if (!is_array($data)) {
throw new InvalidArgumentException('Data expected to be an array, '.gettype($data).' given.');
}
if (substr($class, -2) !== '[]') {
throw new InvalidArgumentException('Unsupported class: '.$class);
}
$serializer = $this->serializer;
$class = substr($class, 0, -2);
return array_map(
function ($data) use ($serializer, $class, $format, $context) {
return $serializer->denormalize($data, $class, $format, $context);
},
$data
);
}
/**
* {@inheritdoc}
*/
public function supportsDenormalization($data, $type, $format = null)
{
return substr($type, -2) === '[]'
&& $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format);
}
/**
* {@inheritdoc}
*/
public function setSerializer(SerializerInterface $serializer)
{
if (!$serializer instanceof DenormalizerInterface) {
throw new InvalidArgumentException('Expected a serializer that also implements DenormalizerInterface.');
}
$this->serializer = $serializer;
}
}

View file

@ -59,8 +59,10 @@ class CustomNormalizer extends SerializerAwareNormalizer implements NormalizerIn
*/
public function supportsDenormalization($data, $type, $format = null)
{
$class = new \ReflectionClass($type);
if (!class_exists($type)) {
return false;
}
return $class->isSubclassOf('Symfony\Component\Serializer\Normalizer\DenormalizableInterface');
return is_subclass_of($type, 'Symfony\Component\Serializer\Normalizer\DenormalizableInterface');
}
}

View file

@ -114,7 +114,7 @@ class GetSetMethodNormalizer extends AbstractNormalizer
if ($allowed && !$ignored) {
$setter = 'set'.ucfirst($attribute);
if (in_array($setter, $classMethods)) {
if (in_array($setter, $classMethods) && !$reflectionClass->getMethod($setter)->isStatic()) {
$object->$setter($value);
}
}
@ -136,7 +136,7 @@ class GetSetMethodNormalizer extends AbstractNormalizer
*/
public function supportsDenormalization($data, $type, $format = null)
{
return $this->supports($type);
return class_exists($type) && $this->supports($type);
}
/**
@ -170,10 +170,13 @@ class GetSetMethodNormalizer extends AbstractNormalizer
{
$methodLength = strlen($method->name);
return (
((0 === strpos($method->name, 'get') && 3 < $methodLength) ||
(0 === strpos($method->name, 'is') && 2 < $methodLength)) &&
0 === $method->getNumberOfRequiredParameters()
);
return
!$method->isStatic() &&
(
((0 === strpos($method->name, 'get') && 3 < $methodLength) ||
(0 === strpos($method->name, 'is') && 2 < $methodLength)) &&
0 === $method->getNumberOfRequiredParameters()
)
;
}
}

View file

@ -26,6 +26,8 @@ use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
*/
class ObjectNormalizer extends AbstractNormalizer
{
private $attributesCache = array();
/**
* @var PropertyAccessorInterface
*/
@ -53,44 +55,15 @@ class ObjectNormalizer extends AbstractNormalizer
*/
public function normalize($object, $format = null, array $context = array())
{
if (!isset($context['cache_key'])) {
$context['cache_key'] = $this->getCacheKey($context);
}
if ($this->isCircularReference($object, $context)) {
return $this->handleCircularReference($object);
}
$data = array();
$attributes = $this->getAllowedAttributes($object, $context, true);
// If not using groups, detect manually
if (false === $attributes) {
$attributes = array();
// methods
$reflClass = new \ReflectionClass($object);
foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
if (
!$reflMethod->isConstructor() &&
!$reflMethod->isDestructor() &&
0 === $reflMethod->getNumberOfRequiredParameters()
) {
$name = $reflMethod->getName();
if (strpos($name, 'get') === 0 || strpos($name, 'has') === 0) {
// getters and hassers
$attributes[lcfirst(substr($name, 3))] = true;
} elseif (strpos($name, 'is') === 0) {
// issers
$attributes[lcfirst(substr($name, 2))] = true;
}
}
}
// properties
foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) {
$attributes[$reflProperty->getName()] = true;
}
$attributes = array_keys($attributes);
}
$attributes = $this->getAttributes($object, $context);
foreach ($attributes as $attribute) {
if (in_array($attribute, $this->ignoredAttributes)) {
@ -134,6 +107,9 @@ class ObjectNormalizer extends AbstractNormalizer
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
if (!isset($context['cache_key'])) {
$context['cache_key'] = $this->getCacheKey($context);
}
$allowedAttributes = $this->getAllowedAttributes($class, $context, true);
$normalizedData = $this->prepareForDenormalization($data);
@ -159,4 +135,95 @@ class ObjectNormalizer extends AbstractNormalizer
return $object;
}
private function getCacheKey(array $context)
{
try {
return md5(serialize($context));
} catch (\Exception $exception) {
// The context cannot be serialized, skip the cache
return false;
}
}
/**
* Gets and caches attributes for this class and context.
*
* @param object $object
* @param array $context
*
* @return string[]
*/
private function getAttributes($object, array $context)
{
$class = get_class($object);
$key = $class.'-'.$context['cache_key'];
if (isset($this->attributesCache[$key])) {
return $this->attributesCache[$key];
}
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
if (false !== $allowedAttributes) {
if ($context['cache_key']) {
$this->attributesCache[$key] = $allowedAttributes;
}
return $allowedAttributes;
}
if (isset($this->attributesCache[$class])) {
return $this->attributesCache[$class];
}
return $this->attributesCache[$class] = $this->extractAttributes($object);
}
/**
* Extracts attributes for this class and context.
*
* @param object $object
*
* @return string[]
*/
private function extractAttributes($object)
{
// If not using groups, detect manually
$attributes = array();
// methods
$reflClass = new \ReflectionClass($object);
foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
if (
$reflMethod->getNumberOfRequiredParameters() !== 0 ||
$reflMethod->isStatic() ||
$reflMethod->isConstructor() ||
$reflMethod->isDestructor()
) {
continue;
}
$name = $reflMethod->name;
if (0 === strpos($name, 'get') || 0 === strpos($name, 'has')) {
// getters and hassers
$attributes[lcfirst(substr($name, 3))] = true;
} elseif (strpos($name, 'is') === 0) {
// issers
$attributes[lcfirst(substr($name, 2))] = true;
}
}
// properties
foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) {
if ($reflProperty->isStatic()) {
continue;
}
$attributes[$reflProperty->name] = true;
}
return array_keys($attributes);
}
}

View file

@ -50,7 +50,7 @@ class PropertyNormalizer extends AbstractNormalizer
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
foreach ($reflectionObject->getProperties() as $property) {
if (in_array($property->name, $this->ignoredAttributes)) {
if (in_array($property->name, $this->ignoredAttributes) || $property->isStatic()) {
continue;
}
@ -110,6 +110,10 @@ class PropertyNormalizer extends AbstractNormalizer
if ($allowed && !$ignored && $reflectionClass->hasProperty($propertyName)) {
$property = $reflectionClass->getProperty($propertyName);
if ($property->isStatic()) {
continue;
}
// Override visibility
if (!$property->isPublic()) {
$property->setAccessible(true);
@ -135,7 +139,7 @@ class PropertyNormalizer extends AbstractNormalizer
*/
public function supportsDenormalization($data, $type, $format = null)
{
return $this->supports($type);
return class_exists($type) && $this->supports($type);
}
/**