/** * @param TransportableInterface $resource * @param array $data * @return TransportableInterface * * @throws HydrationException when invalid data provided. */ protected function hydrateResource(TransportableInterface $resource, array $data) { $mapping = $this->parser->parse($resource); foreach ($mapping->getFields() as $field) { $reflector = $field->getField()->getReflector(); $reflector->setAccessible(true); if (!isset($data[$field->getName()])) { throw new HydrationException(sprintf(HydrationException::MESSAGE_DATA_MISSING, get_class($resource), $reflector->getName(), $field->getName())); } $reflector->setValue($resource, $data[$field->getName()]); } foreach ($mapping->getAssociations() as $association) { $reflector = $association->getAssociation()->getReflector(); $reflector->setAccessible(true); if (!isset($data[$association->getName()])) { throw new HydrationException(sprintf(HydrationException::MESSAGE_DATA_MISSING, get_class($resource), $reflector->getName(), $association->getName())); } $resourceData = $data[$association->getName()]; if ($association->getAssociation()->collection) { $value = new ResourceCollection(); } else { $instance = $association->getAssociation()->target; $instance = new $instance(); if (isset($resourceData[self::KEY_RECURSION])) { $value = $instance; } else { $value = $this->hydrateResource($instance, $resourceData); } } $reflector->setValue($resource, $value); } return $resource; }
/** * Expect that the {@link ArtistResourceMock} is parsed correctly. * * @test */ public function validateMockResourceParsing() { $resource = new ArtistResourceMock(); $mapping = $this->parser->parse($resource); $message = 'The primary @Field annotation was marked against the $id property.'; $this->assertEquals('id', $mapping->getPrimary()->getField()->getReflector()->getName(), $message); $fields = $mapping->getFields(); $this->assertCount(2, $fields, 'There should be 2 properties mapped with @Field annotations'); $field = $fields[0]; $this->assertEquals('id', $field->getField()->getReflector()->getName()); $this->assertTrue($field->getField()->primary); $field = $fields[1]; $this->assertEquals('name', $field->getField()->getReflector()->getName()); $this->assertFalse($field->getField()->primary); $associations = $mapping->getAssociations(); $this->assertCount(1, $associations, 'There should be 1 property mapped with @Association annotations'); $field = $associations[0]; $this->assertEquals('albums', $field->getField()->getReflector()->getName()); $this->assertFalse($field->getField()->primary); $this->assertEquals(AlbumResourceMock::class, $field->getAssociation()->target); $this->assertTrue($field->getAssociation()->collection); }