Skip to content

Commit

Permalink
Add type hints to data transformers
Browse files Browse the repository at this point in the history
  • Loading branch information
core23 committed Sep 7, 2020
1 parent 57ee852 commit ad7cc35
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 33 deletions.
12 changes: 6 additions & 6 deletions docs/cookbook/recipe_sortable_sonata_type_model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -377,29 +377,29 @@ to handle the conversion of ``Expectation`` to ``UserHasExpectations``::
$this->modelManager = $modelManager;
}

public function transform($data)
public function transform($value)
{
if (!is_null($data)) {
if (!is_null($value)) {
$results = [];

/** @var UserHasExpectations $userHasExpectations */
foreach ($data as $userHasExpectations) {
foreach ($value as $userHasExpectations) {
$results[] = $userHasExpectations->getExpectation();
}

return $results;
}

return $data;
return $value;
}

public function reverseTransform($expectations)
public function reverseTransform($value)
{
$results = new ArrayCollection();
$position = 0;

/** @var Expectation $expectation */
foreach ($expectations as $expectation) {
foreach ($value as $expectation) {
$userHasExpectations = $this->create();
$userHasExpectations->setExpectation($expectation);
$userHasExpectations->setPosition($position++);
Expand Down
34 changes: 29 additions & 5 deletions src/Form/DataTransformer/ArrayToModelTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
* @final since sonata-project/admin-bundle 3.52
*
* @author Thomas Rabaix <[email protected]>
*
* @phpstan-template T of object
*/
class ArrayToModelTransformer implements DataTransformerInterface
{
Expand All @@ -30,35 +32,57 @@ class ArrayToModelTransformer implements DataTransformerInterface

/**
* @var string
*
* @phpstan-var class-string<T>
*/
protected $className;

/**
* @param string $className
*
* @phpstan-param class-string<T> $className
*/
public function __construct(ModelManagerInterface $modelManager, $className)
{
$this->modelManager = $modelManager;
$this->className = $className;
}

public function reverseTransform($array)
/**
* @param object|object[]|null $value
*
* @return object
*
* @phpstan-param T|T[]|null $value
*
* @phpstan-return T
*/
public function reverseTransform($value)
{
// when the object is created the form return an array
// one the object is persisted, the edit $array is the user instance
if ($array instanceof $this->className) {
return $array;
if ($value instanceof $this->className) {
return $value;
}

$instance = new $this->className();

if (!\is_array($array)) {
if (!\is_array($value)) {
return $instance;
}

return $this->modelManager->modelReverseTransform($this->className, $array);
return $this->modelManager->modelReverseTransform($this->className, $value);
}

/**
* @param mixed|null $value
*
* @return mixed|null
*
* @phpstan-param T|null $value
*
* @phpstan-return T|null
*/
public function transform($value)
{
return $value;
Expand Down
46 changes: 35 additions & 11 deletions src/Form/DataTransformer/ModelToIdPropertyTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Sonata\AdminBundle\Form\DataTransformer;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Util\ClassUtils;
use Sonata\AdminBundle\Model\ModelManagerInterface;
use Symfony\Component\Form\DataTransformerInterface;
Expand All @@ -24,6 +25,8 @@
* @final since sonata-project/admin-bundle 3.52
*
* @author Andrej Hudec <[email protected]>
*
* @phpstan-template T of object
*/
class ModelToIdPropertyTransformer implements DataTransformerInterface
{
Expand All @@ -34,6 +37,8 @@ class ModelToIdPropertyTransformer implements DataTransformerInterface

/**
* @var string
*
* @phpstan-var class-string<T>
*/
protected $className;

Expand All @@ -57,6 +62,9 @@ class ModelToIdPropertyTransformer implements DataTransformerInterface
* @param string $property
* @param bool $multiple
* @param callable|null $toStringCallback
*
* @phpstan-param class-string<T> $className
* @phpstan-param null|callable(object, string): string $toStringCallback
*/
public function __construct(
ModelManagerInterface $modelManager,
Expand All @@ -72,9 +80,16 @@ public function __construct(
$this->toStringCallback = $toStringCallback;
}

/**
* @param mixed[]|null $value
*
* @return Collection<int|string, object>|object|null
*
* @phpstan-return Collection<array-key, T>|T|null
*/
public function reverseTransform($value)
{
/** @var ArrayCollection<array-key, object> $collection */
/** @phpstan-var ArrayCollection<array-key, T> $collection */
$collection = new ArrayCollection();

if (empty($value)) {
Expand Down Expand Up @@ -104,25 +119,34 @@ public function reverseTransform($value)
return $collection;
}

public function transform($entityOrCollection)
/**
* @param object|object[]|null $value
*
* @return array<string|int, string>
*
* @phpstan-param T|T[]|null $value
*
* @phpstan-return array{_labels?: mixed}
*/
public function transform($value)
{
$result = [];

if (!$entityOrCollection) {
if (!$value) {
return $result;
}

if ($this->multiple) {
$isArray = \is_array($entityOrCollection);
if (!$isArray && substr(\get_class($entityOrCollection), -1 * \strlen($this->className)) === $this->className) {
$isArray = \is_array($value);
if (!$isArray && substr(\get_class($value), -1 * \strlen($this->className)) === $this->className) {
throw new \InvalidArgumentException(
'A multiple selection must be passed a collection not a single value.'
.' Make sure that form option "multiple=false" is set for many-to-one relation and "multiple=true"'
.' is set for many-to-many or one-to-many relations.'
);
}
if ($isArray || ($entityOrCollection instanceof \ArrayAccess)) {
$collection = $entityOrCollection;
if ($isArray || ($value instanceof \ArrayAccess)) {
$collection = $value;
} else {
throw new \InvalidArgumentException(
'A multiple selection must be passed a collection not a single value.'
Expand All @@ -131,16 +155,16 @@ public function transform($entityOrCollection)
);
}
} else {
if (substr(\get_class($entityOrCollection), -1 * \strlen($this->className)) === $this->className) {
$collection = [$entityOrCollection];
} elseif ($entityOrCollection instanceof \ArrayAccess) {
if (substr(\get_class($value), -1 * \strlen($this->className)) === $this->className) {
$collection = [$value];
} elseif ($value instanceof \ArrayAccess) {
throw new \InvalidArgumentException(
'A single selection must be passed a single value not a collection.'
.' Make sure that form option "multiple=false" is set for many-to-one relation and "multiple=true"'
.' is set for many-to-many or one-to-many relations.'
);
} else {
$collection = [$entityOrCollection];
$collection = [$value];
}
}

Expand Down
32 changes: 26 additions & 6 deletions src/Form/DataTransformer/ModelToIdTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
* @final since sonata-project/admin-bundle 3.52
*
* @author Thomas Rabaix <[email protected]>
*
* @phpstan-template T of object
*/
class ModelToIdTransformer implements DataTransformerInterface
{
Expand All @@ -30,33 +32,51 @@ class ModelToIdTransformer implements DataTransformerInterface

/**
* @var string
*
* @phpstan-var class-string<T>
*/
protected $className;

/**
* @param string $className
*
* @phpstan-param class-string<T> $className
*/
public function __construct(ModelManagerInterface $modelManager, $className)
{
$this->modelManager = $modelManager;
$this->className = $className;
}

public function reverseTransform($newId)
/**
* @param mixed|null $value
*
* @return object|null
*
* @phpstan-return T|null
*/
public function reverseTransform($value)
{
if (empty($newId) && !\in_array($newId, ['0', 0], true)) {
if (empty($value) && !\in_array($value, ['0', 0], true)) {
return null;
}

return $this->modelManager->find($this->className, $newId);
return $this->modelManager->find($this->className, $value);
}

public function transform($model)
/**
* @param object|null $value
*
* @return mixed|null
*
* @phpstan-param T|null $value
*/
public function transform($value)
{
if (empty($model)) {
if (empty($value)) {
return null;
}

return $this->modelManager->getNormalizedIdentifier($model);
return $this->modelManager->getNormalizedIdentifier($value);
}
}
31 changes: 26 additions & 5 deletions src/Form/DataTransformer/ModelsToArrayTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Sonata\AdminBundle\Form\DataTransformer;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Util\ClassUtils;
use Sonata\AdminBundle\Form\ChoiceList\ModelChoiceLoader;
use Sonata\AdminBundle\Model\ModelManagerInterface;
Expand All @@ -28,6 +29,8 @@
* @final since sonata-project/admin-bundle 3.52
*
* @author Thomas Rabaix <[email protected]>
*
* @phpstan-template T of object
*/
class ModelsToArrayTransformer implements DataTransformerInterface
{
Expand All @@ -38,6 +41,8 @@ class ModelsToArrayTransformer implements DataTransformerInterface

/**
* @var string
*
* @phpstan-var class-string<T>
*/
protected $class;

Expand All @@ -56,7 +61,7 @@ class ModelsToArrayTransformer implements DataTransformerInterface
* @param ModelManagerInterface $modelManager
* @param string $class
*
* @phpstan-param class-string $class
* @phpstan-param class-string<T> $class
*
* @throws RuntimeException
*/
Expand Down Expand Up @@ -125,14 +130,21 @@ public function __unset($name)
unset($this->$name);
}

public function transform($collection)
/**
* @param object[]|null $value
*
* @return string[]
*
* @phpstan-param T[]|null $value
*/
public function transform($value)
{
if (null === $collection) {
if (null === $value) {
return [];
}

$array = [];
foreach ($collection as $key => $model) {
foreach ($value as $model) {
$id = implode(AdapterInterface::ID_SEPARATOR, $this->getIdentifierValues($model));

$array[] = $id;
Expand All @@ -141,13 +153,18 @@ public function transform($collection)
return $array;
}

/**
* @return Collection<int|string, object>|null
*
* @phpstan-return Collection<array-key, T>|null
*/
public function reverseTransform($keys)
{
if (!\is_array($keys)) {
throw new UnexpectedTypeException($keys, 'array');
}

/** @var ArrayCollection<array-key, object> $collection */
/** @phpstan-var ArrayCollection<array-key, T> $collection */
$collection = new ArrayCollection();
$notFound = [];

Expand Down Expand Up @@ -194,6 +211,10 @@ private function legacyConstructor(array $args): void

/**
* @param object $model
*
* @return mixed[]
*
* @phpstan-param T $model
*/
private function getIdentifierValues($model): array
{
Expand Down

0 comments on commit ad7cc35

Please sign in to comment.