/** * If the method was called with the same class name (or an object of that * class) before, the same metadata instance is returned. * * If the factory was configured with a cache, this method will first look * for an existing metadata instance in the cache. If an existing instance * is found, it will be returned without further ado. * * Otherwise, a new metadata instance is created. If the factory was * configured with a loader, the metadata is passed to the * {@link LoaderInterface::loadClassMetadata()} method for further * configuration. At last, the new object is returned. * * @param string|object $value * @return ClassMetadata * @throws \InvalidArgumentException */ public function getMetadataFor($value) { $class = $this->getClass($value); if (!$class) { throw new \InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: %s', gettype($value))); } if (isset($this->loadedClasses[$class])) { return $this->loadedClasses[$class]; } if ($this->cache && ($this->loadedClasses[$class] = $this->cache->fetch($class))) { return $this->loadedClasses[$class]; } if (!class_exists($class) && !interface_exists($class)) { throw new \InvalidArgumentException(sprintf('The class or interface "%s" does not exist.', $class)); } $metadata = new ClassMetadata($class); $reflClass = $metadata->getReflectionClass(); // Include groups from the parent class if ($parent = $reflClass->getParentClass()) { $metadata->mergeAttributesGroups($this->getMetadataFor($parent->name)); } // Include groups from all implemented interfaces foreach ($reflClass->getInterfaces() as $interface) { $metadata->mergeAttributesGroups($this->getMetadataFor($interface->name)); } if ($this->loader) { $this->loader->loadClassMetadata($metadata); } if ($this->cache) { $this->cache->save($class, $metadata); } return $this->loadedClasses[$class] = $metadata; }
/** * {@inheritdoc} */ public function loadClassMetadata(ClassMetadata $metadata) { $reflClass = $metadata->getReflectionClass(); $className = $reflClass->name; $loaded = false; foreach ($reflClass->getProperties() as $property) { if ($property->getDeclaringClass()->name == $className) { foreach ($this->reader->getPropertyAnnotations($property) as $groups) { if ($groups instanceof Groups) { foreach ($groups->getGroups() as $group) { $metadata->addAttributeGroup($property->name, $group); } } $loaded = true; } } } foreach ($reflClass->getMethods() as $method) { if ($method->getDeclaringClass()->name == $className) { foreach ($this->reader->getMethodAnnotations($method) as $groups) { if ($groups instanceof Groups) { if (preg_match('/^(get|is)(.+)$/i', $method->name, $matches)) { foreach ($groups->getGroups() as $group) { $metadata->addAttributeGroup(lcfirst($matches[2]), $group); } } else { throw new \BadMethodCallException(sprintf('Groups on "%s::%s" cannot be added. Groups can only be added on methods beginning with "get" or "is".', $className, $method->name)); } } $loaded = true; } } } return $loaded; }
/** * {@inheritdoc} */ public function loadClassMetadata(ClassMetadata $metadata) { if (null === $this->classes) { if (!stream_is_local($this->file)) { throw new MappingException(sprintf('This is not a local file "%s".', $this->file)); } if (null === $this->yamlParser) { $this->yamlParser = new Parser(); } $classes = $this->yamlParser->parse(file_get_contents($this->file)); if (empty($classes)) { return false; } // not an array if (!is_array($classes)) { throw new MappingException(sprintf('The file "%s" must contain a YAML array.', $this->file)); } $this->classes = $classes; } if (isset($this->classes[$metadata->getClassName()])) { $yaml = $this->classes[$metadata->getClassName()]; if (isset($yaml['attributes']) && is_array($yaml['attributes'])) { foreach ($yaml['attributes'] as $attribute => $data) { if (isset($data['groups'])) { foreach ($data['groups'] as $group) { $metadata->addAttributeGroup($attribute, $group); } } } } return true; } return false; }
public static function createXmlCLassMetadata() { $expected = new ClassMetadata('Symfony\\Component\\Serializer\\Tests\\Fixtures\\GroupDummy'); $expected->addAttributeGroup('foo', 'group1'); $expected->addAttributeGroup('foo', 'group2'); $expected->addAttributeGroup('bar', 'group2'); return $expected; }
public function testLoadClassMetadataAndMerge() { $classMetadata = new ClassMetadata('Symfony\\Component\\Serializer\\Tests\\Fixtures\\GroupDummy'); $parentClassMetadata = new ClassMetadata('Symfony\\Component\\Serializer\\Tests\\Fixtures\\GroupDummyParent'); $this->loader->loadClassMetadata($parentClassMetadata); $classMetadata->merge($parentClassMetadata); $this->loader->loadClassMetadata($classMetadata); $this->assertEquals(TestClassMetadataFactory::createClassMetadata(true), $classMetadata); }
public function testLoadClassMetadataAndMerge() { $loader = new AnnotationLoader(new AnnotationReader()); $metadata = new ClassMetadata('Symfony\\Component\\Serializer\\Tests\\Fixtures\\GroupDummy'); $parentMetadata = new ClassMetadata('Symfony\\Component\\Serializer\\Tests\\Fixtures\\GroupDummyParent'); $loader->loadClassMetadata($parentMetadata); $metadata->mergeAttributesGroups($parentMetadata); $loader->loadClassMetadata($metadata); $this->assertEquals(TestClassMetadataFactory::createClassMetadata(true), $metadata); }
public function testCreate() { $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); $dummyResourceMetadata = (new ResourceMetadata())->withAttributes(['normalization_context' => ['groups' => ['dummy_read']], 'denormalization_context' => ['groups' => ['dummy_write']]]); $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn($dummyResourceMetadata)->shouldBeCalled(); $resourceMetadataFactoryProphecy->create(RelatedDummy::class)->willReturn(new ResourceMetadata())->shouldBeCalled(); $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal(); $serializerClassMetadataFactoryProphecy = $this->prophesize(SerializerClassMetadataFactoryInterface::class); $dummySerializerClassMetadata = new SerializerClassMetadata(Dummy::class); $fooSerializerAttributeMetadata = new SerializerAttributeMetadata('foo'); $fooSerializerAttributeMetadata->addGroup('dummy_read'); $fooSerializerAttributeMetadata->addGroup('dummy_write'); $dummySerializerClassMetadata->addAttributeMetadata($fooSerializerAttributeMetadata); $relatedDummySerializerAttributeMetadata = new SerializerAttributeMetadata('relatedDummy'); $relatedDummySerializerAttributeMetadata->addGroup('dummy_read'); $relatedDummySerializerAttributeMetadata->addGroup('dummy_write'); $dummySerializerClassMetadata->addAttributeMetadata($relatedDummySerializerAttributeMetadata); $nameConvertedSerializerAttributeMetadata = new SerializerAttributeMetadata('nameConverted'); $dummySerializerClassMetadata->addAttributeMetadata($nameConvertedSerializerAttributeMetadata); $serializerClassMetadataFactoryProphecy->getMetadataFor(Dummy::class)->willReturn($dummySerializerClassMetadata)->shouldBeCalled(); $relatedDummySerializerClassMetadata = new SerializerClassMetadata(RelatedDummy::class); $idSerializerAttributeMetadata = new SerializerAttributeMetadata('id'); $idSerializerAttributeMetadata->addGroup('dummy_read'); $relatedDummySerializerClassMetadata->addAttributeMetadata($idSerializerAttributeMetadata); $nameSerializerAttributeMetadata = new SerializerAttributeMetadata('name'); $nameSerializerAttributeMetadata->addGroup('dummy_read'); $relatedDummySerializerClassMetadata->addAttributeMetadata($nameSerializerAttributeMetadata); $serializerClassMetadataFactoryProphecy->getMetadataFor(RelatedDummy::class)->willReturn($relatedDummySerializerClassMetadata)->shouldBeCalled(); $serializerClassMetadataFactory = $serializerClassMetadataFactoryProphecy->reveal(); $decoratedProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); $fooPropertyMetadata = (new PropertyMetadata())->withType(new Type(Type::BUILTIN_TYPE_ARRAY, true))->withReadable(false)->withWritable(true); $decoratedProphecy->create(Dummy::class, 'foo', [])->willReturn($fooPropertyMetadata)->shouldBeCalled(); $relatedDummyPropertyMetadata = (new PropertyMetadata())->withType(new Type(Type::BUILTIN_TYPE_OBJECT, true, RelatedDummy::class)); $decoratedProphecy->create(Dummy::class, 'relatedDummy', [])->willReturn($relatedDummyPropertyMetadata)->shouldBeCalled(); $nameConvertedPropertyMetadata = (new PropertyMetadata())->withType(new Type(Type::BUILTIN_TYPE_STRING, true)); $decoratedProphecy->create(Dummy::class, 'nameConverted', [])->willReturn($nameConvertedPropertyMetadata)->shouldBeCalled(); $decorated = $decoratedProphecy->reveal(); $serializerPropertyMetadataFactory = new SerializerPropertyMetadataFactory($resourceMetadataFactory, $serializerClassMetadataFactory, $decorated); $actual = []; $actual[] = $serializerPropertyMetadataFactory->create(Dummy::class, 'foo'); $actual[] = $serializerPropertyMetadataFactory->create(Dummy::class, 'relatedDummy'); $actual[] = $serializerPropertyMetadataFactory->create(Dummy::class, 'nameConverted'); $this->assertInstanceOf(PropertyMetadata::class, $actual[0]); $this->assertFalse($actual[0]->isReadable()); $this->assertTrue($actual[0]->isWritable()); $this->assertInstanceOf(PropertyMetadata::class, $actual[1]); $this->assertTrue($actual[1]->isReadable()); $this->assertTrue($actual[1]->isWritable()); $this->assertTrue($actual[1]->isReadableLink()); $this->assertFalse($actual[1]->isWritableLink()); $this->assertInstanceOf(PropertyMetadata::class, $actual[2]); $this->assertFalse($actual[2]->isReadable()); $this->assertFalse($actual[2]->isWritable()); }
public function testSerialize() { $classMetadata = new ClassMetadata('a'); $a1 = $this->getMock('Symfony\\Component\\Serializer\\Mapping\\AttributeMetadataInterface'); $a1->method('getName')->willReturn('b1'); $a2 = $this->getMock('Symfony\\Component\\Serializer\\Mapping\\AttributeMetadataInterface'); $a2->method('getName')->willReturn('b2'); $classMetadata->addAttributeMetadata($a1); $classMetadata->addAttributeMetadata($a2); $serialized = serialize($classMetadata); $this->assertEquals($classMetadata, unserialize($serialized)); }
public function testMerge() { $classMetadata1 = new ClassMetadata('c1'); $classMetadata2 = new ClassMetadata('c2'); $ac1 = $this->getMock('Symfony\\Component\\Serializer\\Mapping\\AttributeMetadataInterface'); $ac1->method('getName')->willReturn('a1'); $ac1->method('getGroups')->willReturn(array('a', 'b')); $ac2 = $this->getMock('Symfony\\Component\\Serializer\\Mapping\\AttributeMetadataInterface'); $ac2->method('getName')->willReturn('a1'); $ac2->method('getGroups')->willReturn(array('b', 'c')); $classMetadata1->addAttributeMetadata($ac1); $classMetadata2->addAttributeMetadata($ac2); $classMetadata1->merge($classMetadata2); $ac1->method('getGroups')->willReturn('a', 'b', 'c'); $this->assertEquals(array('a1' => $ac1), $classMetadata2->getAttributesMetadata()); }
/** * {@inheritdoc} */ public function loadClassMetadata(ClassMetadata $metadata) { if (null === $this->classes) { $this->classes = array(); $xml = $this->parseFile($this->file); foreach ($xml->class as $class) { $this->classes[(string) $class['name']] = $class; } } if (isset($this->classes[$metadata->getClassName()])) { $xml = $this->classes[$metadata->getClassName()]; foreach ($xml->attribute as $attribute) { foreach ($attribute->group as $group) { $metadata->addAttributeGroup((string) $attribute['name'], (string) $group); } } return true; } return false; }
public function testGetAllowedAttributesAsObjects() { $classMetadata = new ClassMetadata('c'); $a1 = new AttributeMetadata('a1'); $classMetadata->addAttributeMetadata($a1); $a2 = new AttributeMetadata('a2'); $a2->addGroup('test'); $classMetadata->addAttributeMetadata($a2); $a3 = new AttributeMetadata('a3'); $a3->addGroup('other'); $classMetadata->addAttributeMetadata($a3); $a4 = new AttributeMetadata('a4'); $a4->addGroup('test'); $a4->addGroup('other'); $classMetadata->addAttributeMetadata($a4); $this->classMetadata->method('getMetadataFor')->willReturn($classMetadata); $result = $this->normalizer->getAllowedAttributes('c', array('groups' => array('test')), false); $this->assertEquals(array($a2, $a4), $result); $result = $this->normalizer->getAllowedAttributes('c', array('groups' => array('other')), false); $this->assertEquals(array($a3, $a4), $result); }