WIP: Implement feedback functionality

This commit is contained in:
Björn Fromme
2023-11-05 18:19:58 +01:00
parent 47f2aa17be
commit 908b904b67
15 changed files with 346 additions and 75 deletions
+33 -27
View File
@@ -2,7 +2,7 @@
namespace App\Form;
use App\Form\DataTransformer\EntityToIdTransformer;
use App\Form\DataTransformer\EntityToIdentifierTransformer;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
@@ -21,27 +21,33 @@ class AutocompleteEntityType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$dataTransformer = new EntityToIdTransformer($this->entityManager, $options['class']);
$dataTransformer = new EntityToIdentifierTransformer(
$this->entityManager,
$options['class'],
$options['identifier']
);
$builder->addModelTransformer($dataTransformer);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setRequired(['class']);
$resolver->setDefaults([
'endpoint_route' => null,
'choices' => [],
'compound' => false,
'label_property' => 'label',
'label_function' => null,
'placeholder' => null,
'endpoint_parameters' => [],
'controller_action' => null,
]);
$resolver->setAllowedTypes('choices', 'array');
$resolver->setAllowedTypes('label_function', ['null', 'callable']);
$resolver
->setRequired(['class'])
->setDefaults([
'endpoint_route' => null,
'choices' => [],
'compound' => false,
'label_property' => 'label',
'label_function' => null,
'placeholder' => null,
'endpoint_parameters' => [],
'controller_action' => null,
'identifier' => 'id',
])
->setAllowedTypes('choices', 'array')
->setAllowedTypes('label_function', ['null', 'callable'])
->setAllowedValues('identifier', ['id', 'uuid'])
;
}
public function buildView(FormView $view, FormInterface $form, array $options): void
@@ -57,17 +63,17 @@ class AutocompleteEntityType extends AbstractType
$view->vars['initial_label'] = '';
$view->vars['action'] = $options['controller_action'];
$entity = $form->getData();
if (null === $entity = $form->getData()) {
return;
}
if (null !== $entity) {
if (null !== $options['label_function']) {
$labelFunction = $options['label_function'];
$view->vars['initial_label'] = $labelFunction($entity);
} else {
$getter = 'get'.ucfirst($options['label_property']);
if (method_exists($entity, $getter)) {
$view->vars['initial_label'] = $entity->$getter();
}
if (null !== $options['label_function']) {
$labelFunction = $options['label_function'];
$view->vars['initial_label'] = $labelFunction($entity);
} else {
$getter = 'get'.ucfirst($options['label_property']);
if (method_exists($entity, $getter)) {
$view->vars['initial_label'] = call_user_func([$entity, $getter]);
}
}
}
@@ -1,38 +0,0 @@
<?php
namespace App\Form\DataTransformer;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class EntityToIdTransformer implements DataTransformerInterface
{
public function __construct(private readonly EntityManagerInterface $entityManager, private readonly string $class)
{
}
public function transform($value)
{
if (null === $value) {
return null;
}
return $value->getId();
}
public function reverseTransform($value)
{
if (empty($value)) {
return null;
}
$entity = $this->entityManager->getRepository($this->class)->find($value);
if (null === $entity) {
throw new TransformationFailedException(sprintf('No %s with id %d found', $this->class, $value));
}
return $entity;
}
}
@@ -0,0 +1,54 @@
<?php
namespace App\Form\DataTransformer;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class EntityToIdentifierTransformer implements DataTransformerInterface
{
private string $identifier;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly string $class,
string $identifier = 'id'
) {
if (false === in_array($identifier, ['id', 'uuid'])) {
throw new \InvalidArgumentException(sprintf('Identifier must be one of "id" or "uuid" got "%s"', $identifier));
}
$this->identifier = $identifier;
}
public function transform($value)
{
if (null === $value) {
return null;
}
$getter = 'get'.ucfirst($this->identifier);
return call_user_func([$value, $getter]);
}
public function reverseTransform($value)
{
if (empty($value)) {
return null;
}
$entity = $this
->entityManager
->getRepository($this->class)
->findOneBy([$this->identifier => $value])
;
if (null === $entity) {
throw new TransformationFailedException(sprintf('No %s with %s %s found', $this->class, $this->identifier, $value));
}
return $entity;
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Form\DataTransformer;
use App\Entity\FeedbackSet;
use Symfony\Component\Form\DataTransformerInterface;
class FeedbackToRatingsTransformer implements DataTransformerInterface
{
public function __construct(private readonly FeedbackSet $feedbackSet)
{
}
public function transform(mixed $value)
{
// Not in use
return $value;
}
public function reverseTransform(mixed $value)
{
$feedbackRatings = [];
foreach ($this->feedbackSet->getRatings() as $index => $rating) {
$feedbackRatings[] = [
'rating' => $rating,
'mark' => $value['rating_'.$index],
];
}
return $feedbackRatings;
}
}
+8
View File
@@ -4,6 +4,7 @@ namespace App\Form;
use App\Entity\Feedback;
use App\Entity\FeedbackSet;
use App\Form\DataTransformer\FeedbackToRatingsTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
@@ -26,6 +27,13 @@ class FeedbackType extends AbstractType
],
])
;
// This is most probably more suitable for DatamapperInterface
// but it works very well for the time being
$builder
->get('ratings')
->addModelTransformer(new FeedbackToRatingsTransformer($options['feedback_set']))
;
}
public function configureOptions(OptionsResolver $resolver): void
+8 -2
View File
@@ -2,7 +2,7 @@
namespace App\Form;
use App\Form\DataTransformer\EntityToIdTransformer;
use App\Form\DataTransformer\EntityToIdentifierTransformer;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
@@ -19,7 +19,11 @@ class HiddenEntityType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$transformer = new EntityToIdTransformer($this->entityManager, $options['class']);
$transformer = new EntityToIdentifierTransformer(
$this->entityManager,
$options['class'],
$options['identifier']
);
$builder->addModelTransformer($transformer);
}
@@ -34,7 +38,9 @@ class HiddenEntityType extends AbstractType
->setRequired(['class'])
->setDefaults([
'invalid_message' => 'The entity does not exist.',
'identifier' => 'id',
])
->setAllowedValues('identifier', ['id', 'uuid'])
;
}