How to save data from Postman in Symfony? - php

I try to send data from Postman to this function
public function new(Request $request): Response
{
$tag = new Tag();
$form = $this->createForm(TagType::class, $tag);
$form->submit($request->request->all());
if ($form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($tag);
$entityManager->flush();
$message = "Tag was successfully added";
return new JsonResponse(array("message: $message"));
}
$errors = $form->getErrors();
return new JsonResponse(array("message:$errors"));
}
If i send data as 'form-data' i can save it to database.
But i can't understand how to accept 'raw' Json 'application/json'
I can only manually take value from Request with
$tagTitle = $request->query->get('title');
And i can't do it with some FOSUserBundle etc.
I can use only jms/serializer. If i will need it.

You need to fetch the json from $request->getContent() first:
public function new(Request $request): Response
{
$tag = new Tag();
$form = $this->createForm(TagType::class, $tag);
$form->submit(json_decode($request->getContent(), true));
if ($form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($tag);
$entityManager->flush();
$message = "Tag was successfully added";
return new JsonResponse(array("message: $message"));
}
$errors = $form->getErrors();
return new JsonResponse(array("message:$errors"));
}

Related

How I can implement code for card registration with MangoPay API?

I would like to transfer the card details to mangopay
At first, I put the necessary code for the registration provided by the API
public function Registration($user)
{
$CardRegistration = new \MangoPay\CardRegistration();
$CardRegistration->UserId = $user->getIdMangopay();
$CardRegistration->Currency = "EUR";
$CardRegistration->CardType = "CB_VISA_MASTERCARD";
$Result = $Api->CardRegistrations->Create($CardRegistration);
}
then I call this function when submitting my form during a purchase
public function payment(Request $request, ApiUser $ApiUser): Response
{
$payment = new PaymentMethod();
$form = $this->createForm(RegistrationCard::class);
$form->handleRequest($request);
if ($form->isSubmitted()){
$name = $form->get('name')->getData();
$cardnumber = $form->get('cardnumber')->getData();
if($name){
$payment->setName($name);
}
if($cardnumber){
$payment->setCardNumber($cardnumber);
}
$ApiUser->Registration($form);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($payment);
$entityManager->flush();
return $this->redirectToRoute("profil");
}
return $this->render('home/payment.html.twig', [
'controller_name' => 'HomeController',
]);
}

How Can I specified the object of my precedent form?

In my project I want to use the object created by my precedent form:
Here is the schema of my database:
My QuizController
public function creation(Request $request){
$quiz = new Quiz();
$user = $this->getUser();
$formQuiz = $this->createForm(QuizType::class, $quiz);
$formQuiz->handleRequest($request);
if ($formQuiz->isSubmitted() && $formQuiz->isValid() ) {
$quiz->setCreatedAt(new DateTimeImmutable());
$quiz->setCreatedBy($user);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($quiz);
$entityManager->flush();
return $this->redirectToRoute('creation_questions');
}
return $this->render('quiz/creation.html.twig', [
'formQuiz' => $formQuiz->createView(),
]);
}
And my QuestionController that must be connected with the quiz form
public function creation_questions(Request $request){
$quiz = ?
$question = new Questions();
$formQuestions = $this->createForm(QuestionType::class, $question);
$formQuestions->handleRequest($request);
if ($formQuestions->isSubmitted() && $formQuestions->isValid() ) {
$question->setCreatedAt(new DateTimeImmutable());
$question->setQuiz($quiz);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($question);
$entityManager->flush();
return $this->redirectToRoute('home');
}
return $this->render('questions/questions.html.twig', [
'formQuestion' => $formQuestions->createView()
]);
}
What do I have to write in place of the '?'?
You don't show your routing but you could use paramConverte "magic" from SensioFrameworkExtraBundle and do something like this.
/**
* #Route("/some-route/{id}", name="some_route_name")
*/
public function creation_questions(Request $request, Quiz $quiz)
{
$question = new Questions();
$formQuestions = $this->createForm(QuestionType::class, $question);
$formQuestions->handleRequest($request);
if ($formQuestions->isSubmitted() && $formQuestions->isValid()) {
$question->setCreatedAt(new DateTimeImmutable());
$question->setQuiz($quiz);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($question);
$entityManager->flush();
return $this->redirectToRoute('home');
}
return $this->render('questions/questions.html.twig', [
'formQuestion' => $formQuestions->createView()
]);
}
Where the {id} part of /someRoute/{id} is the Quiz Id. Symfony should automagically fetch the Quiz matching that id. Or you can be more explicit about how the param converter should interpret such a value. More info here https://symfony.com/bundles/SensioFrameworkExtraBundle/current/annotations/converters.html
Alternatively, you could pass the quiz id and fetch the quiz manually (less magic but totally legit).
/**
* #Route("/some-route/{id}", name="some_route_name")
*/
public function creation_questions(Request $request, int $id)
{
$entityManager = $this->getDoctrine()->getManager();
$quiz = $entityManager->getRepository(Quiz::class)->find($id);
$question = new Questions();
$formQuestions = $this->createForm(QuestionType::class, $question);
$formQuestions->handleRequest($request);
if ($formQuestions->isSubmitted() && $formQuestions->isValid()) {
$question->setCreatedAt(new DateTimeImmutable());
$question->setQuiz($quiz);
$entityManager->persist($question);
$entityManager->flush();
return $this->redirectToRoute('home');
}
return $this->render('questions/questions.html.twig', [
'formQuestion' => $formQuestions->createView()
]);
}

