Skip to content

Commit

Permalink
Merge pull request #22 from biig-io/feature/custom-data-mapper
Browse files Browse the repository at this point in the history
Add new option custom data mapper on ApiType
  • Loading branch information
Maxime Veber authored Aug 1, 2019
2 parents 554fd15 + e14f873 commit 76b6730
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
- #22 Add possibility to define a custom data normalizer for ApiType

## [0.3.2] - 2019-07-05
### Changed
- #19 Documentation is now using scheme of the application
Expand Down
16 changes: 16 additions & 0 deletions src/Bridge/Symfony/Form/DomainObjectDataMapperInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Biig\Melodiia\Bridge\Symfony\Form;

use Symfony\Component\Form\DataMapperInterface;

interface DomainObjectDataMapperInterface extends DataMapperInterface
{
/**
* @param iterable $form
* @param string|null $dataClass
*
* @return mixed
*/
public function createObject(iterable $form, string $dataClass = null);
}
9 changes: 2 additions & 7 deletions src/Bridge/Symfony/Form/DomainObjectsDataMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Add support for objects that require constructor instantiation.
*/
class DomainObjectsDataMapper extends PropertyPathMapper implements DataMapperInterface
class DomainObjectsDataMapper extends PropertyPathMapper implements DomainObjectDataMapperInterface
{
public function mapFormsToData($forms, &$data)
{
Expand All @@ -18,12 +18,7 @@ public function mapFormsToData($forms, &$data)
}

/**
* @param FormInterface[] $form
* @param string $dataClass
*
* @throws \ReflectionException
*
* @return object|null
* {@inheritDoc}
*/
public function createObject(iterable $form, string $dataClass = null)
{
Expand Down
16 changes: 15 additions & 1 deletion src/Bridge/Symfony/Form/Type/ApiType.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ public function __construct(DataMapperInterface $dataMapper = null)

public function buildForm(FormBuilderInterface $builder, array $options)
{
$dataMapper = $this->dataMapper;

if ($options['customDataMapper'] !== null) {
$dataMapper = $options['customDataMapper'];
}

if ($options['value_object']) {
$builder->setDataMapper($this->dataMapper);
}
Expand All @@ -31,6 +37,7 @@ public function configureOptions(OptionsResolver $resolver)
$resolver->setDefaults([
'csrf_protection' => false,
'value_object' => false,
'customDataMapper' => null,

/*
* Creates data object just like standard form would do
Expand All @@ -41,8 +48,15 @@ public function configureOptions(OptionsResolver $resolver)
* @throws \ReflectionException
*/
'empty_data' => function (FormInterface $form) {
return $this->dataMapper->createObject($form);
$dataMapper = $this->dataMapper;
if ($form->getConfig()->getOption('customDataMapper') !== null) {
$dataMapper = $form->getConfig()->getOption('customDataMapper');
}

return $dataMapper->createObject($form);
},
]);

$resolver->setAllowedTypes('customDataMapper', ['null', DomainObjectsDataMapper::class]);
}
}
23 changes: 23 additions & 0 deletions tests/Melodiia/Bridge/Symfony/Form/ApiTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Biig\Melodiia\Test\Bridge\Symfony\Form;

use Biig\Melodiia\Bridge\Symfony\Form\DomainObjectsDataMapper;
use Biig\Melodiia\Bridge\Symfony\Form\Type\ApiType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
Expand Down Expand Up @@ -34,6 +35,28 @@ public function testItReturnsDataForEmptyDataInCaseOfDataAvailable()
$this->assertEquals('some content', $data->getFoo());
}

public function testItSupportsCustomDataMapper()
{
$customDataMapper = new class extends DomainObjectsDataMapper {
private $hasBeenCalled = false;
public function createObject(iterable $form, string $dataClass = null)
{
$this->hasBeenCalled = true;
return parent::createObject($form, $dataClass);
}

public function hasBeenCalled() { return $this->hasBeenCalled; }
};
$form = $this->factory->createNamed('', FakeTypeUsingApiType::class, null, [
'customDataMapper' => $customDataMapper
]);
$form->submit(['foo' => 'some content']);
$data = $form->getData();
$this->assertInstanceOf(FakeModel::class, $data);
$this->assertEquals('some content', $data->getFoo());
$this->assertTrue($customDataMapper->hasBeenCalled());
}

protected function getTypes()
{
return [new ApiType()];
Expand Down

0 comments on commit 76b6730

Please sign in to comment.