Skip to content

Commit

Permalink
new iteration of type hints
Browse files Browse the repository at this point in the history
  • Loading branch information
jordisala1991 committed Aug 15, 2020
1 parent 8fb9201 commit 0278dae
Show file tree
Hide file tree
Showing 23 changed files with 150 additions and 70 deletions.
30 changes: 9 additions & 21 deletions src/Form/ChoiceList/ModelChoiceLoader.php
Expand Up @@ -20,26 +20,20 @@
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use Symfony\Component\Form\Exception\RuntimeException;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;

/**
* @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
*/
final class ModelChoiceLoader implements ChoiceLoaderInterface
{
/**
* @var string[]
*/
public $identifier;

/**
* @var ModelManagerInterface
*/
private $modelManager;

/**
* @var string
* @var class-string|null
*/
private $class;

Expand All @@ -49,7 +43,7 @@ final class ModelChoiceLoader implements ChoiceLoaderInterface
private $property;

/**
* @var mixed
* @var object|null
*/
private $query;

Expand All @@ -69,25 +63,23 @@ final class ModelChoiceLoader implements ChoiceLoaderInterface
private $choiceList;

/**
* @param mixed $query
* @param object[] $choices
* @param class-string|null $class
* @param object[] $choices
*/
public function __construct(
ModelManagerInterface $modelManager,
string $class,
PropertyAccessorInterface $propertyAccessor,
?string $class = null,
?string $property = null,
$query = null,
array $choices = [],
?PropertyAccessorInterface $propertyAccessor = null
?object $query = null,
array $choices = []
) {
$this->modelManager = $modelManager;
$this->class = $class;
$this->property = $property;
$this->query = $query;
$this->choices = $choices;
$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor();

$this->identifier = $this->modelManager->getIdentifierFieldNames($this->class);
$this->propertyAccessor = $propertyAccessor;
}

public function loadChoiceList($value = null): ChoiceListInterface
Expand Down Expand Up @@ -146,8 +138,6 @@ public function loadChoiceList($value = null): ChoiceListInterface
}

/**
* @param string[] $values
*
* @return object[]
*/
public function loadChoicesForValues(array $values, $value = null): array
Expand All @@ -157,8 +147,6 @@ public function loadChoicesForValues(array $values, $value = null): array

/**
* @param object[] $choices
*
* @return string[]
*/
public function loadValuesForChoices(array $choices, $value = null): array
{
Expand Down
26 changes: 16 additions & 10 deletions src/Form/DataTransformer/ArrayToModelTransformer.php
Expand Up @@ -18,6 +18,8 @@

/**
* @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* @template T of object
*/
final class ArrayToModelTransformer implements DataTransformerInterface
{
Expand All @@ -27,31 +29,35 @@ final class ArrayToModelTransformer implements DataTransformerInterface
private $modelManager;

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

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

public function reverseTransform($array)
/**
* @return T
*/
public function reverseTransform($value): object
{
// 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;
// one the object is persisted, the edit $value is the user instance
if ($value instanceof $this->className) {
return $value;
}

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

if (!\is_array($array)) {
return $instance;
if (!\is_array($value)) {
return new $this->className();
}

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

public function transform($value)
Expand Down
30 changes: 19 additions & 11 deletions src/Form/DataTransformer/ModelToIdPropertyTransformer.php
Expand Up @@ -13,6 +13,7 @@

namespace Sonata\AdminBundle\Form\DataTransformer;

use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Util\ClassUtils;
use Sonata\AdminBundle\Model\ModelManagerInterface;
use Symfony\Component\Form\DataTransformerInterface;
Expand All @@ -21,6 +22,8 @@
* Transform object to ID and property label.
*
* @author Andrej Hudec <pulzarraider@gmail.com>
*
* @template T of object
*/
final class ModelToIdPropertyTransformer implements DataTransformerInterface
{
Expand All @@ -30,7 +33,7 @@ final class ModelToIdPropertyTransformer implements DataTransformerInterface
private $modelManager;

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

Expand All @@ -49,6 +52,9 @@ final class ModelToIdPropertyTransformer implements DataTransformerInterface
*/
private $toStringCallback;

/**
* @param class-string<T> $className
*/
public function __construct(
ModelManagerInterface $modelManager,
string $className,
Expand All @@ -65,6 +71,8 @@ public function __construct(

/**
* @throws \UnexpectedValueException
*
* @return Collection<array-key, T>|T|null
*/
public function reverseTransform($value)
{
Expand Down Expand Up @@ -100,25 +108,25 @@ public function reverseTransform($value)
/**
* @throws \InvalidArgumentException
*/
public function transform($entityOrCollection)
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 @@ -127,16 +135,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
22 changes: 15 additions & 7 deletions src/Form/DataTransformer/ModelToIdTransformer.php
Expand Up @@ -18,6 +18,8 @@

/**
* @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* @template T of object
*/
final class ModelToIdTransformer implements DataTransformerInterface
{
Expand All @@ -27,31 +29,37 @@ final class ModelToIdTransformer implements DataTransformerInterface
private $modelManager;

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

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

public function reverseTransform($newId)
/**
* @return T|null
*/
public function reverseTransform($value): ?object
{
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)
public function transform($value): ?string
{
if (empty($model)) {
if (empty($value)) {
return null;
}

return $this->modelManager->getNormalizedIdentifier($model);
return $this->modelManager->getNormalizedIdentifier($value);
}
}
33 changes: 22 additions & 11 deletions src/Form/DataTransformer/ModelsToArrayTransformer.php
Expand Up @@ -13,6 +13,7 @@

namespace Sonata\AdminBundle\Form\DataTransformer;

use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Util\ClassUtils;
use Sonata\AdminBundle\Model\ModelManagerInterface;
use Sonata\Doctrine\Adapter\AdapterInterface;
Expand All @@ -22,6 +23,8 @@

/**
* @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* @template T of object
*/
final class ModelsToArrayTransformer implements DataTransformerInterface
{
Expand All @@ -31,46 +34,54 @@ final class ModelsToArrayTransformer implements DataTransformerInterface
private $modelManager;

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

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

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

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

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

return $array;
}

/**
* @throws UnexpectedTypeException
*
* @return Collection<array-key, T>
*/
public function reverseTransform($keys)
public function reverseTransform($value)
{
if (!\is_array($keys)) {
throw new UnexpectedTypeException($keys, 'array');
if (!\is_array($value)) {
throw new UnexpectedTypeException($value, 'array');
}

$collection = $this->modelManager->getModelCollectionInstance($this->class);
$notFound = [];

// optimize this into a SELECT WHERE IN query
foreach ($keys as $key) {
foreach ($value as $key) {
if ($model = $this->modelManager->find($this->class, $key)) {
$collection[] = $model;
} else {
Expand Down
3 changes: 3 additions & 0 deletions src/Form/EventListener/MergeCollectionListener.php
Expand Up @@ -33,6 +33,9 @@ public function __construct(ModelManagerInterface $modelManager)
$this->modelManager = $modelManager;
}

/**
* @return array<string, mixed>
*/
public static function getSubscribedEvents(): array
{
return [
Expand Down
3 changes: 3 additions & 0 deletions src/Form/Type/AclMatrixType.php
Expand Up @@ -28,6 +28,9 @@
*/
final class AclMatrixType extends AbstractType
{
/**
* @param array<string, mixed> $options
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$aclValueType = $options['acl_value'] instanceof UserInterface ? 'user' : 'role';
Expand Down

0 comments on commit 0278dae

Please sign in to comment.