/**
  * 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;
 }
示例#2
0
 /**
  * {@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;
 }
示例#3
0
 /**
  * {@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());
 }
示例#8
0
 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));
 }
示例#9
0
 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());
 }
示例#10
0
 /**
  * {@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);
 }