Symfony 4 Validator - Auto logout if invalid

I wanted to validate my User Object ($user) with the Symfony Validator and return a JsonResponse ($response) if the form input data is valid / is not valid.
But I have the issue that I get logged out automatically when the data could not be validated. I have to login again and this is not the behaviour I expect when some data ist not valid. I found a workaround (see comments below) but this is not very satisfying :/
Here is the method of my Controller:
/**
* Update user profile data
*
* #Route("/api/users/updateprofile")
* #Security("is_granted('USERS_LIST')")
*/
public function apiProfileUpdate(ValidatorInterface $validator, FlashMessageBuilder $flashMessageBuilder)
{
$request = Request::createFromGlobals();
// Prepare Response
$response = new JsonResponse();
$response->setData([]);
/** #var User $user */
$user = $this->getUser();
$oldName = $user->getName();
$oldEmail = $user->getEmail();
$user->setName($request->request->get('name'));
$user->setEmail($request->request->get('email'));
$errors = $validator->validate($user);
if (count($errors) > 0) { // if this -> auto logout
$user->setName($oldName); // if I set the both attributes back to the old value
$user->setEmail($oldEmail); // then I don't get logged out automatically but this is just a workaround and not satisfying
$entityManager = $this->getDoctrine()->getManager(); // forgot to remove this
$entityManager->persist($user); // and this line, this is actually deleted in the real code
foreach ($errors as $error) {
$errorMessage = $error->getMessage();
$errorField = $error->getPropertyPath();
$flashMessageBuilder->addErrorMessage($errorMessage, $errorField);
};
return $response;
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
$flashMessageBuilder->addSuccessMessage("Success!");
return $response;
}
Sorry for my bad english and thank you in advance!
You are persisting the User Object even if there are errors in validation, which can cause the problem with the logout.
Try to update ONLY in case there is no validation error:
public function apiProfileUpdate(ValidatorInterface $validator, FlashMessageBuilder $flashMessageBuilder)
{
$request = Request::createFromGlobals();
// Prepare Response
$response = new JsonResponse();
$response->setData([]);
/** #var User $user */
$user = $this->getUser();
$user->setName($request->request->get('name'));
$user->setEmail($request->request->get('email'));
$errors = $validator->validate($user);
if (count($errors) == 0) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
$flashMessageBuilder->addSuccessMessage("Success!");
return $response;
}
foreach ($errors as $error) {
$errorMessage = $error->getMessage();
$errorField = $error->getPropertyPath();
$flashMessageBuilder->addErrorMessage($errorMessage, $errorField);
};
return $response;
}
But I think you should not mix API calls and the classical form approach utilizing FlashMessages, instead return a proper JSON result.
So consider to change the code accordingly:
public function apiProfileUpdate(ValidatorInterface $validator, FlashMessageBuilder $flashMessageBuilder)
{
$request = Request::createFromGlobals();
/** #var User $user */
$user = $this->getUser();
$user->setName($request->request->get('name'));
$user->setEmail($request->request->get('email'));
$errors = $validator->validate($user);
if (count($errors) == 0) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
return new JsonResponse(['success' => true]);
}
$data = [];
foreach ($errors as $error) {
$data[$error->getPropertyPath()] = $error->getMessage();
};
return new JsonResponse(['success' => false, 'errors' => $data], 400);
}
Now your calling code can handle a 200 result (success) and the error case with status code 400 and display the error messages for all failed fields from the errors part in the result body.

