Как изменить данные с помощью событий API-платформы перед записью - PullRequest
0 голосов
/ 29 мая 2018

У меня есть Пользователь и Университет с отношением ManyToOne (в одном университете может быть много пользователей).Я добавил ограничение уникальности для имени университета, чтобы избежать дубликатов.

Поэтому, когда я делаю HTTP-запрос PUT по маршруту / users / $ id с полезной нагрузкой, содержащей существующее название университета, я получаю следующее:

Нарушение ограничения целостности: 1062 Повторяющаяся запись 'INSA' для ключа 'unique_university_name'

Я хотел бы, чтобы доктрина записала запись в базу данных, чтобы изменить ее, еслион уже существует.

Для этого я попытался использовать систему событий API-платформы: https://api -platform.com / docs / core / events

С событиями kernel.request я мог получить доступ к данным, но мне не удалось их изменить.Я не нашел способ изменить «содержание» запроса.Я попытался также это: Есть ли способ изменить тело запроса в ядре Symfony event_listener , и я закончил с этой ошибкой.

Сериализация для формата html не поддерживается

Я хотел сделать это с событиями kernel.view, такими как PRE_VALIDATE, POST_VALIDATE или PRE_WRITE, но они не вызваны по какой-то причине.

Использую ли я правильный подход?Что я должен сделать, чтобы добавить университет к пользователю, если он уже существует на основе его «имени»?

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Чтобы решить вашу проблему, я вижу 3 варианта:


Вот как создатьПользовательский денормализатор:

use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

final class UniversityDenormalizer implements DenormalizerInterface
{
    private $decoratedDenormalizer;
    private $repository;
    public function __construct(DenormalizerInterface $decorated, UniversityRepository $repository) {
        $this->repository = $repository;
        $this->decoratedNormalizer = $decorated;
    }

    public function denormalize($data, $class, $format = null, array $context = array())
    {
        if ($count = $this->repository->countUniversitiesStartingBy($data['name'])) {
            $data['name'] .= '_' . ($this->repository->countUniversities() + 1);
        }
        return $this->decoratedDenormalizer->denormalize($data, $class, $context);
    }

    public function supportsDenormalization($data, $type, $format = null)
    {
        return is_string($data) && University::class === $type;
    }
}

Вам также необходимо зарегистрировать его как сервис:

App\Serializer\UniversityDenormalizer:
    arguments:
        # Choose the denormalizer depending on your output.
        # For example, for JSON+LD it's "api_platform.jsonld.normalizer.item"
        - '@api_platform.json.normalizer.item'
        - '@App\Repository\UniversityRepository'
    tags:
        # Priority is important but any value more than 8 should be ok
        - { name: serializer.normalizer, priority: 17 }
0 голосов
/ 29 мая 2018

Если я правильно понимаю, вы хотите изменить свой university объект, который встроен в вашу user сущность.

Если вы следуете документам и делаете это следующим образом, тогда он выиграет 'Это не работает, потому что основным объектом является User экземпляр.

$object = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$object instanceof University || Request::METHOD_POST !== $method) {
  return;
}

Один из способов:

$object = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$object instanceof User || Request::METHOD_POST !== $method) {
  return;
}

$university = $user->getUniversity();
// modify or replace your university here.

Другой подход заключается в использовании подписчика события доктрины , имейте в виду, что это выполняется после проверки сущности .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...