How to do edit function in symfony2

I have written a function for edit in symfony2, my problem is i can fetch the previous values from the database but after submitting the form the values were notr created instead a new form is creating
Here is the controller
public function editAction($id){
$request = $this->getRequest();
$em = $this->getDoctrine()->getEntityManager();
$profile= $em->getRepository('TcprofileBundle:TcProfiles')
->find($id);
$profile_form = $this->createForm(new ProfileType(), $profile);
$response = new JsonResponse();
$response->setData(array('content' => $this->renderView('TcprofileBundle:Default:create.html.twig',array('form' => $profile_form->createView()))));
return $response;
}
Html.twig file
<div class="edit01"> Edit Profile </div>
I'm fetching the old values, so i put if loop for condition check like this
controller
public function editAction($id){
$request = $this->getRequest();
$em = $this->getDoctrine()->getEntityManager();
$profile= $em->getRepository('TcprofileBundle:TcProfiles')
->find($id);
if(!$id){
$profile_form = $this->createForm(new ProfileType(), $profile);
$response = new JsonResponse();
$response->setData(array('content' => $this->renderView('TcprofileBundle:Default:create.html.twig',array('form' => $profile_form->createView()))));
return $response;
}else{
$profile->upload();
$em->persist($profile);
$em->flush();
$response = new JsonResponse();
$response->setData(array('content' => $this->renderView('TcprofileBundle:Default:create.html.twig',array('form' => $profile_form->createView()))));
return $response;
}
}
Its not getting output Pls help me if i gone wrong somewhere
You can use $em->merge($profile) instead of $em->persist($profile) when updating an entity. Please this stack overflow post

Symfony2 How to process dynamic embed forms collection?

I try this cookbook about embed form:
http://symfony.com/doc/current/cookbook/form/form_collections.html
But the embed foreign key (task_id field in Tag table) is not save, always NULL
Here the complete code: https://gist.github.com/1755140
Do you know why?
Thank
Edit::
My trouble was in process form action. Like the tag form is embed dynamically, so i don't know how many tag(s) i will have. If i add in createAction
$tag1 = new Tag();
$task->addTags($tag1);
only the first embed form was correctly save! How to save the other tags?
public function createAction(Request $request)
{
$task = new Task();
$tag1 = new Tag();
$task->addTags($tag1);
$form = $this->createForm(new TaskType(), $task);
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($task);
$em->flush();
return $this->redirect($this->generateUrl('new_task', array('id' => $task->getId())));
}
return array(
'form' => $form->createView()
);
}
Edit2:
My solution which resolve the trouble, what do you think about it? Better?
public function createAction(Request $request)
{
$task = new Task();
$tasks = $request->request->get('task', array());
if (isset($tasks['tags'])) {
$tags = $tasks['tags'];
foreach($tags as $tag) {
$tag = new Tag();
$task->addTags($tag);
}
}
$form = $this->createForm(new TaskType(), $task);
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($task);
$em->flush();
return $this->redirect($this->generateUrl('new_task', array('id' => $task->getId())));
}
return array(
'form' => $form->createView()
);
}
Edit3:
A much better alternative (not tested again)
http://www.siteduzero.com/tutoriel-3-523899-creer-des-formulaires-avec-symfony2.html#ss_part_2
public function createAction(Request $request)
{
$task = new Task();
$form = $this->createForm(new TaskType(), $task);
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($task);
foreach($task->getTags() as $tag) {
$em->persist($tag);
}
$em->flush();
return $this->redirect($this->generateUrl('new_task', array('id' => $task->getId())));
}
return array(
'form' => $form->createView()
);
}
In TaskController on line 29 try to use $task->addTags($tag1); instead of $task->getTags()->add($tag1);
I don't understand. Is this solution wrong?
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
foreach($task->getTags() as $tag) {
$tag->setTask($task);
}
$em->persist($task);
$em->flush();
return $this->redirect($this->generateUrl('new_task', array('id' => $task->getId())));
}
It works and it seems simpler.

Categories